Phase 3 (Part 1): API Infrastructure - FastAPI, Database, Redis, gRPC Client

Completed Tasks (T027-T032):
-  FastAPI application with structured logging, CORS, global error handlers
-  Pydantic Settings for environment configuration
-  SQLAlchemy async engine with session management
-  Alembic migration environment setup
-  Redis async client with connection pooling
-  gRPC SDK Bridge client (placeholder - awaiting protobuf generation)

Next: JWT utilities, middleware, database models

🤖 Generated with Claude Code
This commit is contained in:
Geutebruck API Developer
2025-12-09 08:49:08 +01:00
parent 48fafae9d2
commit 12c4e1ca9c
6 changed files with 724 additions and 0 deletions

View File

@@ -0,0 +1,69 @@
"""
SQLAlchemy database setup with async support
"""
from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession, async_sessionmaker
from sqlalchemy.orm import DeclarativeBase
from config import settings
import structlog
logger = structlog.get_logger()
# Create async engine
engine = create_async_engine(
settings.DATABASE_URL,
echo=settings.ENVIRONMENT == "development",
pool_size=settings.DATABASE_POOL_SIZE,
max_overflow=settings.DATABASE_MAX_OVERFLOW,
pool_pre_ping=True, # Verify connections before using
)
# Create async session factory
AsyncSessionLocal = async_sessionmaker(
engine,
class_=AsyncSession,
expire_on_commit=False,
)
# Base class for models
class Base(DeclarativeBase):
"""Base class for all database models"""
pass
# Dependency for FastAPI routes
async def get_db() -> AsyncSession:
"""
Dependency that provides database session to FastAPI routes
Usage: db: AsyncSession = Depends(get_db)
"""
async with AsyncSessionLocal() as session:
try:
yield session
await session.commit()
except Exception:
await session.rollback()
raise
finally:
await session.close()
# Database initialization
async def init_db():
"""Initialize database connection (call on startup)"""
try:
logger.info("database_init", url=settings.DATABASE_URL.split("@")[-1]) # Hide credentials
async with engine.begin() as conn:
# Test connection
await conn.run_sync(lambda _: None)
logger.info("database_connected")
except Exception as e:
logger.error("database_connection_failed", error=str(e))
raise
async def close_db():
"""Close database connections (call on shutdown)"""
try:
logger.info("database_closing")
await engine.dispose()
logger.info("database_closed")
except Exception as e:
logger.error("database_close_failed", error=str(e))
raise