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