Chame o solvethree a partir de um backend FastAPI
Retorne a tarefa após a criação, não após toda a resolução. O cliente consulta seu status até que seja ready ou failed e então envia o token ao destino se a resolução tiver sido bem-sucedida.
Nesta página
Configure o servidor e o alvo
Use Python 3.10 ou posterior. Instale o FastAPI com python -m pip install "fastapi[standard]" e depois instale o SDK oficial com python -m pip install https://solvethree.com/downloads/solvethree_sdk-0.1.0-py3-none-any.whl.
Defina estas variáveis de ambiente no processo do servidor antes de iniciar a aplicação:
SOLVETHREE_API_KEY: a chave de API do seu workspace. Mantenha-a no servidor; o SDK a usa para se autenticar no solvethree.INTEGRATION_KEY: um segredo separado que os clientes enviam no cabeçalhoX-Integration-Keypara se autenticar nas suas rotas do FastAPI.CAPTCHA_SITE: o hostname de destino, não uma URL completa.SOLVETHREE_PROXY: a URL do proxy HTTP ou HTTPS usado para esta tarefa, sem caminho, query ou fragmento.
Crie um perfil ativo para o destino no seu workspace antes de chamar a rota. O exemplo fixa a ação em login, então o perfil e a requisição pretendida ao destino devem corresponder a esse uso. Fornecer um hostname não cria um perfil; consulte a configuração de perfil de site.
Adicione e execute as rotas do FastAPI
Salve este exemplo como main.py. Ambas as rotas exigem X-Integration-Key. A rota de criação monta a tarefa inteiramente a partir da configuração do servidor; os clientes não fornecem o site, a ação ou o proxy no corpo da requisição.
# 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})A tarefa usa reCAPTCHA Enterprise v3 por padrão. Ela envia site, action e um proxy, sem um campo type ou url.
O SDK Python é síncrono. Chamá-lo diretamente dentro de async def bloquearia o loop de eventos, por isso ambos os handlers usam run_in_threadpool. A criação usa wait_ms=0 com um tempo limite de requisição do SDK de 20 segundos; a consulta permite uma espera de 15 segundos com um tempo limite de requisição do SDK de 25 segundos. Nenhum dos handlers espera toda a resolução usando client.solve.
Para desenvolvimento local, execute fastapi dev main.py no diretório que contém o arquivo. As rotas são POST http://127.0.0.1:8000/captcha/tasks e GET http://127.0.0.1:8000/captcha/tasks/{task_id}. O FastAPI descobre o objeto app; não há um URLconf separado para registrar.
Crie uma tarefa, consulte-a e recupere requisições interrompidas
- 1.
Crie uma única vez com um ID de requisição estável
Envie POST /captcha/tasks com X-Integration-Key e um X-Request-ID que você mantenha para esta tarefa lógica. O ID de requisição deve conter 1–64 letras ASCII, números, sublinhados ou hífens. A rota o repassa ao solvethree como requestId. Salve o ID da tarefa retornado.
- 2.
Verifique o status HTTP antes de ler o status da tarefa
O wrapper retorna 401 para falhas de autenticação, 400 para falhas de entrada do tipo ValueError e 502 para exceções SolvethreeError capturadas. O detalhe da resposta 502 contém requestId e taskId do erro do SDK. Trate esse erro HTTP antes de interpretar a resposta como uma tarefa.
- 3.
Consulte a tarefa existente
Chame GET /captcha/tasks/{task_id} com X-Integration-Key. Verifique status após cada resposta HTTP bem-sucedida. Uma consulta pode retornar uma tarefa em estado não terminal mesmo após o fim da espera; consulte a mesma tarefa novamente em vez de criar outra.
- 4.
Recupere uma criação de resultado incerto
Se a criação exceder o tempo limite e você tiver um ID de tarefa, consulte-a. Caso contrário, repita o POST com seu X-Request-ID original e os parâmetros da tarefa no servidor inalterados. Reutilizar esse ID com a mesma tarefa retorna a tarefa existente; parâmetros alterados geram conflito. Guarde o ID original separadamente em vez de substituí-lo pelo requestId de uma resposta de erro.
| Status da tarefa | Ação do cliente |
|---|---|
| pending ou solving | Continue consultando a mesma tarefa. Ainda não há uma solução utilizável. |
| ready | Leia solution e prepare a requisição ao destino. |
| failed | Pare as consultas periódicas. Verifique errorCode e error antes de decidir se faz sentido criar uma nova tarefa; resoluções que falham são reembolsadas. |
Envie o token com o proxy original e a identidade retornada
Estas rotas retornam dados da tarefa; elas não enviam nada ao site de destino. Quando status for ready, o componente que faz a requisição ao destino deve usar solution.token, não o ID da tarefa.
Faça o envio pelo mesmo proxy usado para criar essa tarefa, com a identidade de navegador retornada em solution.userAgent e solution.secChUa. Guarde a configuração original da tarefa em vez de presumir que o ambiente atual ainda contém o mesmo proxy. O helper successful_proxy(original_task, ready_result) do SDK seleciona o proxy dessa tarefa original.
Mantenha o envio vinculado ao destino e à ação pretendidos. Uma tarefa ready significa que o solvethree gerou uma solução; somente a resposta do destino informa se a requisição da aplicação foi aceita.
Fontes e referência da API
Execute sua primeira tarefa.
Comece com $5 em créditos no espaço de trabalho.