asyncio에서 동기식 Python SDK 사용하기

작성: solvethree읽는 데 3분

asyncio.to_thread를 사용하면 이벤트 루프를 차단하지 않고 동기식 Solvethree.solve 메서드를 실행할 수 있습니다. 스레드로 넘기는 호출을 세마포어로 감싸고 각 워커 호출 안에서 별도의 클라이언트를 생성하세요. SDK에는 네이티브 비동기 클라이언트가 없으며, 요청과 폴링은 여전히 스레드 안에서 동기식으로 실행됩니다.

이 페이지의 내용

동시 작업 수 제한 및 SDK 제한 시간 설정

이 예제에는 Python 3.10+와 공식 Python SDK가 필요합니다. 서버 환경에 SOLVETHREE_API_KEY와 SOLVETHREE_PROXY를 설정하세요. accounts.example.com과 login을 대상 호스트 이름과 액션으로 바꾸세요. 해당 사이트에는 워크스페이스에서 사용할 수 있는 활성 프로필이 이미 있어야 합니다. 사이트 프로필 설정을 참조하세요.

asyncio · 동기 SDK 작업 제한
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.
  • 세마포어는 gather에 제출된 작업 여덟 개 중 한 번에 네 개를 허용합니다. 실행 자리를 기다리는 작업은 아직 SDK 호출을 시작하지 않은 상태입니다.
  • 각 워커는 스레드 간에 클라이언트를 공유하지 않고 자체 Solvethree 클라이언트를 생성합니다.
  • SDK의 timeout=180이 풀이 제한 시간을 설정합니다. 세마포어를 기다리는 시간은 포함되지 않습니다. await를 감싸는 asyncio 시간 제한은 이 SDK 제한 시간을 대체할 수 없습니다.
  • 작업과 해당 requestId는 워커에 진입하기 전에 생성됩니다. 오류가 발생할 때마다 새 ID를 생성하지 말고 복구에 사용할 수 있도록 둘 다 유지하세요.

SDK는 작업을 한 번 생성한 뒤 준비 완료 상태가 되거나 오류가 발생할 때까지 폴링합니다. solve를 감싸는 별도의 폴링 루프를 작성할 필요는 없습니다.

취소해도 워커나 원격 작업은 중지되지 않음

to_thread를 기다리는 코루틴을 취소해도 이미 실행 중인 스레드가 중지되거나 원격 풀이가 취소되지는 않습니다. 예제의 일반 예외 처리기는 취소 시 정리 작업을 수행하지 않습니다.

이는 동시 실행 수 제한에도 영향을 줍니다. 워커가 계속 실행되는 동안 취소로 세마포어가 해제될 수 있습니다. 곧바로 대체 작업을 허용하면 네 개를 초과하는 SDK 호출이 활성 상태로 남을 수 있습니다. 취소 중에도 엄격한 제한이 필요하다면 아직 완료되지 않은 워커를 추적하고, 완료될 때까지 해당 실행 용량을 점유한 상태로 유지하세요.

프로덕션에서는 코루틴이 종료된 후에도 복구 경로에서 접근할 수 있는 곳에 정확한 작업 입력과 요청 ID를 보관하세요. 시간 초과는 결과 수신을 중단했다는 뜻이지, 반드시 작업 생성이 실패했다는 뜻은 아닙니다.

  1. 1.

    알려진 작업 복구하기

    Python SDK 오류의 task_id와 request_id를 확인하세요. 작업 ID가 있다면 다른 작업을 생성하지 말고 get_task로 조회를 재개하세요.

  2. 2.

    중단된 생성 복구하기

    작업 ID가 없다면 원래 requestId로 동일한 작업 입력을 재전송하세요. 생성에 성공했다면 기존 작업이 반환됩니다. 해당 ID를 재사용하면서 입력을 변경하면 충돌이 발생합니다.

  3. 3.

    실패와 중단 구분하기

    TaskFailedError는 작업이 최종 실패 상태에 도달했다는 뜻입니다. errorCode와 error를 확인하세요. 해당 작업을 계속 폴링하거나 변경하지 않은 잘못된 입력으로 무작정 재시도하지 마세요. HTTP 오류는 별도 계층의 실패입니다.

워커가 반환하면 솔루션 제출하기

예제는 준비 완료된 작업 ID를 출력할 뿐, 대상에 아무것도 제출하지 않습니다. 출력문 뒤의 주석을 애플리케이션별 제출 코드로 바꾸고, gather의 모든 작업이 끝날 때까지 기다리지 말고 솔루션을 즉시 사용하세요.

반환된 솔루션을 해당 userAgent, secChUa, 풀이에 사용한 것과 동일한 프록시와 함께 제출하세요. SDK의 successful_proxy 헬퍼는 원래 작업과 준비 완료 결과에서 프록시를 선택합니다. 준비 완료 결과는 솔루션이 생성되었다는 뜻이지, 애플리케이션 요청이 성공했다는 뜻은 아닙니다.

첫 작업을 실행하세요.

워크스페이스 크레딧 $5로 시작하세요.

워크스페이스 만들기
asyncio에서 동기식 Python SDK 사용하기 · solvethree