Use o SDK síncrono de Python a partir do asyncio
Use asyncio.to_thread para executar o método síncrono Solvethree.solve sem bloquear seu loop de eventos. Envolva a delegação com um semáforo e crie um cliente separado dentro de cada chamada de trabalho. O SDK não tem um cliente assíncrono nativo; suas requisições e consultas de polling continuam sendo executadas de forma síncrona na thread.
Nesta página
Limite o trabalho e defina o prazo do SDK
O exemplo requer Python 3.10+ e o SDK oficial de Python. Defina SOLVETHREE_API_KEY e SOLVETHREE_PROXY no ambiente do servidor. Substitua accounts.example.com e login pelo hostname e pela ação de destino. O site já deve ter um perfil ativo disponível para seu workspace; consulte a configuração do perfil do site.
import asyncio
import os
import uuid
from solvethree import Solvethree
async def main():
limit = asyncio.Semaphore(4)
async def solve_one(number):
task = {"site": "accounts.example.com", "action": "login", "proxy": os.environ["SOLVETHREE_PROXY"], "requestId": str(uuid.uuid4())}
def blocking_solve():
return Solvethree(os.environ["SOLVETHREE_API_KEY"]).solve(task, timeout=180)
async with limit:
try:
result = await asyncio.to_thread(blocking_solve)
print("Ready task:", result["id"])
# Submit the solution now with its proxy and browser identity.
except Exception as error:
print("Job", number, "requestId", task["requestId"], "error class", type(error).__name__)
# Retain task and inspect SDK recovery IDs before restarting it.
await asyncio.gather(*(solve_one(number) for number in range(8)))
asyncio.run(main())
# Canceling an await does not stop an already-running thread or remote task.- O semáforo permite quatro trabalhos por vez entre os oito enviados a
gather. Os trabalhos que aguardam uma vaga ainda não iniciaram sua chamada ao SDK. - Cada função de trabalho constrói seu próprio cliente
Solvethree, em vez de compartilhar um entre threads. - O
timeout=180do SDK define o prazo para a resolução. O tempo de espera pelo semáforo não está incluído. Um timeout do asyncio em torno do await não substitui esse prazo do SDK. - A tarefa e seu
requestIdsão criados antes de entrar na função de trabalho. Mantenha ambos disponíveis para recuperação, em vez de gerar um ID substituto sempre que ocorrer um erro.
O SDK cria a tarefa uma vez e faz polling até que ela esteja pronta ou lance um erro. Você não precisa escrever um segundo loop de polling em torno de solve.
O cancelamento não interrompe a thread de trabalho nem a tarefa remota
Cancelar a corrotina que aguarda to_thread não interrompe uma thread já em execução nem cancela a resolução remota. O handler de exceções comuns do exemplo não faz a limpeza necessária no cancelamento.
Isso também afeta o limite de concorrência: o cancelamento pode liberar o semáforo enquanto a thread de trabalho continua. Se você admitir trabalhos substitutos imediatamente, mais de quatro chamadas ao SDK poderão permanecer ativas. Se precisar de um limite rígido durante o cancelamento, acompanhe os trabalhos ainda em execução e mantenha a capacidade deles ocupada até que terminem.
Para uso em produção, armazene os parâmetros exatos da tarefa e o ID da requisição em algum lugar acessível ao seu fluxo de recuperação após a saída da corrotina. Um timeout significa que você parou de receber um resultado, não necessariamente que a criação da tarefa falhou.
- 1.
Recupere uma tarefa conhecida
Inspecione
task_iderequest_iddo erro do SDK de Python. Se você tiver um ID de tarefa, retome a consulta comget_taskem vez de criar outra tarefa. - 2.
Recupere uma criação interrompida
Se você não tiver um ID de tarefa, reenvie os mesmos parâmetros da tarefa com o
requestIdoriginal. Isso retorna a tarefa existente se a criação tiver sido bem-sucedida. Alterar os parâmetros e reutilizar esse ID gera um conflito. - 3.
Diferencie falha de interrupção
Um
TaskFailedErrorsignifica que a tarefa atingiu um estado terminal de falha. Inspecione seus camposerrorCodeeerror; não continue consultando a tarefa nem repita cegamente parâmetros inválidos sem alterá-los. Erros HTTP são uma camada de falha separada.
Envie a solução quando a função de trabalho retornar
O exemplo imprime o ID da tarefa pronta; ele não envia nada ao destino. Substitua o comentário após essa impressão pelo envio específico da sua aplicação e use a solução prontamente, em vez de esperar que todos os trabalhos em gather terminem.
Envie a solução retornada com seus campos userAgent e secChUa e o mesmo proxy usado na resolução. O helper successful_proxy do SDK seleciona o proxy a partir da tarefa original e do resultado pronto. Um resultado pronto significa que uma solução foi gerada, não que a requisição da sua aplicação foi bem-sucedida.
Fontes e referência da API
Execute sua primeira tarefa.
Comece com $5 em créditos no espaço de trabalho.