Python client for Esper bot detection API
Project description
Esper Python Client
Lightweight Python client library for Esper bot detection API.
Installation
pip install esper-py-client
Quick Start
from esper import EsperClient, EsperConfig, MitigationRequest, MitigationAction
# Initialize client
config = EsperConfig(api_key="your-api-key")
client = EsperClient(config)
# Check if request should be mitigated
request = MitigationRequest(
ip="192.168.1.1",
user_agent="Mozilla/5.0...",
path="/api/endpoint",
method="POST"
)
response = client.check_mitigation(request)
if response.action == MitigationAction.BLOCK:
# Block the request
print("Request blocked:", response.reason)
elif response.action == MitigationAction.CHALLENGE:
# Present challenge to user
print("Challenge required:", response.challenge)
else:
# Allow the request
print("Request allowed")
Async Support
import asyncio
from esper import AsyncEsperClient, EsperConfig, MitigationRequest
async def check_request():
config = EsperConfig(api_key="your-api-key")
async with AsyncEsperClient(config) as client:
request = MitigationRequest(ip="192.168.1.1")
response = await client.check_mitigation(request)
return response
# Run async function
response = asyncio.run(check_request())
Configuration
from esper import EsperConfig
config = EsperConfig(
api_key="your-api-key", # Required
api_url="https://api.esperr.com", # Optional
beacon_url="https://beacon.esperr.com", # Optional
timeout=30.0, # Optional (seconds)
max_retries=3, # Optional
retry_delay=1.0 # Optional (seconds)
)
API Reference
Check Mitigation
from esper import MitigationRequest
request = MitigationRequest(
ip="192.168.1.1",
user_agent="Mozilla/5.0...",
path="/api/endpoint",
method="POST",
headers={"X-Custom": "value"},
metadata={"user_id": "123"}
)
response = client.check_mitigation(request)
print(f"Action: {response.action}")
print(f"Score: {response.score}")
print(f"Reason: {response.reason}")
Verify Challenge
# Verify user's challenge response
is_valid = client.verify_challenge(
token="challenge-token",
response="user-response"
)
if is_valid:
print("Challenge passed")
else:
print("Challenge failed")
Send Beacon Event
from esper import BeaconEvent
# Send telemetry event
event = BeaconEvent(
type="page_view",
ip="192.168.1.1",
user_agent="Mozilla/5.0...",
session_id="session-123",
data={"page": "/home", "referrer": "/login"}
)
client.send_beacon_event(event)
Get Usage Statistics
# Get API usage
usage = client.get_usage()
print(f"Total requests: {usage.requests}")
print(f"Blocked: {usage.blocked}")
print(f"Challenged: {usage.challenged}")
print(f"Allowed: {usage.allowed}")
Django Integration
# middleware.py
from django.http import JsonResponse
from esper import EsperClient, EsperConfig, MitigationRequest
class EsperMiddleware:
def __init__(self, get_response):
self.get_response = get_response
config = EsperConfig(api_key=settings.ESPER_API_KEY)
self.client = EsperClient(config)
def __call__(self, request):
# Check mitigation
mitigation_request = MitigationRequest(
ip=self.get_client_ip(request),
user_agent=request.META.get('HTTP_USER_AGENT'),
path=request.path,
method=request.method
)
try:
response = self.client.check_mitigation(mitigation_request)
if response.action == MitigationAction.BLOCK:
return JsonResponse({"error": "Access denied"}, status=403)
elif response.action == MitigationAction.CHALLENGE:
return JsonResponse({"challenge": response.challenge.dict()}, status=429)
except Exception as e:
# Log error and allow request on failure
logger.error(f"Esper error: {e}")
return self.get_response(request)
def get_client_ip(self, request):
x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
if x_forwarded_for:
return x_forwarded_for.split(',')[0]
return request.META.get('REMOTE_ADDR')
FastAPI Integration
from fastapi import FastAPI, Request, HTTPException
from esper import AsyncEsperClient, EsperConfig, MitigationRequest
app = FastAPI()
config = EsperConfig(api_key="your-api-key")
esper = AsyncEsperClient(config)
@app.middleware("http")
async def esper_middleware(request: Request, call_next):
# Check mitigation
mitigation_request = MitigationRequest(
ip=request.client.host,
user_agent=request.headers.get("user-agent"),
path=request.url.path,
method=request.method
)
try:
response = await esper.check_mitigation(mitigation_request)
if response.action == MitigationAction.BLOCK:
raise HTTPException(status_code=403, detail="Access denied")
elif response.action == MitigationAction.CHALLENGE:
return JSONResponse(
status_code=429,
content={"challenge": response.challenge.dict()}
)
except Exception as e:
# Log error and continue
logger.error(f"Esper error: {e}")
return await call_next(request)
Error Handling
from esper import (
EsperAPIError,
EsperConnectionError,
EsperTimeoutError
)
try:
response = client.check_mitigation(request)
except EsperAPIError as e:
print(f"API error: {e.message}")
print(f"Status code: {e.status_code}")
print(f"Error code: {e.error_code}")
except EsperConnectionError as e:
print(f"Connection error: {e}")
except EsperTimeoutError as e:
print(f"Timeout error: {e}")
Testing
# Install development dependencies
pip install -e ".[dev]"
# Run tests
pytest
# Run tests with coverage
pytest --cov=esper
# Type checking
mypy src/esper
# Linting
ruff check src/esper
# Formatting
black src/esper
isort src/esper
License
MIT
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
esper_py_client-0.1.0.tar.gz
(9.9 kB
view details)
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 esper_py_client-0.1.0.tar.gz.
File metadata
- Download URL: esper_py_client-0.1.0.tar.gz
- Upload date:
- Size: 9.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.10.0 {"installer":{"name":"uv","version":"0.10.0","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
80a3ef3746453537adbdc93af35acc4b3d759d75bd27699b8bf346cf97e8e56d
|
|
| MD5 |
4efbe84bbc2d962d96b2c07efd88cd83
|
|
| BLAKE2b-256 |
44be5972c6375dd27a71a747a788600f4d9d05f238df8c3a531cfefb32446ec6
|
File details
Details for the file esper_py_client-0.1.0-py3-none-any.whl.
File metadata
- Download URL: esper_py_client-0.1.0-py3-none-any.whl
- Upload date:
- Size: 8.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.10.0 {"installer":{"name":"uv","version":"0.10.0","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3e185d969ae5e9e133b952adce722db13091d83e34097c73c4ba106ad95c625f
|
|
| MD5 |
f0a5607c34ec051e1308911d8a6e4230
|
|
| BLAKE2b-256 |
f5b470c3b14fe36dc1db597fb4b52defa3e596f774b8dd0c4d12af7e041676bd
|