Metadata-Version: 2.4
Name: tracegarden
Version: 0.1.8
Summary: Developer-first visual backend devtools for Django, Flask, and FastAPI
Project-URL: Homepage, https://github.com/tracegarden/tracegarden
Project-URL: Documentation, https://github.com/tracegarden/tracegarden#readme
Project-URL: Repository, https://github.com/tracegarden/tracegarden
Project-URL: Issues, https://github.com/tracegarden/tracegarden/issues
License: MIT
License-File: LICENSE
Requires-Python: >=3.9
Requires-Dist: jinja2>=3.1.0
Requires-Dist: opentelemetry-api<2.0.0,>=1.20.0
Requires-Dist: opentelemetry-sdk<2.0.0,>=1.20.0
Provides-Extra: all
Requires-Dist: celery>=5.0; extra == 'all'
Requires-Dist: django>=3.2; extra == 'all'
Requires-Dist: fastapi>=0.95.0; extra == 'all'
Requires-Dist: flask>=2.0; extra == 'all'
Requires-Dist: httpx>=0.24.0; extra == 'all'
Requires-Dist: redis>=5.0; extra == 'all'
Requires-Dist: requests>=2.31.0; extra == 'all'
Requires-Dist: sqlalchemy>=1.4; extra == 'all'
Requires-Dist: starlette>=0.27.0; extra == 'all'
Provides-Extra: celery
Requires-Dist: celery>=5.0; extra == 'celery'
Requires-Dist: redis>=5.0; extra == 'celery'
Provides-Extra: dev
Requires-Dist: httpx; extra == 'dev'
Requires-Dist: mypy; extra == 'dev'
Requires-Dist: pytest; extra == 'dev'
Requires-Dist: pytest-asyncio; extra == 'dev'
Requires-Dist: requests; extra == 'dev'
Requires-Dist: ruff; extra == 'dev'
Provides-Extra: django
Requires-Dist: django>=3.2; extra == 'django'
Provides-Extra: fastapi
Requires-Dist: fastapi>=0.95.0; extra == 'fastapi'
Requires-Dist: starlette>=0.27.0; extra == 'fastapi'
Provides-Extra: flask
Requires-Dist: flask>=2.0; extra == 'flask'
Provides-Extra: http
Requires-Dist: httpx>=0.24.0; extra == 'http'
Requires-Dist: requests>=2.31.0; extra == 'http'
Provides-Extra: sqlalchemy
Requires-Dist: sqlalchemy>=1.4; extra == 'sqlalchemy'
Description-Content-Type: text/markdown

<p align="center">
  <img src="docs/screenshots/tracegarden.png" alt="TraceGarden" width="200"/>
</p>

# TraceGarden

Developer-first visual backend devtools for Django, Flask, and FastAPI.

TraceGarden captures request timelines (DB + HTTP + spans + Celery) into local SQLite and serves a built-in UI at `/__tracegarden`.

## Features

- WSGI + ASGI support (`Django`, `Flask`, `FastAPI`)
- OTel-native span ingestion into local TraceGarden UI
- DB query fingerprinting, grouping, duplicate and N+1 detection
- Outgoing HTTP inspector (`requests` / `httpx`)
- Celery stitching (`web request -> queued task -> worker state`)
- Trace bundle export (single JSON artifact)
- Development guardrails: redaction by default + UI token protection

## Installation

```bash
pip install tracegarden
# extras
pip install tracegarden[django]
pip install tracegarden[flask]
pip install tracegarden[fastapi]
pip install tracegarden[celery]
```

## Quick Start

### Django (one app + one middleware)

```python
# settings.py
INSTALLED_APPS = [
    ...,
    "tracegarden.integrations.django",
]

MIDDLEWARE = [
    "tracegarden.integrations.django.middleware.TraceGardenMiddleware",
    ...,
]

TRACEGARDEN = {
    "enabled": True,
    "ui_token": "dev-secret",
    "ui_token_header": "X-TraceGarden-Token",
    "ui_prefix": "/__tracegarden",
}

# urls.py
from tracegarden.ui.routes import mount_django_urls
urlpatterns = mount_django_urls() + urlpatterns
```

### Flask (init extension)

```python
from flask import Flask
from tracegarden import TraceGarden

app = Flask(__name__)
TraceGarden(app, ui_token="dev-secret")
```

### FastAPI (one middleware)

```python
from fastapi import FastAPI
from tracegarden import TraceGarden

app = FastAPI()
TraceGarden(app, ui_token="dev-secret")
```

## UI Access

Default route: `/__tracegarden/`

Pass token using one of:
- header: `X-TraceGarden-Token: dev-secret`
- query param: `?token=dev-secret`
- cookie: `tg_token=dev-secret`

## Screenshots

![Request list](docs/screenshots/request-list.svg)
![Request detail](docs/screenshots/request-detail.svg)

## OpenTelemetry

```python
from tracegarden.otel.setup import setup_otel

setup_otel(
    service_name="my-api",
    also_export_to_tracegarden=True,
)
```

## What gets recorded

See [docs/WHAT_IT_RECORDS.md](docs/WHAT_IT_RECORDS.md).

## End-to-end examples

See [examples/README.md](examples/README.md).

## License

MIT
