paper-dynasty-gameplay-webapp/app/services/service_container.py
Cal Corum 1c24161e76 CLAUDE: Achieve 100% test pass rate with comprehensive AI service testing
- Fix TypeError in check_steal_opportunity by properly mocking catcher defense
- Correct tag_from_third test calculation to account for all adjustment conditions
- Fix pitcher replacement test by setting appropriate allowed runners threshold
- Add comprehensive test coverage for AI service business logic
- Implement VS Code testing panel configuration with pytest integration
- Create pytest.ini for consistent test execution and warning management
- Add test isolation guidelines and factory pattern implementation
- Establish 102 passing tests with zero failures

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-28 17:55:34 -05:00

97 lines
2.7 KiB
Python

"""
Dependency injection container for services.
Manages service lifecycles and dependencies using FastAPI's dependency injection.
"""
import logging
from functools import lru_cache
from typing import Annotated
from fastapi import Depends
from sqlmodel import Session, SQLModel, create_engine
from sqlalchemy.pool import StaticPool
from app.config.constants import settings
logger = logging.getLogger(f'{__name__}.service_container')
# Database setup
engine = create_engine(
settings.DATABASE_URL,
echo=settings.DEBUG,
poolclass=StaticPool if "sqlite" in settings.DATABASE_URL else None,
connect_args={"check_same_thread": False} if "sqlite" in settings.DATABASE_URL else {}
)
def create_db_and_tables():
"""Create database tables."""
SQLModel.metadata.create_all(engine)
def get_session() -> Session:
"""
Dependency to get database session.
Each request gets its own session that's automatically closed.
"""
with Session(engine) as session:
try:
yield session
except Exception as e:
logger.error(f"Database session error: {str(e)}")
session.rollback()
raise
finally:
session.close()
# Type aliases for dependency injection
SessionDep = Annotated[Session, Depends(get_session)]
# Service dependencies - these will be implemented as services are created
def get_game_service(session: SessionDep):
"""Get GameService instance."""
from app.services.game_service import GameService
return GameService(session)
def get_user_service(session: SessionDep):
"""Get UserService instance."""
from app.services.user_service import UserService
return UserService(session)
def get_auth_service(session: SessionDep):
"""Get AuthService instance."""
from app.services.auth_service import AuthService
return AuthService(session)
def get_gameplay_service(session: SessionDep):
"""Get GameplayService instance."""
from app.services.gameplay_service import GameplayService
return GameplayService(session)
def get_ai_service(session: SessionDep):
"""Get AIService instance."""
from app.services.ai_service import AIService
return AIService(session)
def get_ui_service(session: SessionDep):
"""Get UIService instance."""
from app.services.ui_service import UIService
return UIService(session)
# Type aliases for service dependencies
GameServiceDep = Annotated[object, Depends(get_game_service)]
UserServiceDep = Annotated[object, Depends(get_user_service)]
AuthServiceDep = Annotated[object, Depends(get_auth_service)]
GameplayServiceDep = Annotated[object, Depends(get_gameplay_service)]
AIServiceDep = Annotated[object, Depends(get_ai_service)]
UIServiceDep = Annotated[object, Depends(get_ui_service)]