FastAPI + AioSQLite Application

Serve SQLSpec-backed content through FastAPI with the AioSQLite adapter.

uv run python docs/examples/frameworks/fastapi/aiosqlite_app.py

Source

 1"""FastAPI application backed by SQLSpec and AioSQLite."""
 2
 3import asyncio
 4from typing import Annotated, Any
 5
 6from fastapi import Depends, FastAPI
 7
 8from docs.examples.shared.configs import aiosqlite_registry
 9from docs.examples.shared.data import ARTICLES, CREATE_ARTICLES
10from sqlspec.adapters.aiosqlite import AiosqliteDriver
11from sqlspec.core import SQL
12
13__all__ = ("get_session", "list_articles", "main", "on_startup", "seed_database")
14
15
16registry, config = aiosqlite_registry()
17app = FastAPI()
18
19
20async def seed_database() -> None:
21    """Create the demo schema and seed rows."""
22    async with config.provide_session() as session:
23        await session.execute(CREATE_ARTICLES)
24        for row in ARTICLES:
25            await session.execute(
26                SQL(
27                    """
28                    INSERT OR REPLACE INTO articles (id, title, body)
29                    VALUES (:id, :title, :body)
30                    """
31                ),
32                row,
33            )
34
35
36@app.on_event("startup")
37async def on_startup() -> None:
38    """Seed data when the FastAPI app starts."""
39    await seed_database()
40
41
42async def get_session() -> "AiosqliteDriver":
43    """Yield an AioSQLite session for request handlers."""
44    async with config.provide_session() as session:
45        yield session
46
47
48@app.get("/articles")
49async def list_articles(db_session: Annotated["AiosqliteDriver", Depends(get_session)]) -> "list[dict[str, Any]]":
50    """Return all demo articles sorted by ID."""
51    result = await db_session.execute(SQL("SELECT id, title, body FROM articles ORDER BY id"))
52    return result.all()
53
54
55def main() -> None:
56    """Seed the database without running the ASGI server."""
57    asyncio.run(seed_database())
58
59
60if __name__ == "__main__":
61    main()