Python 3.8+ client library for the Capsolver captcha-solving API. Single-package src/ layout, dual sync (requests) / async (aiohttp) execution, msgspec for serialization, tenacity for async retries.
./
├── src/python3_capsolver/ # Main library
│ ├── core/ # Base classes, instruments, serializers, enums
│ ├── control.py # Raw API: get_balance, create_task, get_task_result
│ ├── recaptcha.py # ReCaptcha V2/V3/Enterprise
│ ├── cloudflare.py # Cloudflare Turnstile/Challenge
│ └── *.py # Other captcha services (see package AGENTS.md)
├── tests/ # Pytest suite mirroring source structure
│ ├── conftest.py # BaseTest class, fixtures, rate-limiting delays
│ └── test_*.py # Per-service tests + core/instrument/control tests
├── docs/ # Sphinx documentation (make doc); module pages in docs/modules/
├── files/ # Images used by README and docs
├── ARCHITECTURE.md # Layered architecture, data flow, invariants
├── pyproject.toml # Build, deps, black/isort/pytest config
└── Makefile # make tests, make refactor, make build, make doc
Four layers with strict dependency direction (top → bottom only):
- Service layer (
src/python3_capsolver/*.py) — thin wrappers inheritingCaptchaParams, zero HTTP logic - Base layer (
core/base.py) —CaptchaParamsmerges payloads, delegates to instruments - Instrument layer (
core/*_instrument.py) —SIOCaptchaInstrument(sync) andAIOCaptchaInstrument(async) handle all HTTP, retries, and polling - Support layer (
core/serializer.py,core/enum.py,core/const.py) —msgspec.Structclasses, enums, constants
Forbidden: service files importing requests/aiohttp directly; support layer depending on upper layers.
Read only when relevant:
- Architectural or cross-module changes →
ARCHITECTURE.md(full system map, request/data flow, invariants) - Editing service classes or adding a captcha type →
src/python3_capsolver/AGENTS.md - Editing instruments, serializers, enums, or constants →
src/python3_capsolver/core/AGENTS.md - Adding or modifying tests →
tests/AGENTS.md - Sphinx docs changes →
docs/(built withmake doc; one page per module underdocs/modules/)
- Every new captcha service must inherit
CaptchaParams, providecaptcha_handler()+aio_captcha_handler(), and register its type inCaptchaTypeEnm - All serialization must use
msgspec.Struct— never rawjsonmodule - Dual sync/async is mandatory for any new instrument or service
- Service classes are thin: only
__init__with captcha-type-specific params; all HTTP goes through instruments - Context manager support (
with/async with) is required on all service classes - Keep syntax Python 3.8-compatible — CI runs a 3.8–3.14 matrix (
.github/workflows/build.yml)
make tests # pytest + coverage (HTML + XML) — same as CI (test.yml)
make lint # autoflake --check, black --check, isort --check-only — same as CI (lint.yml)
make refactor # autoflake + black + isort on src/ and tests/
uv run pytest tests/ -k <name> # run specific testsTests require the API_KEY environment variable and call the live Capsolver API. Rate-limiting fixtures (delay_func 1s, delay_class 2s) prevent API throttling.
- Empty
__init__.pyfiles: users import via full path (from python3_capsolver.recaptcha import ReCaptcha), never from top-level package AGENTS.mdfiles are repo-only: they do not ship in the wheel —MANIFEST.inincludes onlyREADME.md+LICENSE(verified against built wheels indist/). Keep the tree at exactly two files insidesrc/(package root andcore/); do not add deeper ones or packaging rules that would include themcontrol.pyis the largest file (431 lines) and provides direct API access without the captcha-handling abstraction- Toolchain is
uv: useuv run,uv sync,uv build— not barepiporpytest captcha_instrument.pyis 221 lines: contains bothCaptchaInstrumentBaseandFileInstrument; edits here affect all services