Llama a solvethree desde un backend de FastAPI
Devuelve la tarea después de crearla, no después de completar toda la resolución. El solicitante consulta su estado hasta que sea ready o failed y, si la resolución tiene éxito, envía el token al destino.
En esta página
Configura el servidor y el destino
Usa Python 3.10 o posterior. Instala FastAPI con python -m pip install "fastapi[standard]" y después instala el SDK oficial con python -m pip install https://solvethree.com/downloads/solvethree_sdk-0.1.0-py3-none-any.whl.
Establece estas variables de entorno en el proceso del servidor antes de iniciar la aplicación:
SOLVETHREE_API_KEY: la clave de API de tu espacio de trabajo. Mantenla en el servidor; el SDK la usa para autenticarse con solvethree.INTEGRATION_KEY: un secreto independiente que los solicitantes envían en la cabeceraX-Integration-Keypara autenticarse en tus rutas de FastAPI.CAPTCHA_SITE: el nombre de host de destino, no una URL completa.SOLVETHREE_PROXY: la URL del proxy HTTP o HTTPS usado para esta tarea, sin ruta, consulta ni fragmento.
Crea un perfil activo para el destino en tu espacio de trabajo antes de llamar a la ruta. El ejemplo fija la acción en login, por lo que el perfil y la solicitud prevista al destino deben corresponder a ese uso. Proporcionar un nombre de host no crea un perfil; consulta la configuración del perfil del sitio.
Añade y ejecuta las rutas de FastAPI
Guarda este ejemplo como main.py. Ambas rutas requieren X-Integration-Key. La ruta de creación construye la tarea íntegramente a partir de la configuración del servidor; los solicitantes no proporcionan el sitio, la acción ni el proxy en el cuerpo de la solicitud.
# pip install "fastapi[standard]" and the official solvethree SDK wheel.
import hmac
import os
from fastapi import FastAPI, HTTPException, Request
from fastapi.concurrency import run_in_threadpool
from solvethree import Solvethree, SolvethreeError
app = FastAPI()
def authorize(request):
if not hmac.compare_digest(request.headers.get("x-integration-key", ""), os.environ["INTEGRATION_KEY"]):
raise HTTPException(status_code=401, detail="Unauthorized")
@app.post("/captcha/tasks")
async def create(request: Request):
authorize(request)
task = {"site": os.environ["CAPTCHA_SITE"], "action": "login", "proxy": os.environ["SOLVETHREE_PROXY"]}
if request.headers.get("x-request-id"):
task["requestId"] = request.headers["x-request-id"]
def submit():
return Solvethree(os.environ["SOLVETHREE_API_KEY"]).create_task(task, wait_ms=0, timeout=20)
try:
return await run_in_threadpool(submit)
except ValueError:
raise HTTPException(status_code=400, detail="Invalid task input")
except SolvethreeError as error:
raise HTTPException(status_code=502, detail={"requestId": error.request_id, "taskId": error.task_id})
@app.get("/captcha/tasks/{task_id}")
async def retrieve(task_id: str, request: Request):
authorize(request)
def fetch():
return Solvethree(os.environ["SOLVETHREE_API_KEY"]).get_task(task_id, wait_ms=15000, timeout=25)
try:
return await run_in_threadpool(fetch)
except ValueError:
raise HTTPException(status_code=400, detail="Invalid task ID")
except SolvethreeError as error:
raise HTTPException(status_code=502, detail={"requestId": error.request_id, "taskId": error.task_id})La tarea usa reCAPTCHA Enterprise v3 de forma predeterminada. Envía site, action y un proxy, sin campos type ni url.
El SDK de Python es síncrono. Llamarlo directamente dentro de async def bloquearía el bucle de eventos, por lo que ambos manejadores usan run_in_threadpool. La creación usa wait_ms=0 con un tiempo de espera de 20 segundos para las solicitudes del SDK; la consulta permite una espera de 15 segundos con un tiempo de espera de 25 segundos para las solicitudes del SDK. Ningún manejador espera a que termine toda la resolución mediante client.solve.
Para el desarrollo local, ejecuta fastapi dev main.py desde el directorio que contiene el archivo. Las rutas son POST http://127.0.0.1:8000/captcha/tasks y GET http://127.0.0.1:8000/captcha/tasks/{task_id}. FastAPI detecta el objeto app; no hay que registrar un URLconf aparte.
Crea una tarea, consúltala y recupera las solicitudes interrumpidas
- 1.
Crea una sola vez con un ID de solicitud estable
Envía POST /captcha/tasks con X-Integration-Key y un X-Request-ID que conserves para esta tarea lógica. El ID de solicitud debe contener entre 1–64 letras ASCII, números, guiones bajos o guiones. La ruta lo pasa a solvethree como requestId. Guarda el id de tarea devuelto.
- 2.
Comprueba el estado HTTP antes de leer el estado de la tarea
El envoltorio devuelve 401 si falla la autenticación, 400 para errores de entrada ValueError y 502 para las excepciones SolvethreeError capturadas. El detalle de su respuesta 502 contiene requestId y taskId del error del SDK. Gestiona ese error HTTP antes de tratar la respuesta como una tarea.
- 3.
Recuperar la tarea existente
Llama a GET /captcha/tasks/{task_id} con X-Integration-Key. Comprueba status después de cada respuesta HTTP satisfactoria. Una consulta puede devolver una tarea en estado no terminal incluso después de que termine su espera; vuelve a consultar esa misma tarea en lugar de crear otra.
- 4.
Recupera una creación de resultado incierto
Si la creación agota el tiempo de espera y tienes un ID de tarea, consulta esa tarea. De lo contrario, repite el POST con tu X-Request-ID original y sin cambiar los parámetros de la tarea en el servidor. Reutilizar ese ID con la misma tarea devuelve la tarea existente; cambiar los parámetros genera un conflicto. Conserva el ID original por separado en lugar de sustituirlo por el requestId de una respuesta de error.
| Estado de la tarea | Acción del solicitante |
|---|---|
| pending o solving | Sigue consultando la misma tarea. Aún no hay ninguna solución utilizable. |
| listo | Lee solution y prepara la solicitud al destino. |
| failed | Deja de consultar. Examina errorCode y error antes de decidir si tiene sentido crear una tarea nueva; las resoluciones fallidas se reembolsan. |
Envía el token con el proxy original y la identidad devuelta
Estas rutas devuelven datos de tareas; no envían nada al sitio web de destino. Una vez que status sea ready, el componente que realiza la solicitud al destino debe usar solution.token, no el ID de tarea.
Realiza el envío a través del mismo proxy usado para crear esa tarea, con la identidad del navegador devuelta en solution.userAgent y solution.secChUa. Conserva la configuración original de la tarea en lugar de suponer que el entorno actual sigue conteniendo el mismo proxy. La función auxiliar successful_proxy(original_task, ready_result) del SDK selecciona el proxy de esa tarea original.
Mantén el envío vinculado al destino y la acción previstos. Una tarea ready significa que solvethree ha generado una solución; solo la respuesta del destino indica si se ha aceptado la solicitud de la aplicación.
Fuentes y referencia de la API
Ejecuta tu primera tarea.
Empieza con $5 de crédito en tu espacio de trabajo.