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 response

Flask

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