Skip to content

Instantly share code, notes, and snippets.

@pydanny
Created November 27, 2025 03:33
Show Gist options
  • Select an option

  • Save pydanny/3d3642f3eec42f51cdfa5bc3752c4751 to your computer and use it in GitHub Desktop.

Select an option

Save pydanny/3d3642f3eec42f51cdfa5bc3752c4751 to your computer and use it in GitHub Desktop.

This design follows FastAPI best practices:

import asyncpg
from contextlib import asynccontextmanager
from typing import Callable
from os import getenv # convert to pydantic_settings

import air

DATABASE_URL = getenv('DATABASE_URL')


def make_lifespan(dsn: str, *, min_size: int = 1, max_size: int = 10) -> Callable:
    @asynccontextmanager
    async def lifespan(app: Air):
        async with asyncpg.create_pool(
            dsn=dsn,
            min_size=min_size,
            max_size=max_size,
        ) as pool:
            yield {'pool': pool}

    return lifespan

lifespan = make_lifespan(DATABASE_URL)
app = air.Air(lifespan=lifespan)

Usage:

@app.page
async def index(request: Request):
    async with request.state.pool.acquire() as conn:
        users = await conn.fetchmany(
            "SELECT * FROM users;"
        )
    return *[air.P(u) for x in users]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment