ModPilot / store /connections.py
ThejasRao's picture
Deploy ModPilot Investigation Engine
7302343
Raw
History Blame Contribute Delete
2.14 kB
"""Postgres + Redis connection management.
Spec: docs/Specs.md §9, docs/13-Infra.md.
Used by the FastAPI lifespan hook to probe + bind connection pools at startup.
"""
from __future__ import annotations
from typing import TYPE_CHECKING
import redis.asyncio as aioredis
import structlog
from sqlalchemy import text
from sqlalchemy.ext.asyncio import AsyncEngine, create_async_engine
if TYPE_CHECKING:
from api.config import Settings
logger = structlog.get_logger(__name__)
async def open_postgres(settings: Settings) -> AsyncEngine:
"""Build the async engine and probe it. Raises if unreachable."""
engine = create_async_engine(
settings.database_url,
pool_size=5,
max_overflow=5,
pool_pre_ping=True,
future=True,
)
async with engine.connect() as conn:
result = await conn.execute(text("SELECT version()"))
version = result.scalar_one()
logger.info("db.connected", driver="asyncpg", server=str(version).split(" on ", maxsplit=1)[0])
return engine
async def close_postgres(engine: AsyncEngine) -> None:
await engine.dispose()
logger.info("db.disconnected")
async def open_redis(settings: Settings) -> aioredis.Redis[str]:
"""Build the redis client and probe it with PING. Raises if unreachable."""
client: aioredis.Redis[str] = aioredis.from_url(
settings.redis_url,
encoding="utf-8",
decode_responses=True,
max_connections=20,
)
pong = await client.ping()
logger.info("redis.connected", pong=pong, url=_redact(settings.redis_url))
return client
async def close_redis(client: aioredis.Redis[str]) -> None:
# `aclose` is the redis-py 5+ async-close method; older type stubs don't know it.
await client.aclose() # type: ignore[attr-defined]
logger.info("redis.disconnected")
def _redact(url: str) -> str:
"""Hide credentials in URLs when logging."""
if "@" in url:
scheme, rest = url.split("://", 1)
creds_and_host = rest.split("@", 1)
return f"{scheme}://***@{creds_and_host[1]}" if len(creds_and_host) == 2 else url
return url