Python Integration
Track bot and AI crawler visits from any Python web application. Works with Django, Flask, and FastAPI.
Time to set up: ~2 minutes
Prerequisites
- A Python web application
- A BotSights account with a project created for your domain
- Your API Key (found in BotSights → Account → Projects → API Key)
Django
Add the middleware to your settings.py:
# settings.py
MIDDLEWARE = [
'yourapp.botsights.BotSightsDjangoMiddleware',
# ... other middleware
]Create yourapp/botsights.py:
import time
import json
import threading
from urllib.request import Request, urlopen
BOTSIGHTS_API_KEY = "YOUR_API_KEY_HERE"
BOTSIGHTS_API_URL = "https://www.botsights.com/api/log"
SKIP_EXT = {"css","js","png","jpg","jpeg","gif","svg","webp","ico","woff","woff2","ttf","mp4"}
def _send(data):
try:
req = Request(BOTSIGHTS_API_URL, json.dumps(data).encode(), method="POST")
req.add_header("Content-Type", "application/json")
urlopen(req, timeout=5)
except Exception:
pass
class BotSightsDjangoMiddleware:
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
ext = request.path.rsplit(".", 1)[-1] if "." in request.path else ""
if ext.lower() in SKIP_EXT:
return self.get_response(request)
start = time.time()
response = self.get_response(request)
duration = int((time.time() - start) * 1000)
data = {
"api_key": BOTSIGHTS_API_KEY,
"ua": request.META.get("HTTP_USER_AGENT", ""),
"url": request.get_full_path(),
"ip": (request.META.get("HTTP_CF_CONNECTING_IP")
or request.META.get("HTTP_X_FORWARDED_FOR", "").split(",")[0].strip()
or request.META.get("REMOTE_ADDR", "")),
"referer": request.META.get("HTTP_REFERER", ""),
"status_code": response.status_code,
"duration_ms": duration,
"content_type": response.get("Content-Type", ""),
"http_method": request.method,
"source": "python_django",
}
threading.Thread(target=_send, args=(data,), daemon=True).start()
return responseFlask
import time
import json
import threading
from urllib.request import Request, urlopen
from flask import Flask, request, g
BOTSIGHTS_API_KEY = "YOUR_API_KEY_HERE"
BOTSIGHTS_API_URL = "https://www.botsights.com/api/log"
def _send(data):
try:
req = Request(BOTSIGHTS_API_URL, json.dumps(data).encode(), method="POST")
req.add_header("Content-Type", "application/json")
urlopen(req, timeout=5)
except Exception:
pass
def init_botsights(app: Flask):
@app.before_request
def start_timer():
g._botsights_start = time.time()
@app.after_request
def track(response):
duration = int((time.time() - getattr(g, "_botsights_start", time.time())) * 1000)
data = {
"api_key": BOTSIGHTS_API_KEY,
"ua": request.headers.get("User-Agent", ""),
"url": request.full_path.rstrip("?"),
"ip": (request.headers.get("CF-Connecting-IP")
or request.headers.get("X-Forwarded-For", "").split(",")[0].strip()
or request.remote_addr or ""),
"referer": request.headers.get("Referer", ""),
"status_code": response.status_code,
"duration_ms": duration,
"content_type": response.content_type or "",
"http_method": request.method,
"source": "python_flask",
}
threading.Thread(target=_send, args=(data,), daemon=True).start()
return response
# Usage:
# app = Flask(__name__)
# init_botsights(app)FastAPI
import time
import json
import threading
from urllib.request import Request, urlopen
from starlette.middleware.base import BaseHTTPMiddleware
BOTSIGHTS_API_KEY = "YOUR_API_KEY_HERE"
BOTSIGHTS_API_URL = "https://www.botsights.com/api/log"
def _send(data):
try:
req = Request(BOTSIGHTS_API_URL, json.dumps(data).encode(), method="POST")
req.add_header("Content-Type", "application/json")
urlopen(req, timeout=5)
except Exception:
pass
class BotSightsMiddleware(BaseHTTPMiddleware):
async def dispatch(self, request, call_next):
start = time.time()
response = await call_next(request)
duration = int((time.time() - start) * 1000)
data = {
"api_key": BOTSIGHTS_API_KEY,
"ua": request.headers.get("user-agent", ""),
"url": str(request.url.path) + ("?" + str(request.url.query) if request.url.query else ""),
"ip": (request.headers.get("cf-connecting-ip")
or request.headers.get("x-forwarded-for", "").split(",")[0].strip()
or (request.client.host if request.client else "")),
"referer": request.headers.get("referer", ""),
"status_code": response.status_code,
"duration_ms": duration,
"content_type": response.headers.get("content-type", ""),
"http_method": request.method,
"source": "python_fastapi",
}
threading.Thread(target=_send, args=(data,), daemon=True).start()
return response
# Usage:
# from fastapi import FastAPI
# app = FastAPI()
# app.add_middleware(BotSightsMiddleware)How It Works
All three integrations work the same way: intercept the request, measure response time, then send analytics to BotSights in a background thread after the response is returned.
- Non-blocking — background thread, zero impact on response time
- Server-side — captures all visitors including bots
- Zero dependencies — uses Python's built-in
urllib(no pip install needed) - No cookies or client-side code