Das synchrone Python SDK aus asyncio verwenden
Verwenden Sie asyncio.to_thread, um die synchrone Methode Solvethree.solve auszuführen, ohne Ihre Ereignisschleife zu blockieren. Begrenzen Sie die Auslagerung mit einem Semaphor und erstellen Sie innerhalb jedes Worker-Aufrufs einen eigenen Client. Das SDK hat keinen nativen asynchronen Client; seine Anfragen und das Polling laufen im Thread weiterhin synchron.
Auf dieser Seite
Parallelität begrenzen und die SDK-Frist festlegen
Das Beispiel erfordert Python 3.10+ und das offizielle Python-SDK. Setzen Sie SOLVETHREE_API_KEY und SOLVETHREE_PROXY in Ihrer Serverumgebung. Ersetzen Sie accounts.example.com und login durch den Hostnamen und die Aktion Ihres Ziels. Für die Site muss bereits ein aktives Profil in Ihrem Workspace verfügbar sein; siehe Site-Profil einrichten.
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.- Der Semaphor lässt von den acht an
gatherübergebenen Jobs jeweils vier gleichzeitig zu. Jobs, die auf einen freien Platz warten, haben ihren SDK-Aufruf noch nicht gestartet. - Jeder Worker erstellt seinen eigenen
Solvethree-Client, statt einen Client zwischen Threads zu teilen. - Das SDK legt mit
timeout=180die Frist für das Lösen fest. Die Wartezeit auf den Semaphor wird nicht mitgezählt. Ein asyncio-Timeout um das await ersetzt diese SDK-Frist nicht. - Der Task und seine
requestIdwerden vor dem Eintritt in den Worker erstellt. Halten Sie beide für die Wiederherstellung verfügbar, statt bei jedem Fehler eine Ersatz-ID zu generieren.
Das SDK erstellt den Task einmal und fragt ihn ab, bis er bereit ist oder ein Fehler ausgelöst wird. Sie müssen keine zweite Polling-Schleife um solve schreiben.
Ein Abbruch stoppt weder den Worker noch den serverseitigen Task
Das Abbrechen der Coroutine, die auf to_thread wartet, stoppt keinen bereits laufenden Thread und bricht den serverseitigen Lösevorgang nicht ab. Der gewöhnliche Exception-Handler des Beispiels übernimmt keine Aufräumarbeiten bei einem Abbruch.
Das betrifft auch die Parallelitätsgrenze: Ein Abbruch kann den Semaphor freigeben, während der Worker weiterläuft. Wenn Sie sofort Ersatzjobs zulassen, können mehr als vier SDK-Aufrufe aktiv bleiben. Wenn Sie auch bei Abbrüchen eine strikte Grenze benötigen, verfolgen Sie noch laufende Worker und halten Sie deren Kapazität bis zu ihrem Abschluss belegt.
Bewahren Sie im Produktionsbetrieb die exakten Task-Eingaben und die Anfrage-ID an einem Ort auf, auf den Ihr Wiederherstellungspfad auch nach dem Ende der Coroutine zugreifen kann. Ein Timeout bedeutet, dass Sie kein Ergebnis mehr empfangen, nicht unbedingt, dass die Task-Erstellung fehlgeschlagen ist.
- 1.
Einen bekannten Task wiederaufnehmen
Prüfen Sie
task_idundrequest_idim Fehler des Python-SDKs. Wenn Sie eine Task-ID haben, setzen Sie den Abruf mitget_taskfort, statt einen weiteren Task zu erstellen. - 2.
Eine unterbrochene Erstellung wiederherstellen
Wenn Sie keine Task-ID haben, senden Sie die identischen Task-Eingaben mit der ursprünglichen
requestIderneut. War die Erstellung erfolgreich, wird der bestehende Task zurückgegeben. Wenn Sie bei Wiederverwendung dieser ID die Eingaben ändern, entsteht ein Konflikt. - 3.
Fehlschlag und Unterbrechung unterscheiden
Ein
TaskFailedErrorbedeutet, dass der Task den endgültigen Fehlerstatus erreicht hat. Prüfen Sie seine FeldererrorCodeunderror; fragen Sie ihn nicht weiter ab und wiederholen Sie unveränderte ungültige Eingaben nicht blind. HTTP-Fehler bilden eine separate Fehlerebene.
Die Lösung übermitteln, sobald der Worker zurückkehrt
Das Beispiel gibt die ID des bereiten Tasks aus; es übermittelt nichts an das Ziel. Ersetzen Sie den Kommentar nach dieser Ausgabe durch Ihre anwendungsspezifische Übermittlung und verwenden Sie die Lösung zeitnah, statt auf den Abschluss aller Jobs in gather zu warten.
Übermitteln Sie die zurückgegebene Lösung mit ihrem userAgent, secChUa und demselben Proxy, der zum Lösen verwendet wurde. Die Hilfsfunktion successful_proxy des SDKs wählt den Proxy aus dem ursprünglichen Task und dem ready-Ergebnis aus. Ein ready-Ergebnis bedeutet, dass eine Lösung generiert wurde, nicht, dass Ihre Anwendungsanfrage erfolgreich war.
Quellen und API-Referenz
Führe deinen ersten Task aus.
Starte mit $5 Workspace-Guthaben.