# Python Apps

`/admin/python-apps` lists every Python application across all accounts (one row per app). Filter by account, runtime version, status (running / stopped / errored). Per-app drill-down:

| Tab | What it covers |
|---|---|
| Overview | Owning account, app slug, listen port, runtime, process state, last error, requirements.txt path, virtualenv path, gunicorn workers |
| Settings | Runtime version (3.10 / 3.11 / 3.12), entry point module, environment variables (KEY=VALUE), worker count (capped by plan `python_workers_limit`), max memory (capped by plan `python_max_memory_mb`) |
| Logs | Application stdout / stderr tail (last N lines), gunicorn access log, systemd unit journal |
| Actions | Start / stop / restart, install requirements (long-running, SSE stream), reset state (clears any "errored" flag without restarting) |

The agent provisions a per-app systemd unit + nginx reverse-proxy snippet on activation. The plan's `max_python_apps` caps how many apps an account may create — `0` means no limit; one more than the limit is refused with `403 PYTHON_APP_LIMIT`.

**Domain binding.** An app's domain must already belong to the account it is created for — its primary, addon or subdomain name. Any other name, including another account's domain and the server's own hostname, is refused with `404 DOMAIN_NOT_FOUND` on both create and update; add the domain to the account first. The rule holds for admin and API callers too, since the vhost the app writes decides who serves that name.

**Environment variables.** The app's variables are saved as a whole set. When they cannot be read, the tab shows an error state with a Retry button and its Save stays off — saving would otherwise replace every stored variable with the ones on screen. The Node.js apps page behaves the same.

**Endpoints used:** `GET /accounts/{u}/python-apps`, `POST /accounts/{u}/python-apps`, `GET/PUT/DELETE /accounts/{u}/python-apps/{app}`, `POST /accounts/{u}/python-apps/{app}/{start,stop,restart}`, `POST /accounts/{u}/python-apps/{app}/install-requirements`, `GET /accounts/{u}/python-apps/{app}/logs`.

---
