botcha-verify
Server-side verification middleware for BOTCHA JWT tokens.
Supports both JWKS-based ES256 verification (recommended) and shared-secret HS256 verification (legacy).
Installation
pip install botcha-verify
For FastAPI support:
pip install "botcha-verify[fastapi]"
For Django support:
pip install "botcha-verify[django]"
Note: The
[crypto]extra (cryptography) is included automatically for ES256 key support.
Usage
JWKS Verification (Recommended)
Fetches BOTCHA's public key from the JWKS endpoint. No shared secret to manage.
from botcha_verify import verify_botcha_token, VerifyOptions
result = verify_botcha_token(
token="eyJhbG...",
options=VerifyOptions(
jwks_url="https://botcha.ai/.well-known/jwks",
audience="https://api.example.com",
)
)
if result.valid:
print(f"Challenge solved in {result.payload.solve_time}ms")
else:
print(f"Invalid token: {result.error}")
Legacy: Shared Secret Verification
Still supported for existing HS256 integrations.
from botcha_verify import verify_botcha_token, VerifyOptions
result = verify_botcha_token(
token="eyJhbG...",
secret="your-secret-key",
options=VerifyOptions(audience="https://api.example.com")
)
FastAPI
from fastapi import FastAPI, Depends
from botcha_verify.fastapi import BotchaVerify
from botcha_verify import BotchaPayload
app = FastAPI()
# RECOMMENDED: JWKS verification
botcha = BotchaVerify(jwks_url='https://botcha.ai/.well-known/jwks')
# LEGACY: Shared secret
# botcha = BotchaVerify(secret='your-secret-key')
@app.get('/api/data')
async def get_data(token: BotchaPayload = Depends(botcha)):
return {"solve_time": token.solve_time}
Django
# settings.py
MIDDLEWARE = [
# ... other middleware
'botcha_verify.django.BotchaVerifyMiddleware',
]
# RECOMMENDED: JWKS verification
BOTCHA_JWKS_URL = 'https://botcha.ai/.well-known/jwks'
# LEGACY: Shared secret
# BOTCHA_SECRET = 'your-secret-key'
BOTCHA_PROTECTED_PATHS = ['/api/']
BOTCHA_EXCLUDED_PATHS = ['/api/health']
# views.py
def my_view(request):
if hasattr(request, 'botcha'):
print(f"Solved in {request.botcha.solve_time}ms")
return JsonResponse({"data": "protected"})
Migration from Shared Secret to JWKS
During the transition period, provide both secret and jwks_url. JWKS is tried first with a fallback to the shared secret:
result = verify_botcha_token(
token="eyJhbG...",
secret="your-secret-key", # fallback during migration
options=VerifyOptions(
jwks_url="https://botcha.ai/.well-known/jwks",
audience="https://api.example.com",
)
)
Token Structure
BOTCHA JWT tokens contain:
sub: Challenge IDiss: Issuer (botcha.ai, validated in JWKS mode)iat: Issued at (Unix timestamp)exp: Expiry (Unix timestamp)jti: JWT ID for revocationtype: "botcha-verified"solveTime: Challenge solve time in millisecondsaud: (optional) Audience claimclient_ip: (optional) Client IP binding
License
MIT
Metadata
Release files for botcha-verify 0.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| botcha_verify-0.2.0.tar.gz | 9.4 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| botcha_verify-0.2.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 19.0 kB
Release files / botcha_verify-0.2.0.tar.gz
| Download URL | botcha_verify-0.2.0.tar.gz |
|---|---|
| Size | 9.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
1691cb899fce05a02a3c863681ce5e1e457d6aa5f8cf4d171a97f89d409c1190
|
|
BLAKE2b-256 checksum How to use checksums |
9f8a79e6774c82272c62eca6d37c41d37a1615865970f27c195dfe037adff4c5
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.9
|
Release files / botcha_verify-0.2.0-py3-none-any.whl
| Download URL | botcha_verify-0.2.0-py3-none-any.whl |
|---|---|
| Size | 9.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
733ffef6af92eb14438c4deaf1cbfdb224c01facafa753d95ffd6058f40097fa
|
|
BLAKE2b-256 checksum How to use checksums |
6bfc52434355bee9962fe20003b0ff2e89fff9fa2eede1ac4c2a08a72188586e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.9
|