Official CaptchaSonic Python SDK — modern, async-ready, gRPC + HTTP
Project description
captchasonic
Official CaptchaSonic library for Python.
The CaptchaSonic Python SDK is a modern, async-ready library designed for high-throughput automation. It features first-class type hints, dual-transport flexibility (gRPC + HTTP), and automatic retry logic.
Works in Python 3.10+ — scripts, notebooks, Django, FastAPI, Flask, and CLI tools.
Installation
pip install captchasonic
For HTTP transport (optional):
pip install "captchasonic[http]"
Quick Start
from captchasonic import CaptchaSonic
solver = CaptchaSonic("YOUR_API_KEY")
result = solver.solve_recaptcha_v2(
images=[tile1, tile2, tile3],
question="traffic lights",
)
print(result["typed_solution"]["grid"]["objects"]) # [2, 4, 7]
Usage — Geetest (nine-grid)
from captchasonic import CaptchaSonic
solver = CaptchaSonic("YOUR_API_KEY")
try:
result = solver.solve_geetest(
geetest_type="nine",
question="Select all bicycles",
images=tiles, # list[bytes | Path | str]
)
print("Solution:", result["typed_solution"])
except Exception as err:
print("Error:", err)
Async Usage
The SDK ships a full async client with identical methods.
import asyncio
from captchasonic import AsyncCaptchaSonic
async def main():
async with AsyncCaptchaSonic("YOUR_API_KEY") as solver:
result = await solver.solve_geetest(
geetest_type="nine",
question="Select all bicycles",
images=tiles,
)
print("Solution:", result["typed_solution"])
asyncio.run(main())
Configuration
solver = CaptchaSonic(
"YOUR_API_KEY",
transport="grpc", # "grpc" (default) or "http"
url="api.captchasonic.com:443", # Override the API endpoint. Optional.
base_url=None, # Alias for url. Optional.
timeout=30.0, # Per-call timeout in seconds. Default: 30.
polling_interval=2.0, # Seconds between task polls. Default: 2.
polling_timeout=120.0, # Max seconds to wait for async task. Default: 120.
secure=True, # Use TLS for gRPC. Default: True.
)
Transport guide:
| Transport | Environments | Protocol |
|---|---|---|
grpc (default) |
Server-side Python | gRPC binary over HTTP/2 — lowest latency |
http |
Universal | Plain REST/JSON via httpx |
grpcsends images as raw binary — zero base64 overhead.httpauto-encodes images to base64 before sending.
Solve Methods
All methods accept keyword arguments with full type hints and docstrings.
solve_popular_captcha()
solver.solve_popular_captcha(
images=list[ImageInput],
question=str, # e.g. "Select all traffic lights"
question_type=str, # "objectClassify" | "objectClick" | "objectDrag" | "grid"
examples=list[ImageInput], # optional
screenshot=bool, # optional, default False
website_url=str, # optional
website_key=str, # optional
)
solve_recaptcha_v2()
solver.solve_recaptcha_v2(
images=list[ImageInput],
question=str, # "traffic lights" or "/m/015qff"
question_type=str, # "split_33" | "33" | "44". Optional.
website_url=str, # optional
website_key=str, # optional
)
solve_geetest()
solver.solve_geetest(
geetest_type=str, # "nine" | "click" | "slide" | "match" | "winlinze"
question=str, # required for "nine" and "click"
images=list[ImageInput], # required for "nine", "click", "slide"
examples=list[ImageInput], # optional
gtv=int, # Geetest version (e.g. 3). Optional.
website_url=str, # optional
)
# Type aliases also accepted:
# "nine" → "geetest_nine" | "9"
# "click" → "geetest_click" | "icon"
# "slide" → "geetest_slide"
# "match" → "geetest_match"
# "winlinze" → "geetest_winlinze"
solve_ocr()
solver.solve_ocr(
images=list[ImageInput],
module=str, # "common" | "mtcaptcha" | "bls" | "morocco". Optional.
numeric=bool, # Expect only digits. Optional.
case_sensitive=bool, # Preserve letter case. Optional.
min_length=int, # Minimum text length. Optional.
max_length=int, # Maximum text length. Optional.
website_url=str, # optional
)
# Returns: result["typed_solution"]["text"]["texts"][0]
solve_tiktok()
solver.solve_tiktok(
type=str, # "click" | "whirl" | "slide" (or "tiktok_click" etc.)
question=str, # optional
images=list[ImageInput],
examples=list[ImageInput], # required for "whirl" and "slide"
website_url=str, # optional
)
solve_binance()
solver.solve_binance(
type=str, # "grid" | "slide" (or "binance_grid" etc.)
question=str, # required for "grid"
images=list[ImageInput],
examples=list[ImageInput], # optional
website_url=str, # optional
)
solve_aws_waf()
solver.solve_aws_waf(
images=list[ImageInput],
question=str, # e.g. "grid:vehicles:cars"
website_url=str, # optional
website_key=str, # optional
)
solve_slide_image()
solver.solve_slide_image(images=[background, piece])
# Returns: result["typed_solution"]["slide"]["x"] — pixel offset
Token Automation Methods
These submit a task and poll until a token is returned (up to 120 s).
solver.solve_turnstile(website_url=..., website_key=..., proxy=...)
solver.solve_popular_captcha_token(website_url=..., website_key=..., proxy=..., metadata=...)
solver.solve_recaptcha_v2_token(website_url=..., website_key=..., proxy=...)
solver.solve_recaptcha_v3_token(website_url=..., website_key=..., proxy=...)
solver.solve_cloudflare(website_url=..., website_key=..., proxy=...) # proxy required
Account Methods
balance = solver.get_balance() # → float (USD)
solver.health_check() # → HealthCheckResponse
Image Input
from pathlib import Path
ImageInput = bytes | str | Path | BinaryIO
# File path
solver.solve_ocr(images=[Path("captcha.png")])
solver.solve_ocr(images=["./captcha.png"])
# Raw bytes
with open("captcha.png", "rb") as f:
solver.solve_ocr(images=[f.read()])
grpcsends images as raw binary — zero base64 overhead.httpauto-encodes images to base64 before sending.
Error Handling
from captchasonic import CaptchaSonic
from captchasonic.exceptions import SonicError
try:
result = solver.solve_geetest(geetest_type="nine", question="bicycles", images=tiles)
except SonicError as err:
print(err.error_id) # 1–6
print(type(err).__name__) # "InvalidApiKeyError" | "InsufficientBalanceError" | ...
print(err)
error_id |
Exception | Meaning |
|---|---|---|
| 1 | InvalidApiKeyError |
API key not valid |
| 2 | InsufficientBalanceError |
Insufficient credits |
| 3 | DailyLimitExceededError |
Daily quota exceeded |
| 4 | MinuteLimitExceededError |
Rate limit hit |
| 5 | QuotaExceededError |
Plan quota exceeded |
| 6 | PlanExpiredError |
Subscription expired |
Transient gRPC errors are retried automatically with exponential backoff — up to 3 attempts.
Context Manager
# Sync — auto-closes gRPC channel / HTTP session
with CaptchaSonic("YOUR_API_KEY") as solver:
result = solver.solve_ocr(images=[Path("captcha.png")])
print(result["typed_solution"]["text"]["texts"][0])
# Async
async with AsyncCaptchaSonic("YOUR_API_KEY") as solver:
result = await solver.solve_ocr(images=[Path("captcha.png")])
Requirements
- Python ≥ 3.10
- gRPC transport —
grpcio,protobuf(included) - HTTP transport —
httpx(install withpip install captchasonic[http])
License
MIT — see LICENSE
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file captchasonic-1.0.0.tar.gz.
File metadata
- Download URL: captchasonic-1.0.0.tar.gz
- Upload date:
- Size: 27.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1ead951100b5a38a68171c13267a06976d568fa6465328c39a18ff36cbb43cfa
|
|
| MD5 |
463d873b89ca4b81822454a4eb274eda
|
|
| BLAKE2b-256 |
d2a656515298b6a3b162b7a49c60f141e29a4cc7161d90a5f2cccc6a22bad124
|
File details
Details for the file captchasonic-1.0.0-py3-none-any.whl.
File metadata
- Download URL: captchasonic-1.0.0-py3-none-any.whl
- Upload date:
- Size: 28.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b76252ec5ce6d63ab02eb404f2e142e7902572b2584e0cc9c83e8dada76dcc4e
|
|
| MD5 |
6fbbec29e4a0f4875b2aa3e14638b725
|
|
| BLAKE2b-256 |
eac1a1295f036757313ab58a291aa89ce798c925aa98b9c053cfd965fa34298a
|