46 lines
1.4 KiB
Python
46 lines
1.4 KiB
Python
"""FastAPI dependencies."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from typing import TYPE_CHECKING, Annotated
|
|
|
|
from fastapi import Depends, Request
|
|
from sqlalchemy.engine import Engine
|
|
from sqlalchemy.ext.asyncio import AsyncEngine, AsyncSession
|
|
from sqlalchemy.orm import Session
|
|
|
|
if TYPE_CHECKING:
|
|
from collections.abc import AsyncIterator, Iterator
|
|
|
|
|
|
def get_engine(request: Request) -> Engine:
|
|
"""Get a synchronous database engine from app state."""
|
|
return request.app.state.engine
|
|
|
|
|
|
def get_async_engine(request: Request) -> AsyncEngine:
|
|
"""Get an asynchronous database engine from app state."""
|
|
return request.app.state.engine
|
|
|
|
|
|
def get_db(request: Request) -> Iterator[Session]:
|
|
"""Get database session from app state."""
|
|
with Session(request.app.state.engine) as session:
|
|
yield session
|
|
|
|
|
|
async def get_async_db(request: Request) -> AsyncIterator[AsyncSession]:
|
|
"""Get an async database session from app state.
|
|
|
|
expire_on_commit=False keeps ORM attributes readable after commit without
|
|
triggering implicit IO, which would raise under asyncio.
|
|
"""
|
|
async with AsyncSession(request.app.state.engine, expire_on_commit=False) as session:
|
|
yield session
|
|
|
|
|
|
AppEngine = Annotated[Engine, Depends(get_engine)]
|
|
AppAsyncEngine = Annotated[AsyncEngine, Depends(get_async_engine)]
|
|
DbSession = Annotated[Session, Depends(get_db)]
|
|
AsyncDbSession = Annotated[AsyncSession, Depends(get_async_db)]
|