# Monitor a Python app with Lampwick

> Start FastAPI or Django with opentelemetry-instrument and Lampwick gets requests, queries, errors and logging records. No code changes.

Python apps send to Lampwick through OpenTelemetry. You start the app with `opentelemetry-instrument` and set environment variables; the code stays as it is. We tested FastAPI on uvicorn and Django with `runserver`.

## What you get

- **Requests**, named after the route or URL pattern, such as `GET /orders/{order_id}`.
- **Queries**, linked to the request they ran in.
- **Issues** from unhandled exceptions with the stack trace, and handled ones from `logger.exception`.
- **Logs** from `logging`, linked to their request.

## Set it up

In the app's virtualenv:

```bash
pip install opentelemetry-distro opentelemetry-exporter-otlp-proto-http
opentelemetry-bootstrap -a install
```

`opentelemetry-bootstrap` adds the instrumentations for what's installed. Run it again after adding a framework or database driver. Then set:

```bash
export OTEL_EXPORTER_OTLP_ENDPOINT=https://app.lampwick.dev
export OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf
export OTEL_EXPORTER_OTLP_HEADERS=x-lampwick-token=YOUR_PROJECT_TOKEN
export OTEL_SERVICE_NAME=my-app
export OTEL_METRICS_EXPORTER=none
export OTEL_LOGS_EXPORTER=otlp
```

`YOUR_PROJECT_TOKEN` is the project's ingest token, from the **Connect your app** card on its **Settings** page. Python defaults to gRPC, which Lampwick doesn't accept, so keep `OTEL_EXPORTER_OTLP_PROTOCOL`. Start the app through the instrumentation:

```bash
opentelemetry-instrument uvicorn main:app --port 8000
```

For Django, set `DJANGO_SETTINGS_MODULE` and turn the autoreloader off:

```bash
export DJANGO_SETTINGS_MODULE=mysite.settings
opentelemetry-instrument python manage.py runserver --noreload
```

## What it doesn't do

- **`connection.execute()` on `sqlite3` isn't traced**, only `cursor.execute()`. Django and SQLAlchemy use cursors.
- **Info logs need a level**: Python drops records below `WARNING` unless you configure logging.
- **gunicorn and uWSGI** fork workers after the SDK starts. We haven't tested the `post_fork` hook they need.

## Let your agent do it

```text
Add OpenTelemetry to this Python app so it reports to Lampwick: follow https://lampwick.dev/docs/python.md exactly (opentelemetry-distro, opentelemetry-bootstrap, opentelemetry-instrument, the environment variables). Read the ingest token from the environment, never commit it.
```

## Next step

The [Python docs](/docs/python/) have the apps we tested, what showed up and the troubleshooting table. How spans map to Lampwick: [OpenTelemetry](/docs/opentelemetry/#what-shows-up-where).
