from fastapi import FastAPI, HTTPException, Request, Response from fastapi.middleware.cors import CORSMiddleware import uvicorn from datetime import datetime import httpx import os from typing import Any app = FastAPI( title="Console API Gateway", description="Central orchestrator for microservices", version="0.1.0" ) # Service URLs from environment USERS_SERVICE_URL = os.getenv("USERS_SERVICE_URL", "http://users-backend:8000") # CORS middleware app.add_middleware( CORSMiddleware, allow_origins=["*"], allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) @app.get("/") async def root(): return { "message": "Console API Gateway", "status": "running", "timestamp": datetime.now().isoformat() } @app.get("/health") async def health_check(): return { "status": "healthy", "service": "console", "timestamp": datetime.now().isoformat() } @app.get("/api/status") async def system_status(): services_status = {} # Check Users service try: async with httpx.AsyncClient() as client: response = await client.get(f"{USERS_SERVICE_URL}/health", timeout=2.0) services_status["users"] = "online" if response.status_code == 200 else "error" except: services_status["users"] = "offline" # Other services (not yet implemented) services_status["oauth"] = "pending" services_status["images"] = "pending" services_status["applications"] = "pending" services_status["data"] = "pending" services_status["statistics"] = "pending" return { "console": "online", "services": services_status, "timestamp": datetime.now().isoformat() } # API Gateway - Route to Users service @app.api_route("/api/users/{path:path}", methods=["GET", "POST", "PUT", "DELETE", "PATCH"]) async def proxy_to_users(path: str, request: Request): """Proxy requests to Users service""" try: async with httpx.AsyncClient() as client: # Build the target URL url = f"{USERS_SERVICE_URL}/{path}" # Get request body if exists body = None if request.method in ["POST", "PUT", "PATCH"]: body = await request.body() # Forward the request response = await client.request( method=request.method, url=url, headers={ key: value for key, value in request.headers.items() if key.lower() not in ["host", "content-length"] }, content=body, params=request.query_params ) # Return the response return Response( content=response.content, status_code=response.status_code, headers=dict(response.headers) ) except httpx.ConnectError: raise HTTPException(status_code=503, detail="Users service unavailable") except Exception as e: raise HTTPException(status_code=500, detail=str(e)) if __name__ == "__main__": uvicorn.run( "main:app", host="0.0.0.0", port=8000, reload=True )