Docs / Python

Deploy Python

FastAPI, Django, Flask or any ASGI/WSGI app on Python 3.12.

Detected by

requirements.txt or pyproject.toml at the top of the project. The general rules are in Deploying.

Build

  • Python 3.12 on Debian (slim).
  • pip install -r requirements.txt, or pip install . when there is only a pyproject.toml.
  • Packages with wheels for Linux x86-64 install fastest; psycopg[binary] needs no compiler.

Start

systemi.toml start, else a Procfile web: line, else: with main.py or app.py at the top, uvicorn main:app when fastapi or uvicorn is in your requirements, gunicorn main:app when gunicorn is, and python main.py otherwise (that last one must read PORT itself).

Example

main.py

import os
from fastapi import FastAPI
import psycopg

app = FastAPI()

@app.get("/")
def home():
    return {"ok": True}

@app.get("/orders")
def orders():
    with psycopg.connect(os.environ["DATABASE_URL"]) as conn:
        return conn.execute("SELECT id, total FROM orders ORDER BY id DESC LIMIT 20").fetchall()

requirements.txt

fastapi
uvicorn
psycopg[binary]

Frameworks

FrameworkStart command or setting
FastAPIuvicorn main:app --host 0.0.0.0 --port $PORT
Djangogunicorn mysite.wsgi -b 0.0.0.0:$PORT --workers 2
Flaskgunicorn app:app -b 0.0.0.0:$PORT

Good to know

  • Django: set ALLOWED_HOSTS to your name.systemi.in, SECURE_PROXY_SSL_HEADER = ("HTTP_X_FORWARDED_PROTO", "https"), and run collectstatic before you zip (or serve static files with WhiteNoise). Run migrations from your machine or with Pilotbase against your systemi database.
  • Files are read-only at run time, so Python writes no .pyc files; that is expected.
  • Keep workers low (one or two) on smaller plans; each gunicorn worker is a full copy of your app in memory.