# Connect Postgres for Flask

## Summary

Connect a Flask app to PostgreSQL on Ample. Read DATABASE_URL at runtime with psycopg: when you supply one with --env it is delivered encrypted and takes precedence; when you supply none and the app needs PostgreSQL, Ample auto-provisions a managed PostgreSQL 16 database and injects its connection string.

## Infrastructure requirements

- psycopg reading the DATABASE_URL environment variable at runtime  
- Either a production DATABASE_URL to pass with --env, or nothing (auto-provision)  
- An Ample account token with servers:write and databases:read

## Exact tested configuration

- template: `python-3.12`  
- runtime: `python`  
- size: `s-1vcpu-1gb`  
- install: `python3 -m pip install --target .ample/python -r requirements.txt`  
- start: `PYTHONPATH=.ample/python:${PYTHONPATH:-} python3 app.py`

## Steps

1. **Read the URL at runtime.** Open connections from the DATABASE_URL environment variable inside the app; never commit credentials and never connect at build time.  
2. **Choose the source of the database.** Pass --env DATABASE_URL=... for an existing database, or omit it to let Ample provision a managed one on first deploy and reuse it on redeploys.
   
   ```
   ample deploy . --name <app-name> --public --start "python3 run.py"
   ```
3. **Test the connection through the app.** Expose a route (/items) that runs a trivial query and returns postgres=ok.
4. **Verify.** Fetch the live URL and run the success checks below. On failure read the build log, then the runtime log, fix the cause and deploy again; do not blind-retry.
   
   ```
   ample logs <deployment_id> --kind build
   ```

## Tested examples

- **Flask + PostgreSQL canary** (tests/deploy-canaries/flask-postgres-app): Auto-provisioned managed database with a real query.

## Success checks

- database route reports a live connection (`/items` on the live URL, expect postgres=ok)

## Limitations

- Verified on the node-22 template at s-1vcpu-1gb; other templates and sizes are not verified by this recipe.  
- Region, compliance attestations and request-duration limits are unknown and not claimed.  
- Apps auto-pause when idle and wake on the next request; always-on is an operator setting, not a plan feature.
- Managed PostgreSQL 16 only; extensions, connection limits and backup or restore procedures are not verified.  
- Apps and their managed databases are placed together; cross-node shared databases are unsupported.

## Cost estimate

Estimated 10.00 USD per month (size prices from pricing.toml at build revision a1b8c38919e59cd035ebabaced73cf84ece24371).
- app server x1 `s-1vcpu-1gb`: 5.00 USD  
- managed PostgreSQL database x1 `s-1vcpu-1gb`: 5.00 USD

## Verification evidence

- canary_run on 2026-09-20T01:42:25Z at revision `199ff1dfd52683832ae75d3f98b53a7a4bff7f96-dirty (CLI e3181f5)`: Flask app (waitress) using psycopg with an auto-provisioned managed PostgreSQL database: /items reported postgres=ok and /config confirmed the encrypted secret. (expires 2027-03-19T01:42:25Z)  
- canary_run on 2026-09-19T23:55:33Z at revision `1764076-tls-account-903d345`: Node app needing PostgreSQL with no DATABASE_URL: a managed database was auto-provisioned and /db reported postgres=ok. (expires 2027-03-18T23:55:33Z)

Last verified: 2026-09-20T01:42:25Z

## Execution binding

MCP tool `ample_deploy` (registry `mcp:ample_deploy`), schema hash `876465fce906da0c` observed 2026-09-20T01:55:48.667900+00:00 at revision `199ff1dfd526`, binding state `current`, required scopes: servers:write, databases:read.
