Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
0d1671e
Update idna requirement from >=3.15 to >=3.18
dependabot[bot] Jun 3, 2026
63e43f2
[github-actions] Bump codecov/codecov-action from 6 to 7
dependabot[bot] Jun 8, 2026
4dd59aa
feat: add CaptchaAI as a provider (classic in.php/res.php adapter)
bshahin Jun 17, 2026
4bb9fa9
[github-actions] Bump actions/checkout from 6 to 7
dependabot[bot] Jun 18, 2026
abddcaa
style: narrow broad except clauses to specific exceptions (requests/a…
bshahin Jun 19, 2026
c5fc8f3
Bump black from 25.11.0 to 26.5.1
dependabot[bot] Jun 29, 2026
4c253a3
Update pytest requirement from ==8.* to ==9.*
dependabot[bot] Jun 29, 2026
b70cebd
Update zipp requirement from >=3.23.1 to >=4.1.0
dependabot[bot] Jun 29, 2026
51d713c
Update urllib3 requirement from >=2.2.2 to >=2.7.0
dependabot[bot] Jun 29, 2026
3864447
upd agents
AndreiDrang Jul 11, 2026
3341797
Merge pull request #367 from bshahin/add-captchaai-provider
AndreiDrang Jul 11, 2026
b01aa91
Merge pull request #372 from AndreiDrang/dependabot/pip/urllib3-gte-2…
AndreiDrang Jul 11, 2026
8e7ca2c
Merge branch 'master' into dependabot/pip/zipp-gte-4.1.0
AndreiDrang Jul 11, 2026
dc146c9
Merge pull request #371 from AndreiDrang/dependabot/pip/zipp-gte-4.1.0
AndreiDrang Jul 11, 2026
2ec761e
Merge pull request #370 from AndreiDrang/dependabot/pip/pytest-eq-9.star
AndreiDrang Jul 11, 2026
2df7595
Merge pull request #369 from AndreiDrang/dependabot/pip/black-26.5.1
AndreiDrang Jul 11, 2026
71c9aa5
Merge branch 'master' into dependabot/pip/idna-gte-3.18
AndreiDrang Jul 11, 2026
f27e8ab
Merge pull request #364 from AndreiDrang/dependabot/pip/idna-gte-3.18
AndreiDrang Jul 11, 2026
3fd713a
Merge pull request #365 from AndreiDrang/dependabot/github_actions/co…
AndreiDrang Jul 11, 2026
290eff5
Merge pull request #368 from AndreiDrang/dependabot/github_actions/ac…
AndreiDrang Jul 11, 2026
350360e
Update index.rst
AndreiDrang Jul 11, 2026
b8e8064
feat: add schema-driven CaptchaAI client
AndreiDrang Jul 11, 2026
e92b767
v6.7.0
AndreiDrang Jul 11, 2026
3af4eca
Merge pull request #373 from AndreiDrang/fix/captchaai-classic-api
AndreiDrang Jul 11, 2026
7291c0d
feat(captcha): add TSPD, Basilisk, Alibaba, and Imperva/Incapsula cap…
AndreiDrang Jul 11, 2026
7f9b7e0
chore: update AGENTS.md documentation and test file
AndreiDrang Jul 11, 2026
594aefa
v6.8.0
AndreiDrang Jul 11, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ jobs:
python-version: ["3.9", "3.10", "3.11", "3.12"]

steps:
- uses: actions/checkout@v6
- uses: actions/checkout@v7
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v6
with:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/install.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ jobs:
python-version: ["3.9", "3.10", "3.11", "3.12"]

steps:
- uses: actions/checkout@v6
- uses: actions/checkout@v7
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v6
with:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ jobs:
python-version: ["3.12"]

steps:
- uses: actions/checkout@v6
- uses: actions/checkout@v7
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v6
with:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/sphinx.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jobs:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v6
- uses: actions/checkout@v7
- uses: actions/setup-python@v6

- name: Build docs requirements
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ jobs:
python-version: ["3.11"]

steps:
- uses: actions/checkout@v6
- uses: actions/checkout@v7
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v6
with:
Expand All @@ -48,7 +48,7 @@ jobs:
run: make tests

- name: Upload coverage to Codecov
uses: codecov/codecov-action@v6
uses: codecov/codecov-action@v7
with:
token: ${{ secrets.CODECOV_TOKEN }}
files: ${{github.workspace}}/coverage/coverage.xml
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/zai-code-bot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v6
uses: actions/checkout@v7

- name: Run Z.ai Bot
uses: AndreiDrang/zai-code-bot@main
Expand Down
117 changes: 55 additions & 62 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -1,68 +1,61 @@
# PROJECT KNOWLEDGE BASE
# AGENTS.md

**Generated:** 2026-02-20
**Commit:** 86ee3e6
**Branch:** master
## Repository overview

## OVERVIEW
Python 3.9+ library for RuCaptcha/2Captcha/DeathByCaptcha service APIs. Supports 30+ CAPTCHA types with dual sync/async interfaces.
- `python-rucaptcha` is a Python 3.9+ setuptools library for the 2Captcha, RuCaptcha, DeathByCaptcha, and CaptchaAI APIs.
- The package uses a `src/` layout and provides synchronous and asynchronous CAPTCHA solver handlers.
- The repository is a single package, not a monorepo. The root `AGENTS.md` applies everywhere unless a nearer local file applies.

## STRUCTURE
```
./
├── src/python_rucaptcha/ # Main package (30+ captcha modules)
│ └── core/ # Base classes, serializers, enums
├── tests/ # Pytest test suite (23+ files)
├── docs/ # Sphinx documentation
├── pyproject.toml # Build config (black 110, isort, pytest)
└── Makefile # Build automation
```
## Instruction scope

- Local instruction files are `src/python_rucaptcha/AGENTS.md`, `src/python_rucaptcha/core/AGENTS.md`, `tests/AGENTS.md`, and `docs/AGENTS.md`.
- A nearer `AGENTS.md` adds local guidance; it does not repeat or silently contradict this file. Sibling files do not affect one another.
- No `AGENTS.override.md` files are present. If one is introduced, it takes precedence only within its own directory.

## Where to work

## WHERE TO LOOK
| Task | Location | Notes |
|------|----------|-------|
| Add new CAPTCHA | `src/python_rucaptcha/` | Create module inheriting `BaseCaptcha` |
| Modify API flow | `src/python_rucaptcha/core/base.py` | `_processing_response()` methods |
| Change serialization | `src/python_rucaptcha/core/serializer.py` | `MyBaseModel` class |
| Add CAPTCHA enum | `src/python_rucaptcha/core/enums.py` | 25+ enum classes |
| Run tests | `tests/` | Requires `RUCAPTCHA_KEY` env var |

## CODE MAP
| Symbol | Type | Location | Role |
|--------|------|----------|------|
| BaseCaptcha | Class | core/base.py | Parent for all captcha solvers |
| MyBaseModel | Class | core/serializer.py | msgspec Struct wrapper |
| CaptchaOptionsSer | Class | core/config.py | Service URL abstraction |
| MyEnum | Class | core/enums.py | Custom enum with utils |

## CONVENTIONS
- **Line length**: 110 chars (pyproject.toml)
- **Async mode**: `asyncio_mode = auto` in pytest
- **No tox**: Uses Makefile directly for test/lint
- **Import order**: isort with black profile

## ANTI-PATTERNS (THIS PROJECT)
- No TODO/FIXME/DEPRECATED comments in code
- No explicit "DO NOT" directives
- Logging warnings output full result objects (potential sensitive data)

## UNIQUE STYLES
- **25+ custom enums**: Each CAPTCHA type has dedicated enum (e.g., `HCaptchaEnm`)
- **Service abstraction**: Unified API for 2Captcha/RuCaptcha/DeathByCaptcha
- **msgspec**: Fast serialization (replaced pydantic v6.0)
- **Dual sync/async**: Every captcha class has both handlers

## COMMANDS
```bash
make install # pip install -e .
make tests # Run pytest with coverage
make lint # autoflake + black + isort check
make build # Build package
make doc # Build Sphinx docs
```text
src/python_rucaptcha/ # CAPTCHA implementations and package API
└── core/ # Base request flow, service config, serializers, enums, CaptchaAI profile data
tests/ # Pytest suite and shared fixtures
docs/ # Sphinx sources and per-CAPTCHA examples
pyproject.toml # setuptools, Black, isort, and pytest configuration
Makefile # install, lint, test, build, and documentation workflows
```

## NOTES
- Tests require live API keys (`RUCAPTCHA_KEY`, `DEATHBYCAPTCHA_KEY`)
- CI runs on Python 3.11 (tests) / 3.12 (lint) — version mismatch
- No cross-platform testing (only ubuntu-latest)
- x.py in root is debug script (non-standard)
Do not hand-edit `dist/` or `src/python_rucaptcha.egg-info/`; they are build/package metadata outputs.

## Architecture and boundaries

- Concrete CAPTCHA modules inherit from `BaseCaptcha` in `src/python_rucaptcha/core/base.py`. Keep CAPTCHA-specific payload preparation in the concrete module, not in the shared base flow.
- `core/` owns request/polling behavior, service URL selection, msgspec serialization, result models, and shared enums. Changes there can affect every solver.
- Each solver's synchronous and asynchronous handlers must preserve the same task semantics and response shape. Service task field names are part of the external API contract.
- The data-driven `captchaai` client (top-level `captchaai.py` + `core/captchaai.py`) is deliberately separate from the `BaseCaptcha` flow: it validates packaged JSON profiles in `core/data/` instead of branching on task types. Do not refactor it into the `BaseCaptcha` pattern or add per-method branches to it.

## Context routing

- For public usage and supported solver/service behavior, read `README.md`.
- For contribution expectations, read `CONTRIBUTING.md` before preparing a project-wide change.
- For documentation changes, read `docs/index.rst` and `docs/conf.py`; the local rules are in `docs/AGENTS.md`.
- For build, formatting, test, or packaging changes, read `pyproject.toml`, `Makefile`, and the relevant `.github/workflows/*.yml` file.
- No `ARCHITECTURE.md` is present; use the core modules and package-local instructions as the current implementation source of truth.

## Change rules

- Adding a solver normally requires a new package module, a matching enum in `core/enums.py`, tests under `tests/`, and a documentation example/toctree entry when it is user-facing.
- Preserve the existing flat `*_captcha.py` module naming and `{CaptchaType}Captcha`/`{CaptchaType}Enm` naming patterns.
- Do not put solver-specific branches into `BaseCaptcha` merely to support one CAPTCHA type.
- Never commit API keys or add diagnostics that expose credentials or complete service responses unnecessarily. The integration tests make external service calls.

## Validation

- Formatting/static checks: `make lint` (autoflake, Black, and isort over `src/`).
- Integration tests and coverage: `make tests`; collection requires `RUCAPTCHA_KEY`, and DeathByCaptcha coverage may use `DEATHBYCAPTCHA_KEY`.
- Package build: `make build`.
- Sphinx documentation: `make doc`.
- CI runs tests on Python 3.11, lint on 3.12, and build checks on Python 3.9–3.12; account for the supported `requires-python >= 3.9` range.

## Repository-specific gotchas

- `tests/conftest.py` reads `RUCAPTCHA_KEY` while defining `BaseTest`, so missing credentials can prevent normal test collection rather than merely skip a test.
- The test fixtures deliberately sleep between cases and the suite is not an offline-only unit suite; use targeted tests while iterating, then run the relevant full command before handoff.
62 changes: 61 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,63 @@
[![Downloads](https://static.pepy.tech/badge/python-rucaptcha/month)](https://pepy.tech/project/python-rucaptcha)
[![Documentation](https://img.shields.io/badge/docs-Sphinx-green)](https://andreidrang.github.io/python-rucaptcha/)

**Python 3.9+ library to solve CAPTCHAs automatically using RuCaptcha, 2Captcha, or DeathByCaptcha services.**
**Python 3.9+ library to solve CAPTCHAs automatically using RuCaptcha, 2Captcha, DeathByCaptcha, or CaptchaAI services.**

> **Using CaptchaAI:** compatible high-level classes can pass `service_type=ServiceEnm.CAPTCHAAI`.
> CaptchaAI uses the classic multipart `in.php`/`res.php` endpoints.
> ```python
> from python_rucaptcha.turnstile import Turnstile
> from python_rucaptcha.core.enums import ServiceEnm
> result = Turnstile(
> rucaptcha_key="CAPTCHAAI_KEY",
> service_type=ServiceEnm.CAPTCHAAI,
> websiteURL="https://example.com",
> websiteKey="0x4AAAAAAA...",
> userAgent="Mozilla/5.0 ...",
> ).captcha_handler()
> ```
>
> Proxy task types require `proxyType`, `proxyAddress`, and `proxyPort`; credentials are optional:
> ```python
> from python_rucaptcha.re_captcha import ReCaptcha
> from python_rucaptcha.core.enums import ReCaptchaEnm, ServiceEnm
>
> result = ReCaptcha(
> rucaptcha_key="CAPTCHAAI_KEY",
> service_type=ServiceEnm.CAPTCHAAI,
> websiteURL="https://example.com/login",
> websiteKey="SITE_KEY",
> method=ReCaptchaEnm.RecaptchaV2Task,
> proxyType="HTTPS",
> proxyAddress="203.0.113.7",
> proxyPort=3128,
> proxyLogin="user",
> proxyPassword="pass",
> ).captcha_handler()
> ```
>
> For every documented CaptchaAI method—or a provider method released after this package—use the native,
> type-free client. `profile` validates a packaged documented contract; omit it to pass provider-native fields
> through unchanged.
> ```python
> from python_rucaptcha.captchaai import CaptchaAI, CaptchaAIFile
>
> result = CaptchaAI(
> rucaptcha_key="CAPTCHAAI_KEY",
> profile="cloudflare-challenge",
> params={
> "pageurl": "https://example.com/protected",
> "proxy": "user:pass@203.0.113.7:3128",
> "proxytype": "HTTPS",
> },
> ).captcha_handler()
>
> image = CaptchaAI(
> rucaptcha_key="CAPTCHAAI_KEY",
> profile="normal-solve-file",
> files={"file": CaptchaAIFile(b"... PNG bytes ...", "captcha.png", "image/png")},
> ).captcha_handler()
> ```

## What is this?

Expand Down Expand Up @@ -108,6 +164,10 @@ token = asyncio.run(solve())
| KeyCaptcha | `KeyCaptcha` | KeyCAPTCHA service |
| Amazon WAF | `AmazonWaf` | AWS WAF challenge |
| ALTCHA | `AltchaCaptcha` | ALTCHA challenge |
| TSPD | `TSPDCaptcha` | Cookie-based TSPD protection |
| Basilisk | `BasiliskCaptcha` | Token-based Basilisk challenge |
| Alibaba | `AlibabaCaptcha` | Token-based Alibaba challenge |
| Imperva/Incapsula | `IncapsulaCaptcha` | Cookie-based Imperva protection |
| Binance | `BinanceCaptcha` | Token-based Binance challenge |
| Grid | `GridCaptcha` | Select grid cells |
| Coordinates | `CoordinatesCaptcha` | Click on coordinates |
Expand Down
35 changes: 35 additions & 0 deletions docs/AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# AGENTS.md

## Scope and inheritance

Applies to: `docs/` and its descendants.

Inherits repository-wide guidance from `../AGENTS.md`.

This file defines only local differences for the Sphinx documentation subtree.

## What lives here

```text
docs/
├── conf.py # Sphinx extensions, autodoc imports, theme, metadata
├── index.rst # Main toctrees and documentation navigation
├── modules/ # Per-CAPTCHA examples and supporting Markdown/RST
├── _static/ # Images and other published assets
├── requirements.txt # Documentation-only dependencies
└── Makefile # Local Sphinx build wrapper
```

## Local boundaries and invariants

- Sphinx configuration imports the package's solver modules directly and uses autodoc; documentation builds therefore depend on importable, current Python modules.
- User-facing solver additions should have a matching example under `docs/modules/` and an entry in the appropriate `index.rst` toctree. Keep example parameter names aligned with the actual solver payload.
- Keep generated `_build/` output out of source edits. Static images belong in `docs/_static/` when they are part of the published docs.

## Validation

From the repository root, run `make doc`; it installs the package and invokes the Sphinx build in `docs/`. For a docs-only iteration, `cd docs && make html -e` uses the local documentation Makefile after its requirements are installed.

## Nearby docs

Read `docs/index.rst` when changing navigation and `docs/conf.py` when changing extensions, autodoc imports, theme settings, or published metadata.
4 changes: 4 additions & 0 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,17 @@
grid_captcha,
temu_captcha,
text_captcha,
tspd_captcha,
image_captcha,
lemin_captcha,
yidun_captcha,
rotate_captcha,
alibaba_captcha,
binance_captcha,
basilisk_captcha,
datadome_captcha,
friendly_captcha,
incapsula_captcha,
cyber_siara_captcha,
draw_around_captcha,
bounding_box_captcha,
Expand Down
5 changes: 5 additions & 0 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,13 @@ Check our other projects here - `RedPandaDev group <https://red-panda-dev.xyz/bl
modules/captcha-fox/example.rst
modules/captcha-temu/example.rst
modules/captcha-vk/example.rst
modules/captchaai/example.rst
modules/yidun-necaptcha/example.rst
modules/yandex-smart-captcha/example.rst
modules/tspd-captcha/example.rst
modules/basilisk-captcha/example.rst
modules/alibaba-captcha/example.rst
modules/incapsula-captcha/example.rst
modules/control/example.rst

.. toctree::
Expand Down
21 changes: 21 additions & 0 deletions docs/modules/alibaba-captcha/example.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
Alibaba captcha
================

To import this module:

.. code-block:: python

from python_rucaptcha.alibaba_captcha import AlibabaCaptcha
from python_rucaptcha.core.enums import AlibabaEnm


.. autoclass:: python_rucaptcha.alibaba_captcha.AlibabaCaptcha
:members:

The required ``sceneId`` and ``prefix`` values, together with optional values
such as ``userId``, ``verifyType``, ``region``, and ``userCertifyId``, are
page-specific and should be extracted from the captcha initialization
requests. ``apiGetLib`` may also be generated dynamically.

The result is a JSON string in ``solution.data.tokens``. Parse it with
``json.loads`` before resending the Alibaba verification request.
21 changes: 21 additions & 0 deletions docs/modules/basilisk-captcha/example.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
Basilisk captcha
=================

To import this module:

.. code-block:: python

from python_rucaptcha.basilisk_captcha import BasiliskCaptcha
from python_rucaptcha.core.enums import BasiliskEnm


.. autoclass:: python_rucaptcha.basilisk_captcha.BasiliskCaptcha
:members:

The proxyless task requires ``websiteURL`` and ``websiteKey``. Use
``BasiliskEnm.BasiliskTask`` when the solve must use your own proxy and provide
``proxyType``, ``proxyAddress``, and ``proxyPort``.

The token is returned as ``solution.data.captcha_response``. If the response
contains ``solution.headers.User-Agent``, reuse that User-Agent in the request
to the target site.
Loading
Loading