Skip to main content

Async-first, fully type-hinted, minimal captcha library with adapters for aiogram, FastAPI and Discord.

Project description

captchakit

Async-first, fully type-hinted captcha library for Python 3.10+. Zero runtime deps beyond Pillow. Drop-in adapters for FastAPI, aiogram and discord.py.

PyPI Python CI mypy: strict Ruff License: MIT


Why another one?

Feature lepture/captcha claptcha multicolorcaptcha captchakit
Async API
py.typed + mypy strict ⚠️
TTL & attempt tracking ✅ built-in
Pluggable storage Protocol
Framework adapters ✅ FastAPI · aiogram · discord.py
Runtime deps (core) +Pillow +Pillow +Pillow +Pillow

Install

pip install captchakit                  # core
pip install "captchakit[fastapi]"       # + FastAPI adapter
pip install "captchakit[aiogram]"       # + aiogram adapter (coming in 0.2)
pip install "captchakit[discord]"       # + discord.py adapter (coming in 0.3)
pip install "captchakit[redis]"         # + Redis storage backend (coming in 0.2)

Adapters other than FastAPI are declared in the roadmap but not shipped in 0.1 yet. The extras install today but the adapter modules land in later releases — see ROADMAP.md.

30-second example

import asyncio
from captchakit import (
    CaptchaManager, ImageRenderer, MemoryStorage, TextChallengeFactory,
)

async def main() -> None:
    manager = CaptchaManager(
        factory=TextChallengeFactory(length=5),
        renderer=ImageRenderer(),
        storage=MemoryStorage(),
        ttl=120.0,
        max_attempts=3,
    )
    challenge_id, png_bytes = await manager.issue()
    # ... show png_bytes to the user, receive their answer ...
    ok = await manager.verify(challenge_id, user_input="ABCDE")
    print("verified" if ok else "wrong answer, more attempts remain")

asyncio.run(main())

FastAPI in 10 lines

from fastapi import Depends, FastAPI
from captchakit import CaptchaManager, ImageRenderer, MathChallengeFactory, MemoryStorage
from captchakit.adapters.fastapi import captcha_router, verify_captcha

manager = CaptchaManager(MathChallengeFactory(), ImageRenderer(), MemoryStorage())
app = FastAPI()
app.include_router(captcha_router(manager, prefix="/captcha"))

@app.post("/register")
async def register(_: None = Depends(verify_captcha(manager))) -> dict[str, bool]:
    return {"ok": True}

Run the bundled demo:

uv run python -m uvicorn examples.fastapi_login:app --reload
# open http://127.0.0.1:8000

Design

┌─────────────────────────────────────────────────┐
│  Adapters (fastapi / aiogram / discord)         │
├─────────────────────────────────────────────────┤
│  CaptchaManager  (public facade)                │
├──────────────┬──────────────┬───────────────────┤
│  Challenge   │  Renderer    │  Storage          │
│  Text / Math │  Image (PIL) │  Memory / Redis   │
└──────────────┴──────────────┴───────────────────┘
  • Protocol-based, so you can drop in your own storage (Redis, Postgres, Memcached), your own renderer (SVG, WebP, audio), or your own challenge factory (wordlists, emoji grids, …).
  • Constant-time comparison via hmac.compare_digest.
  • Crypto-safe randomness via secrets for solution generation.
  • CPU-bound Pillow drawing offloaded to a worker thread via asyncio.to_thread, so the event loop never blocks.

Security scope

captchakit is a lightweight human-check, not a bot-farm-grade security layer. It is aimed at Telegram/Discord verification, simple FastAPI registration flows and similar use cases where you just want to raise the cost for casual spam.

For high-value forms (login, payment) use hCaptcha, Cloudflare Turnstile or reCAPTCHA Enterprise in addition. Combine captchakit with proper rate limiting at the edge of your application.

Roadmap

See ROADMAP.md for the full development plan.

Version Highlights
0.1 (MVP) Core + Text/Math challenges + Image renderer + Memory storage + FastAPI
0.2 aiogram + Redis storage + EmojiGridChallenge + docs site
0.3 discord.py adapter + AudioChallenge (optional) + WordChallenge
0.4 i18n + theming + metrics hooks
1.0 Stable API, semver commitment

Contributing

Contributions welcome. Local development:

git clone https://github.com/akerem16/captchakit
cd captchakit
uv sync --all-extras
uv run ruff check .
uv run mypy
uv run pytest

License

MIT — see LICENSE.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

captchakit-0.1.0.tar.gz (19.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

captchakit-0.1.0-py3-none-any.whl (16.3 kB view details)

Uploaded Python 3

File details

Details for the file captchakit-0.1.0.tar.gz.

File metadata

  • Download URL: captchakit-0.1.0.tar.gz
  • Upload date:
  • Size: 19.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for captchakit-0.1.0.tar.gz
Algorithm Hash digest
SHA256 d5a247e8037d871f767e66797dfd0089efd92d9f7a39247ad6302a91be821390
MD5 3d556d623c7a93b06a64bf3eab9fa651
BLAKE2b-256 17edbbb94db55c6bc45f4398c369782f3e3456733840fddee7583c42cbd00c38

See more details on using hashes here.

Provenance

The following attestation bundles were made for captchakit-0.1.0.tar.gz:

Publisher: release.yml on akerem16/captchakit

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file captchakit-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: captchakit-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 16.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for captchakit-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 f5d0fe993b732abedb41f8d22f7640126f9b57688f402f03d96b0820110d51c0
MD5 8843cd9a4273794278410d17ae39c857
BLAKE2b-256 929ea83e38d7f81b441439700e78116a8539ec6761852ef020922feb836fbc98

See more details on using hashes here.

Provenance

The following attestation bundles were made for captchakit-0.1.0-py3-none-any.whl:

Publisher: release.yml on akerem16/captchakit

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page