python-rucaptcha is a Python 3.9+ library that adapts multiple CAPTCHA-solving task types to the 2Captcha, RuCaptcha, DeathByCaptcha, and CaptchaAI service APIs. Its source is a src/-layout setuptools package (pyproject.toml) with synchronous and asyncio entry points, rather than a standalone server, worker, or command-line application. The user-facing purpose and supported providers are stated in README.md and docs/index.rst.
The primary architecture is a family of thin, flat solver adapters over a shared task engine. A concrete solver prepares provider task fields and delegates request creation, polling, retries, serialization, and response normalization to src/python_rucaptcha/core/. CaptchaAI is a deliberate second path: src/python_rucaptcha/captchaai.py and src/python_rucaptcha/core/captchaai.py submit its classic multipart protocol using packaged JSON profiles. External service calls are the system boundary; no database or long-running application runtime is defined in the repository. The executable package boundary is module-based: src/python_rucaptcha/__init__.py currently imports only the version, despite some root-level import examples in README.md.
Dependency direction:
Library caller
├──> flat solver adapters ──> shared task engine ──> provider task APIs
└──> CaptchaAI native client ──> CaptchaAI classic multipart API
Tests / Sphinx / build checks ──> package source and packaging metadata
- Responsibility: Expose one adapter per supported CAPTCHA or control operation, validate task-method choices, add task-specific fields, and provide sync/async handlers.
- Code locations:
src/python_rucaptcha/*_captcha.py,src/python_rucaptcha/control.py. - Entry points: Concrete
captcha_handlerandaio_captcha_handlermethods; representative implementations aresrc/python_rucaptcha/hcaptcha.pyandsrc/python_rucaptcha/image_captcha.py. - Depends on:
core.base.BaseCaptchaand the relevant enum incore.enums. - Must not depend on: Provider-specific transport implementations in leaf modules; shared HTTP and polling behavior belongs in
core/. - Owns: CAPTCHA-specific task names, task fields, validation, and input-shaping decisions such as image/file handling.
- State and external boundaries: Holds an in-memory task payload and delegates all provider HTTP calls to the shared core.
- Evidence:
src/python_rucaptcha/hcaptcha.py,src/python_rucaptcha/image_captcha.py,src/python_rucaptcha/AGENTS.md.
- Responsibility: Build create-task and result payloads, select service URLs, execute sync/async HTTP requests, retry connections, poll task results, and normalize errors/results.
- Code locations:
src/python_rucaptcha/core/base.py,src/python_rucaptcha/core/result_handler.py,src/python_rucaptcha/core/config.py. - Entry points:
BaseCaptcha._processing_response,BaseCaptcha._aio_processing_response,get_sync_result, andget_async_result. - Depends on:
requests,aiohttp,tenacity, and the serializer/enums incore/. - Must not depend on: Individual CAPTCHA modules for task-specific behavior; the base flow accepts generic task data and the leaf adapter supplies its fields.
- Owns: Shared task lifecycle, request sessions, retry/poll timing, task IDs, and common failure mapping.
- State and external boundaries: Keeps request state in Python objects; crosses HTTP boundaries to JSON task APIs, classic CaptchaAI delegation, and optional source-image URLs.
- Evidence:
src/python_rucaptcha/core/base.py,src/python_rucaptcha/core/result_handler.py,src/python_rucaptcha/core/config.py.
- Responsibility: Define the structured request/response shapes, serialized field names, service selection, and task-method enums used by adapters and transport.
- Code locations:
src/python_rucaptcha/core/serializer.py,src/python_rucaptcha/core/enums.py. - Entry points:
MyBaseModel.to_dict()andCaptchaOptionsSer.urls_set(). - Depends on:
msgspecand the shared service enum values. - Must not depend on: Concrete solver modules; contract types are consumed by them rather than encoding their individual payload rules.
- Owns:
TaskSer, create-task/result models, service endpoint selection, and the canonical enum vocabulary. - State and external boundaries: Produces dictionaries consumed by remote APIs; it does not persist data or perform network I/O.
- Evidence:
src/python_rucaptcha/core/serializer.py,src/python_rucaptcha/core/enums.py,pyproject.toml.
- Responsibility: Support CaptchaAI’s classic
in.php/res.phpmultipart protocol, including native methods, optional profile validation, control operations, legacy task translation, and sync/async polling. - Code locations:
src/python_rucaptcha/captchaai.py,src/python_rucaptcha/core/captchaai.py,src/python_rucaptcha/core/data/captchaai_profiles.json,src/python_rucaptcha/core/data/captchaai_legacy_profiles.json. - Entry points:
CaptchaAI.captcha_handler,CaptchaAI.aio_captcha_handler, and the corresponding native transport functions incore/captchaai.py. - Depends on:
core.serializer.GetTaskResultResponseSer,core.config.attempts_generator, and packaged profile metadata; directCaptchaAIdoes not inheritBaseCaptcha. - Must not depend on: Per-method branches in Python transport code; documented method behavior is represented in profile data. Legacy generic tasks may delegate into this path through the explicit CaptchaAI service branch in
core/base.py. - Owns: Provider-native multipart fields, profile defaults/validation, response aliases, and CaptchaAI control-operation mappings.
- State and external boundaries: Uses in-memory mappings and packaged JSON metadata, then crosses CaptchaAI submission and polling endpoints.
- Evidence:
src/python_rucaptcha/captchaai.py,src/python_rucaptcha/core/captchaai.py,src/python_rucaptcha/core/data/,src/python_rucaptcha/core/AGENTS.md.
.
├── src/python_rucaptcha/
│ ├── *_captcha.py, re_captcha.py, hcaptcha.py, ... # concrete solver adapters
│ ├── captchaai.py # native CaptchaAI client
│ ├── control.py # balance/report-style operations
│ └── core/
│ ├── base.py, result_handler.py, config.py # shared lifecycle and polling
│ ├── serializer.py, enums.py # wire models and vocabulary
│ └── captchaai.py, data/*.json # native transport and profiles
├── tests/
│ ├── conftest.py # credential-dependent fixtures
│ ├── test_core.py # shared foundation checks
│ └── test_by_solver.py # solver-oriented coverage
├── docs/
│ ├── index.rst, conf.py # Sphinx navigation and imports
│ └── modules/ # user-facing solver examples
├── pyproject.toml, Makefile # package, format, test, build, docs tasks
└── .github/workflows/ # install, lint, test, build, and docs CI
- Trigger: A library caller constructs a concrete adapter and invokes its synchronous or asynchronous handler.
- Entry point: A leaf method such as
HCaptcha.captcha_handler/aio_captcha_handlerinsrc/python_rucaptcha/hcaptcha.py. - Coordination:
BaseCaptchabuilds the generic create-task envelope and selects endpoints throughCaptchaOptionsSer.urls_set(). - Core or domain processing: The leaf adapter has already supplied its method-specific task fields;
BaseCaptchasubmits the task and records the returned task ID. - Persistence or external interaction: The shared engine polls
getTaskResult(or the DeathByCaptcha-compatible classic endpoints) throughget_sync_resultorget_async_result, with retry and delay settings fromcore/config.py. - Output or side effect:
GetTaskResultResponseSer.to_dict()returns a normalized ready/error mapping to the caller; image adapters may also read a local file or fetch and optionally save a source image.
Architectural boundaries crossed:
- Caller API → concrete solver adapter → shared core → remote provider HTTP API.
- Optional local filesystem or source-image URL → encoded task payload.
Evidence:
src/python_rucaptcha/hcaptcha.pysrc/python_rucaptcha/core/base.pysrc/python_rucaptcha/core/result_handler.pysrc/python_rucaptcha/core/serializer.py
- Trigger: A caller constructs
CaptchaAIwith a provider-native method or a packaged profile and invokescaptcha_handleroraio_captcha_handler. - Entry point:
src/python_rucaptcha/captchaai.pydelegates tosolve_nativeoraio_solve_nativeinsrc/python_rucaptcha/core/captchaai.py. - Coordination: Profile metadata supplies defaults, required fields, file-field rules, aliases, and polling behavior; unprofiled calls pass provider-native parameters through validation.
- Core or domain processing: The native transport builds multipart form fields, submits
in.php/profile-specific paths, and interprets the provider’s response contract. - Persistence or external interaction: The transport optionally polls
res.phpusing the provider task ID; binary parts remain request-local and profile JSON is read from the installed package. - Output or side effect: The transport maps provider success/error values into the common result shape, or returns a control-operation response.
Architectural boundaries crossed:
- Caller → native CaptchaAI façade → data-driven transport → CaptchaAI classic HTTP API.
- Installed package metadata → request validation and response aliasing.
Evidence:
src/python_rucaptcha/captchaai.pysrc/python_rucaptcha/core/captchaai.pysrc/python_rucaptcha/core/data/captchaai_profiles.json
- Rule: CAPTCHA-specific method names, fields, validation, and input preparation stay in the concrete modules; shared core code remains generic.
- Rationale: One transport/polling implementation can serve the flat family of solver adapters without accumulating solver-specific branches.
- Enforcement / Signals: Import direction and repeated inheritance in
src/python_rucaptcha/*.py; explicitly documented insrc/python_rucaptcha/AGENTS.mdandsrc/python_rucaptcha/core/AGENTS.md.
- Rule: A solver that exposes both modes must use the same task contract and normalized response shape while selecting blocking or asyncio I/O.
- Rationale: Consumers can change execution model without changing provider task meaning.
- Enforcement / Signals: Paired handlers in
src/python_rucaptcha/hcaptcha.py, paired core processing methods insrc/python_rucaptcha/core/base.py, and sync/async result handlers insrc/python_rucaptcha/core/result_handler.py.
- Rule: Service names and endpoint selection flow through
ServiceEnmandCaptchaOptionsSer.urls_set()rather than being reimplemented by each solver. - Rationale: 2Captcha/RuCaptcha JSON APIs, DeathByCaptcha-compatible URLs, and CaptchaAI classic URLs have distinct wire boundaries.
- Enforcement / Signals:
src/python_rucaptcha/core/enums.pyandsrc/python_rucaptcha/core/serializer.py;BaseCaptchacallsurls_set()during initialization.
- Rule: Generic task creation/results and transport failures use
GetTaskResultResponseSerand itsto_dict()representation. - Rationale: Different adapters and services present one stable library-facing result contract.
- Enforcement / Signals:
src/python_rucaptcha/core/serializer.py,src/python_rucaptcha/core/base.py, andsrc/python_rucaptcha/core/result_handler.pyconstruct or return the serializer.
- Rule: Remote submission and result retrieval use the configured retry policies, polling attempt generator, and caller-visible sleep interval.
- Rationale: The library is a client of asynchronous human-solving services and must tolerate delayed results without an unbounded local loop.
- Enforcement / Signals:
RETRIES,ASYNC_RETRIES, andattempts_generator()insrc/python_rucaptcha/core/config.py; polling loops insrc/python_rucaptcha/core/result_handler.pyandsrc/python_rucaptcha/core/captchaai.py.
- Rule: Direct CaptchaAI calls use
CaptchaAIplus packaged profiles; new provider methods must not require per-method branches in the native transport or conversion intoBaseCaptcha. - Rationale: CaptchaAI’s classic multipart contract differs from the generic JSON task API and is intentionally extensible through metadata.
- Enforcement / Signals: Separate façade/transport modules, profile lookups in
src/python_rucaptcha/core/captchaai.py, packaged data declaration inpyproject.toml, and local guidance insrc/python_rucaptcha/core/AGENTS.md.
- Rule: Both CaptchaAI profile JSON files must ship with the installed wheel when the native path is used.
- Rationale: Profile validation, compatibility translation, and control mappings load these files at runtime.
- Enforcement / Signals:
tool.setuptools.package-datainpyproject.toml, file reads insrc/python_rucaptcha/core/captchaai.py, and the files undersrc/python_rucaptcha/core/data/.
- Rule: Task state is request-local/in-memory, with optional local image files; solving state and results remain on the external provider APIs.
- Rationale: The package is an SDK boundary for consumer applications, not a server or worker owning a task database.
- Enforcement / Signals: Runtime dependencies and source layout contain HTTP clients but no database, web-server, queue, or worker framework;
src/python_rucaptcha/core/base.pystores payloads and task IDs on instances.
ARCHITECTURE.md owns the global architecture map, dependency direction, representative flows, and durable invariants. It should remain a navigation document rather than an API reference, usage tutorial, deployment runbook, or per-solver catalog.
AGENTS.mddefines repository-wide contribution and context-routing rules; childAGENTS.mdfiles refine those rules forsrc/python_rucaptcha/,core/,tests/, anddocs/.README.mdowns the public overview, installation/usage examples, supported services, and high-level feature claims.docs/index.rst,docs/conf.py, anddocs/modules/own the Sphinx navigation, autodoc configuration, and per-CAPTCHA examples.okf/contains the project-local OKF v0.1 knowledge bundle: concept-oriented architecture and operational knowledge, stable cross-links, update history, and citation-backed repository evidence. It complements this document and should not duplicate the global architecture map.tests/AGENTS.mdand the test modules define test-fixture and validation conventions; they are evidence for behavior, not replacements for this architecture map.- Provider API contracts remain external service documentation; repository schemas are represented by
src/python_rucaptcha/core/serializer.pyand the packaged CaptchaAI profile data. - No repository-local ADR, runbook, or
DESIGN.mdis present in the active tracked layout; if such documents are added, they should own decisions, operations, or visual design rather than duplicating this map.