Flaxon 0.3.0 and Teloce-Py 0.3.0 are available on PyPI. Release instructions are maintained on this site; source links identify the framework snapshot. Check version and upgrade guidance.

Framework source · Markdown

Deploying Flaxon Apps

A note on how this doc is sourced, since deployment platforms change their behavior over time: claims about Flaxon itself (ASGI compliance, the module system, the serverless-detection pattern) were built and tested in this environment, including a simulated real Lambda event handled end to end. Claims specific to Vercel's and AWS's current platform behavior (entrypoint detection, timeouts, framework detection) are sourced from each platform's own current documentation, not memorized -- check the linked pages if something has changed since.

Why this works at all: Flaxon apps are plain ASGI apps

Flaxon implements the ASGI protocol directly -- async def __call__(self, scope, receive, send) -- with no framework- specific glue in between. That means any host that can run a standard ASGI application can run a Flaxon app, without Flaxon needing its own special integration for each one. This is verified, not assumed: a bare Flaxon app was wrapped with Mangum (the standard AWS Lambda ASGI adapter) and handled a simulated real Lambda/API Gateway event correctly, with zero Flaxon-side changes.


Vercel

Per Vercel's current docs, the Python runtime auto-detects a supported framework from requirements.txt/pyproject.toml/Pipfile, and looks for an ASGI or WSGI application object named app in one of these entrypoint files: app.py, index.py, server.py, main.py, wsgi.py, or asgi.py (or a custom path via tool.vercel.entrypoint in pyproject.toml). ASGI apps are supported natively -- Vercel's own docs describe the Python runtime as running "ASGI and WSGI applications including FastAPI, Flask, Django, and other Python web frameworks."

Conveniently, Flaxon's own flaxon new scaffold already generates app.py with a top-level app = Flaxon(...) -- one of Vercel's default entrypoints, no restructuring needed for the basic case.

Minimal setup

myapp/
├── app.py              # exposes `app` -- Vercel finds this automatically
├── requirements.txt
└── vercel.json
# app.py
from flaxon import Flaxon

app = Flaxon("myapp")

@app.get("/")
async def home():
    return {"message": "Hello from Flaxon on Vercel"}
# requirements.txt
flaxon
// vercel.json
{
  "rewrites": [{ "source": "/(.*)", "destination": "/app.py" }]
}

Deploy with vercel deploy or by connecting the repo through the Vercel dashboard/CLI.

What actually needs adapting for Vercel specifically

Nothing Flaxon-side needs a code adapter to run on Vercel -- the app object works as-is. What genuinely needs attention is Vercel's execution model, which is meaningfully different from a long-running server. This is the part worth being careful about:

1. WebSocket-dependent modules should not be mounted on Vercel

Per Vercel's own current documentation, standard Vercel Functions are short-lived and stateless, and WebSockets are explicitly called out as unreliable in that model. If you've built anything with Flaxon's WebSocket support (live-updating admin panels, the CMS live feed from earlier in this project, chat features), don't mount those routes when deploying to Vercel -- detect the environment and skip them:

import os
from flaxon import Flaxon
from flaxon.modules import FlaxonModule

IS_SERVERLESS = bool(os.environ.get("VERCEL"))

app = Flaxon("myapp")

api = FlaxonModule("api")

@api.get("/ping")
async def ping():
    return {"pong": True}

app.mount_module(api, prefix="/api")

if not IS_SERVERLESS:
    live = FlaxonModule("live")

    @live.websocket("/updates")
    async def updates(socket):
        await socket.accept()
        # ... live updates ...

    app.mount_module(live, prefix="/live")

Verified: the same app object built with VERCEL set vs. unset correctly includes or excludes the WebSocket route, while the HTTP routes work identically either way. Vercel sets VERCEL=1 in its Function environment automatically -- no manual configuration needed to detect it.

2. Don't rely solely on on_startup for critical initialization

Flaxon's @app.on_startup hooks fire on the ASGI lifespan protocol. Whether a given serverless host reliably drives that protocol the same way a long-running server does is host-specific and not something to assume — as a defensive measure for any serverless target, do critical setup (e.g. opening a DB connection) at module level too, so it runs on every cold start regardless of whether lifespan events fire the way they would locally under flaxon run:

from flaxon.database.manager import DatabaseManager
from flaxon.database.adapters.postgresql import PostgreSQLAdapter

db = DatabaseManager(PostgreSQLAdapter(...))
app.container.register_instance("db", db)

# Also keep the normal hook for local dev / hosts that do drive lifespan:
@app.on_startup
async def setup():
    await db.initialize()

3. Real limits to plan around (from Vercel's current docs)

  • Execution timeout: 10 seconds on the free plan, 60 seconds on Pro (longer with Fluid Compute, which has its own pricing model -- check current Vercel docs before relying on it)
  • No persistent background processes or workers in the standard model -- Flaxon's flaxon worker/flaxon schedule CLI commands assume a long-running process and don't fit this model at all; run those on a different host (see below) if you need them
  • Bundle size: 500MB standard, up to 5GB on the "Large Functions" beta -- relevant if your requirements.txt pulls in heavy DB drivers

AWS Lambda (via Mangum)

Unlike Vercel, AWS Lambda doesn't natively speak ASGI -- it needs an adapter to translate Lambda/API Gateway events into ASGI scope/receive/ send calls. Mangum is the standard tool for this, framework-agnostic, and was verified here to correctly wrap a real Flaxon app and handle a simulated API Gateway event end to end.

# lambda_handler.py
from flaxon import Flaxon
from mangum import Mangum

app = Flaxon("myapp")

@app.get("/hello")
async def hello():
    return {"message": "from flaxon on lambda"}

handler = Mangum(app, lifespan="off")
pip install mangum

Set the Lambda function's handler to lambda_handler.handler. Point API Gateway (HTTP API, for simplicity) at the function.

lifespan="off" is the safer default here for the same reason as the Vercel note above -- do critical initialization at module level, not solely inside @app.on_startup, since Lambda's relationship to the lifespan protocol is adapter-mediated rather than native. Same serverless caveats apply as Vercel: no long-running flaxon worker/ flaxon schedule, WebSockets need API Gateway's separate WebSocket API (more setup than the REST/HTTP API path, not covered here).

If you'd rather avoid Lambda's event-translation model entirely, AWS App Runner or ECS Fargate run a normal container with a normal long-running ASGI server -- see "Container-based hosting" below; no Mangum needed, same as any other container host.


Platforms with normal, long-running processes

These are the simplest deployment targets for Flaxon, since nothing needs adapting at all -- Flaxon apps run exactly the way they do locally, WebSockets and background workers included.

All three run your app as a normal long-running process from a Dockerfile or buildpack. This is the right choice for anything using Flaxon's WebSocket features, flaxon worker, or flaxon schedule, none of which fit a serverless execution model.

# Dockerfile
FROM python:3.12-slim

WORKDIR /app
COPY . .
RUN pip install --no-cache-dir -e . uvicorn[standard]

EXPOSE 8000
CMD ["flaxon", "run", "app:app", "--host", "0.0.0.0", "--port", "8000"]

Fly.io: fly launch detects the Dockerfile and deploys it. Railway/Render: connect the repo, both auto-detect a Dockerfile.

Any VPS / bare server

Same Dockerfile works standalone (docker run -p 8000:8000 myapp), or skip Docker entirely and run flaxon run app:app --host 0.0.0.0 --port 8000 behind a reverse proxy (nginx/Caddy) for TLS termination. For production, prefer running under a process manager (systemd, or multiple Uvicorn workers via --workers if flaxon run exposes it, otherwise invoke uvicorn app:app directly with --workers N) rather than a single foreground process.


Choosing a platform

Need Best fit
Simple API, no WebSockets, want zero-config Vercel
Existing AWS infrastructure, comfortable with Lambda AWS Lambda + Mangum
WebSocket features (CMS live updates, chat, etc.) Fly.io / Railway / Render / any container host -- not Vercel or Lambda's REST path
flaxon worker / flaxon schedule background processes Any long-running host -- not serverless
Full control, existing ops setup Docker on a VPS

If you're not sure yet, start with Fly.io/Railway/Render: nothing about your Flaxon app needs to change later if you decide to add WebSocket features, since you're not fighting a serverless execution model to begin with.