Metadata-Version: 2.4
Name: api-autopsy
Version: 0.1.0
Summary: Production-grade API performance analysis platform for Django and FastAPI
Project-URL: Homepage, https://github.com/api-autopsy/api-autopsy
Project-URL: Documentation, https://api-autopsy.readthedocs.io
Project-URL: Repository, https://github.com/api-autopsy/api-autopsy
Project-URL: Issues, https://github.com/api-autopsy/api-autopsy/issues
Author: API Autopsy Contributors
License: MIT
License-File: LICENSE
Keywords: api,apm,django,fastapi,performance,profiling
Classifier: Development Status :: 4 - Beta
Classifier: Framework :: Django
Classifier: Framework :: FastAPI
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Topic :: System :: Monitoring
Requires-Python: >=3.9
Provides-Extra: all
Requires-Dist: asyncpg>=0.27.0; extra == 'all'
Requires-Dist: django>=3.2; extra == 'all'
Requires-Dist: fastapi>=0.68.0; extra == 'all'
Requires-Dist: redis>=4.0.0; extra == 'all'
Requires-Dist: starlette>=0.14.0; extra == 'all'
Provides-Extra: dev
Requires-Dist: aiosqlite>=0.19.0; extra == 'dev'
Requires-Dist: httpx>=0.24.0; extra == 'dev'
Requires-Dist: pytest-asyncio>=0.21.0; extra == 'dev'
Requires-Dist: pytest-cov>=4.0; extra == 'dev'
Requires-Dist: pytest>=7.0; extra == 'dev'
Provides-Extra: django
Requires-Dist: django>=3.2; extra == 'django'
Provides-Extra: fastapi
Requires-Dist: fastapi>=0.68.0; extra == 'fastapi'
Requires-Dist: starlette>=0.14.0; extra == 'fastapi'
Provides-Extra: postgres
Requires-Dist: asyncpg>=0.27.0; extra == 'postgres'
Provides-Extra: redis
Requires-Dist: redis>=4.0.0; extra == 'redis'
Description-Content-Type: text/markdown

# 🔬 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.

[![Python 3.9+](https://img.shields.io/badge/python-3.9+-blue.svg)](https://python.org)
[![License: MIT](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE)

---

## ⚡ Quickstart

### Install

```bash
pip install api-autopsy
```

### Django

```python
# settings.py
INSTALLED_APPS += ["api_autopsy"]

MIDDLEWARE += ["api_autopsy.integrations.django.middleware.APIAutopsyMiddleware"]
```

### FastAPI

```python
from fastapi import FastAPI
from api_autopsy.integrations.fastapi import APIAutopsyMiddleware

app = FastAPI()
app.add_middleware(APIAutopsyMiddleware)
```

**That's it.** Visit [`/api-autopsy/`](http://localhost:8000/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

```python
# 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

```python
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

```bash
# 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

```python
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

```toml
# 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

```bash
pip install -e ".[dev]"
pytest tests/ -v
```

---

## Production Safety

- **Sampling**: Set `sample_rate` to `0.01`–`0.1` for high-traffic
- **Overhead**: < 5% with sampling; collectors are lightweight
- **Retention**: Auto-cleanup via `retention_hours` or CLI
- **Async-safe**: Uses `contextvars` — no thread-local issues

---

## License

MIT
