Production-grade API performance analysis platform for Django and FastAPI
Project description
๐ฌ API Autopsy
Production-grade API performance analysis for Django and FastAPI.
Automatically detect performance issues โ N+1 queries, blocking async calls, slow serializers โ without external APM services.
โก Quickstart
Install
pip install api-autopsy
Django
# settings.py
INSTALLED_APPS += ["api_autopsy"]
MIDDLEWARE += ["api_autopsy.integrations.django.middleware.APIAutopsyMiddleware"]
FastAPI
from fastapi import FastAPI
from api_autopsy.integrations.fastapi import APIAutopsyMiddleware
app = FastAPI()
app.add_middleware(APIAutopsyMiddleware)
That's it. Visit /api-autopsy/ to see the dashboard.
๐ฏ What It Detects
| Category | Detection |
|---|---|
| N+1 Queries | Repeated SQL patterns across a single request |
| Duplicate Queries | Identical SQL executed multiple times |
| Slow Queries | Individual queries exceeding thresholds |
| Missing Indexes | Slow WHERE clauses on non-primary columns |
| Slow Serializers | DRF serializer timing and nested cost |
| Async Violations | time.sleep(), requests.* in async handlers |
| Memory Bloat | Per-request memory allocation deltas |
| External Calls | Outbound HTTP call count and timing |
Every detection comes with actionable recommendations.
๐ Performance Score
Each endpoint receives a 0โ100 score based on:
- Latency (30%) โ exponential decay from ideal threshold
- Query Efficiency (30%) โ penalizes count, duplicates, N+1
- Memory Usage (20%) โ penalizes large allocation deltas
- Async Correctness (20%) โ binary penalties for blocking calls
๐ฅ๏ธ Dashboard
Auto-served at /api-autopsy/ with:
- Endpoint ranking table (sortable by score, latency, queries)
- Performance timeline (5-minute buckets over 24h)
- Slow endpoint heatmap (by hour)
- Analysis findings with severity and recommendations
- Dark/light mode toggle
- Auto-refresh every 30s
๐ง Configuration
Django
# settings.py
API_AUTOPSY = {
"ENABLED": True,
"STORAGE_BACKEND": "sqlite", # sqlite | postgres | redis
"STORAGE_DSN": "autopsy.db",
"SAMPLE_RATE": 1.0, # 0.0โ1.0
"RETENTION_HOURS": 72,
"DASHBOARD_PREFIX": "/api-autopsy",
}
FastAPI
from api_autopsy.config import configure
configure(
sample_rate=0.1, # 10% sampling in production
retention_hours=48,
storage_dsn="/var/data/autopsy.db",
)
๐ CI/CD Mode
# Generate JSON report
api-autopsy analyze --format json --output report.json
# Fail CI if score drops below threshold
api-autopsy analyze --threshold 70
# Detect regression against a baseline
api-autopsy analyze --baseline baseline.json --threshold 10
# Cleanup old data
api-autopsy cleanup --hours 24
Exit codes: 0 = pass, 1 = regression or critical findings.
๐ Extensibility
Custom Analyzer
from api_autopsy.plugins import register_analyzer
from api_autopsy.analyzers.base import BaseAnalyzer
from api_autopsy.core.context import Finding
@register_analyzer
class MyCustomAnalyzer(BaseAnalyzer):
def analyze(self, ctx):
findings = []
if ctx.duration_ms > 1000:
findings.append(Finding(
severity="warning",
category="slow_response",
message=f"Response took {ctx.duration_ms:.0f}ms",
recommendation="Consider caching or pagination.",
))
return findings
Via Entry Points
# pyproject.toml
[project.entry-points."api_autopsy.plugins"]
my_plugin = "my_package.autopsy:register"
๐๏ธ Architecture
api_autopsy/
โโโ config.py # Central configuration + auto-detection
โโโ plugins.py # Plugin discovery system
โโโ core/
โ โโโ context.py # contextvars-based RequestContext
โ โโโ registry.py # Collector/Analyzer registry
โโโ collectors/
โ โโโ base.py # Abstract collector
โ โโโ timing.py # Request duration
โ โโโ sql.py # SQL queries + duplicates
โ โโโ memory.py # Memory delta (tracemalloc)
โ โโโ http_calls.py # Outbound HTTP tracking
โ โโโ cache.py # Cache hit/miss tracking
โโโ analyzers/
โ โโโ base.py # Abstract analyzer
โ โโโ orm.py # N+1, duplicates, slow queries
โ โโโ serializer.py # DRF serializer profiling
โ โโโ async_safety.py # Blocking I/O detection
โโโ scoring/
โ โโโ engine.py # Weighted 0โ100 scoring
โโโ storage/
โ โโโ base.py # Abstract storage
โ โโโ sqlite.py # SQLite backend (default)
โโโ dashboard/
โ โโโ views.py # Django + ASGI handlers
โ โโโ templates/
โ โโโ index.html # Dashboard UI
โโโ integrations/
โ โโโ django/
โ โ โโโ apps.py # Django AppConfig
โ โ โโโ middleware.py # WSGI middleware
โ โโโ fastapi/
โ โโโ middleware.py # ASGI middleware
โโโ cli/
โโโ main.py # CLI entry point
๐งช Testing
pip install -e ".[dev]"
pytest tests/ -v
Production Safety
- Sampling: Set
sample_rateto0.01โ0.1for high-traffic - Overhead: < 5% with sampling; collectors are lightweight
- Retention: Auto-cleanup via
retention_hoursor CLI - Async-safe: Uses
contextvarsโ no thread-local issues
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
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 api_autopsy-0.1.0.tar.gz.
File metadata
- Download URL: api_autopsy-0.1.0.tar.gz
- Upload date:
- Size: 27.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0de0479d52657649c3c714bddaadb2d0e21dea216fe795e3ed4367e2ae014862
|
|
| MD5 |
7dc4cbefb17c115e7d0f28c98de87744
|
|
| BLAKE2b-256 |
4c567682e8c910c94c2f9176b7538974e97a3a94e6f65cf1b7cab528c05c9770
|
File details
Details for the file api_autopsy-0.1.0-py3-none-any.whl.
File metadata
- Download URL: api_autopsy-0.1.0-py3-none-any.whl
- Upload date:
- Size: 40.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
29fb845ba9af56e69c5ddc0323019da3cf4434b8461c386e36cd31f32c9560fc
|
|
| MD5 |
bc0286d26b13e674a07cfe71e393f403
|
|
| BLAKE2b-256 |
bdb31b9f54e57d1f73c823ef0f0bc2294c9bf59fa1e3bd3ca692e620aca7499b
|