feat(auth): implement auth stack
This commit is contained in:
33
app/db.py
33
app/db.py
@@ -2,8 +2,10 @@
|
||||
|
||||
from collections.abc import AsyncGenerator
|
||||
from contextlib import asynccontextmanager
|
||||
from contextvars import ContextVar
|
||||
|
||||
import asyncpg
|
||||
from asyncpg.pool import PoolConnectionProxy
|
||||
import redis.asyncio as redis
|
||||
|
||||
|
||||
@@ -27,7 +29,7 @@ class Database:
|
||||
await self.pool.close()
|
||||
|
||||
@asynccontextmanager
|
||||
async def connection(self) -> AsyncGenerator[asyncpg.Connection, None]:
|
||||
async def connection(self) -> AsyncGenerator[asyncpg.Connection | PoolConnectionProxy, None]:
|
||||
"""Acquire a connection from the pool."""
|
||||
if not self.pool:
|
||||
raise RuntimeError("Database not connected")
|
||||
@@ -35,7 +37,7 @@ class Database:
|
||||
yield conn
|
||||
|
||||
@asynccontextmanager
|
||||
async def transaction(self) -> AsyncGenerator[asyncpg.Connection, None]:
|
||||
async def transaction(self) -> AsyncGenerator[asyncpg.Connection | PoolConnectionProxy, None]:
|
||||
"""Acquire a connection with an active transaction."""
|
||||
if not self.pool:
|
||||
raise RuntimeError("Database not connected")
|
||||
@@ -74,7 +76,26 @@ db = Database()
|
||||
redis_client = RedisClient()
|
||||
|
||||
|
||||
async def get_conn() -> AsyncGenerator[asyncpg.Connection, None]:
|
||||
"""Dependency for getting a database connection."""
|
||||
async with db.connection() as conn:
|
||||
yield conn
|
||||
_connection_ctx: ContextVar[asyncpg.Connection | PoolConnectionProxy | None] = ContextVar(
|
||||
"db_connection",
|
||||
default=None,
|
||||
)
|
||||
|
||||
|
||||
async def get_conn() -> AsyncGenerator[asyncpg.Connection | PoolConnectionProxy, None]:
|
||||
"""Dependency that reuses the same DB connection within a request context."""
|
||||
|
||||
existing_conn = _connection_ctx.get()
|
||||
if existing_conn is not None:
|
||||
yield existing_conn
|
||||
return
|
||||
|
||||
if not db.pool:
|
||||
raise RuntimeError("Database not connected")
|
||||
|
||||
async with db.pool.acquire() as conn:
|
||||
token = _connection_ctx.set(conn)
|
||||
try:
|
||||
yield conn
|
||||
finally:
|
||||
_connection_ctx.reset(token)
|
||||
|
||||
Reference in New Issue
Block a user