""" Training routes for gateway """ from fastapi import APIRouter, Request, HTTPException, Query from fastapi.responses import JSONResponse import httpx import logging from typing import Optional from app.core.config import settings logger = logging.getLogger(__name__) router = APIRouter() @router.post("/train") async def start_training(request: Request): """Proxy training request to training service""" try: body = await request.body() auth_header = request.headers.get("Authorization") async with httpx.AsyncClient(timeout=30.0) as client: response = await client.post( f"{settings.TRAINING_SERVICE_URL}/train", content=body, headers={ "Content-Type": "application/json", "Authorization": auth_header } ) return JSONResponse( status_code=response.status_code, content=response.json() ) except httpx.RequestError as e: logger.error(f"Training service unavailable: {e}") raise HTTPException( status_code=503, detail="Training service unavailable" ) except Exception as e: logger.error(f"Training error: {e}") raise HTTPException(status_code=500, detail="Internal server error") @router.get("/status/{training_job_id}") async def get_training_status(training_job_id: str, request: Request): """Get training job status""" try: auth_header = request.headers.get("Authorization") async with httpx.AsyncClient(timeout=10.0) as client: response = await client.get( f"{settings.TRAINING_SERVICE_URL}/status/{training_job_id}", headers={"Authorization": auth_header} ) return JSONResponse( status_code=response.status_code, content=response.json() ) except httpx.RequestError as e: logger.error(f"Training service unavailable: {e}") raise HTTPException( status_code=503, detail="Training service unavailable" ) except Exception as e: logger.error(f"Training status error: {e}") raise HTTPException(status_code=500, detail="Internal server error") @router.get("/models") async def get_trained_models(request: Request): """Get trained models""" try: auth_header = request.headers.get("Authorization") async with httpx.AsyncClient(timeout=10.0) as client: response = await client.get( f"{settings.TRAINING_SERVICE_URL}/models", headers={"Authorization": auth_header} ) return JSONResponse( status_code=response.status_code, content=response.json() ) except httpx.RequestError as e: logger.error(f"Training service unavailable: {e}") raise HTTPException( status_code=503, detail="Training service unavailable" ) except Exception as e: logger.error(f"Get models error: {e}") raise HTTPException(status_code=500, detail="Internal server error") @router.get("/jobs") async def get_training_jobs( request: Request, limit: Optional[int] = Query(10, ge=1, le=100), offset: Optional[int] = Query(0, ge=0) ): """Get training jobs""" try: auth_header = request.headers.get("Authorization") async with httpx.AsyncClient(timeout=10.0) as client: response = await client.get( f"{settings.TRAINING_SERVICE_URL}/jobs", params={"limit": limit, "offset": offset}, headers={"Authorization": auth_header} ) return JSONResponse( status_code=response.status_code, content=response.json() ) except httpx.RequestError as e: logger.error(f"Training service unavailable: {e}") raise HTTPException( status_code=503, detail="Training service unavailable" ) except Exception as e: logger.error(f"Get training jobs error: {e}") raise HTTPException(status_code=500, detail="Internal server error") # gateway/Dockerfile FROM python:3.11-slim WORKDIR /app # Install system dependencies RUN apt-get update && apt-get install -y \ gcc \ curl \ && rm -rf /var/lib/apt/lists/* # Copy requirements COPY requirements.txt . # Install Python dependencies RUN pip install --no-cache-dir -r requirements.txt # Copy application code COPY . . # Add shared libraries to Python path ENV PYTHONPATH="/app:/app/shared:$PYTHONPATH" # Expose port EXPOSE 8000 # Health check HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \ CMD curl -f http://localhost:8000/health || exit 1 # Run application CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"]