Skip to content

About

A todo API with interactive docs, on managed Postgres. Starter template for velixir.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

2 Commits

Folders and files

Repository files navigation

FastAPI + Postgres

Deploy on velixir

A small todo API, live on its own URL in minutes, with every endpoint testable from the browser at /docs. FastAPI, SQLAlchemy 2 and Pydantic on the front, managed Postgres behind.

Deploy it on velixir.

The todos are the least interesting part. The point of this template is the wiring: how an API finds its database, creates its tables, rides out a database that is not there yet, and reports health honestly. Swap the todos for your own resources and keep the rest.

What it shows

  • Finding the database. The managed Postgres bound to the app arrives as DATABASE_URL. db.py rewrites its postgres:// scheme to postgresql+psycopg://, which SQLAlchemy needs, and leaves sslmode=require to libpq, which encrypts without checking the certificate against public CAs: exactly what velixir's own CA calls for.
  • Tables on start, without the crash loop. A background thread creates the tables and keeps retrying until the database answers. Meanwhile the API returns 503 with a Retry-After header and the home page explains the wait. It recovers on its own.
  • A setup page instead of a crash. Start it with no database and / says exactly how to bind one, the API answers 503 with the same instructions, and /healthz stays green.
  • An honest health check. /healthz runs SELECT 1, so a lost database takes the app out of rotation rather than letting it serve errors.
  • Types as the contract. Pydantic models decide what the API accepts and returns, and the docs at /docs and the schema at /openapi.json are generated from the same code.
  • Correct behind the proxy. uvicorn trusts the edge's forwarded headers (--forwarded-allow-ips "*" in the Procfile), so the app sees the visitor's address and scheme rather than the edge's.

Setting it up on velixir

Deploy it from the gallery. velixir creates a managed Postgres, binds it to the app as DATABASE_URL, and holds the first deploy until the database is running, so the app starts connected. The table is created on first boot.

By hand, for example after deploying your own copy with velixir deploy:

  1. Create a managed Postgres from the Databases page, or run velixir db create.
  2. Bind it to the app as DATABASE_URL: on the database's page under Bound apps, or velixir db bind <database-id> --app <app-id>.
  3. Redeploy, with the Redeploy button on the live release in the Deploys tab.

API

Method Path Does
GET / A landing page with links to the docs
GET /docs Interactive docs: try every endpoint from the browser
GET /redoc The same API as a reference page
GET /api/todos Newest 100 todos as JSON, ?done=true or ?done=false to filter
POST /api/todos Create one, {"title": "..."}
GET /api/todos/{id} One todo
PATCH /api/todos/{id} Change title, done, or both
DELETE /api/todos/{id} Delete one
GET /healthz 200 when the database answers (or no database is bound yet), 503 while it is unreachable

Running it locally

python -m venv .venv
. .venv/bin/activate                 # .venv\Scripts\activate on Windows
pip install -r requirements.txt
DATABASE_URL=postgres://user:pass@localhost:5432/todos uvicorn main:app --reload --port 8080

Then open http://localhost:8080/docs. With no sslmode in the URL, the connection is plain TCP, which is what a local Postgres expects.

Deploying

velixir deploy

Things to know before you rely on it

There is no authentication. Anyone with the URL can read, change and delete every todo. Add auth before storing anything you care about. FastAPI's security helpers make an API key header a few lines of code.

Tables are created, not migrated. create_all makes missing tables and never alters existing ones, so a column added to the model does not reach a table that already exists. Move to a migration tool such as Alembic before your first schema change on real data.

One process by default. It already serves many requests at once: uvicorn is asynchronous, and the database handlers run in a thread pool. On a bigger plan, set WEB_CONCURRENCY for more worker processes.

The certificate is not verified by default. The connection is encrypted, but sslmode=require does not check who issued the certificate, which matches what it means everywhere else. To verify the server as well, download your database's CA certificate from its page in the velixir dashboard and connect with sslmode=verify-full. See https://velixir.net/docs/databases#verifying-the-server-certificate.

The Free plan sleeps. After 15 idle minutes the app stops, and the next request wakes it, which takes a few seconds.

Licence

MIT.

About

A todo API with interactive docs, on managed Postgres. Starter template for velixir.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages