from core_domain import ChatCompletionRequestContract, ChatCompletionResponseContract, ServiceHealth from fastapi import APIRouter, Depends, HTTPException from sqlalchemy import text from sqlalchemy.orm import Session from app.application.services import ModelGatewayApplicationService from app.bootstrap.settings import ModelGatewayServiceSettings from app.db.session import get_db from app.domain.repositories import ModelDefinitionRepository from app.infrastructure.provider import ModelProviderClient, ModelProviderClientError from app.schemas.model import ( ModelCreateRequest, ModelResponse, ModelStatusUpdateRequest, ModelTestRequest, ModelTestResponse, ModelUpdateRequest, ) router = APIRouter() def get_model_gateway_settings() -> ModelGatewayServiceSettings: return ModelGatewayServiceSettings() def get_model_gateway_application_service( db: Session = Depends(get_db), settings: ModelGatewayServiceSettings = Depends(get_model_gateway_settings)) -> ModelGatewayApplicationService: return ModelGatewayApplicationService( model_repository=ModelDefinitionRepository(db), provider_client=ModelProviderClient(settings=settings), settings=settings) @router.get("/health", response_model=ServiceHealth) def health_check( db: Session = Depends(get_db), settings: ModelGatewayServiceSettings = Depends(get_model_gateway_settings)) -> ServiceHealth: db.execute(text("SELECT 1")) provider_status = "configured" if settings.provider_base_url else "missing" return ServiceHealth(service="model-gateway-service", status="ok", database=provider_status) @router.post("", response_model=ModelResponse) def create_model( payload: ModelCreateRequest, service: ModelGatewayApplicationService = Depends(get_model_gateway_application_service), ) -> ModelResponse: try: entity = service.create_model(payload) except ValueError as exc: raise HTTPException(status_code=422, detail=str(exc)) from exc return ModelResponse.from_entity(entity) @router.get("", response_model=list[ModelResponse]) def list_models( service: ModelGatewayApplicationService = Depends(get_model_gateway_application_service), ) -> list[ModelResponse]: return [ModelResponse.from_entity(item) for item in service.list_models()] @router.patch("/{model_id}", response_model=ModelResponse) def update_model( model_id: str, payload: ModelUpdateRequest, service: ModelGatewayApplicationService = Depends(get_model_gateway_application_service), ) -> ModelResponse: try: entity = service.update_model(model_id=model_id, payload=payload) except ValueError as exc: raise HTTPException(status_code=422, detail=str(exc)) from exc if entity is None: raise HTTPException(status_code=404, detail=f"model not found: {model_id}") return ModelResponse.from_entity(entity) @router.patch("/{model_id}/status", response_model=ModelResponse) def update_model_status( model_id: str, payload: ModelStatusUpdateRequest, service: ModelGatewayApplicationService = Depends(get_model_gateway_application_service), ) -> ModelResponse: entity = service.update_model_status(model_id=model_id, payload=payload) if entity is None: raise HTTPException(status_code=404, detail=f"model not found: {model_id}") return ModelResponse.from_entity(entity) @router.delete("/{model_id}", status_code=204) def delete_model( model_id: str, service: ModelGatewayApplicationService = Depends(get_model_gateway_application_service), ) -> None: if not service.delete_model(model_id): raise HTTPException(status_code=404, detail=f"model not found: {model_id}") @router.post("/{model_id}/test", response_model=ModelTestResponse) def test_model( model_id: str, payload: ModelTestRequest, service: ModelGatewayApplicationService = Depends(get_model_gateway_application_service), ) -> ModelTestResponse: try: result = service.test_model(model_id=model_id, payload=payload) except ModelProviderClientError as exc: raise HTTPException(status_code=502, detail=str(exc)) from exc if result is None: raise HTTPException(status_code=404, detail=f"model not found: {model_id}") return result @router.post("/chat-completions", response_model=ChatCompletionResponseContract) def create_chat_completion( payload: ChatCompletionRequestContract, service: ModelGatewayApplicationService = Depends(get_model_gateway_application_service)) -> ChatCompletionResponseContract: try: return service.create_chat_completion(payload) except ModelProviderClientError as exc: raise HTTPException(status_code=502, detail=str(exc)) from exc