You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
85 lines
3.0 KiB
Python
85 lines
3.0 KiB
Python
from fastapi import FastAPI, HTTPException, Request
|
|
from fastapi.middleware.cors import CORSMiddleware
|
|
from fastapi.responses import JSONResponse
|
|
import httpx
|
|
import os
|
|
import sys
|
|
import socketio
|
|
from pathlib import Path
|
|
|
|
# Add shared modules to path
|
|
sys.path.append(str(Path(__file__).parent.parent.parent.parent / "shared"))
|
|
|
|
from websocket.socket_manager import socket_manager
|
|
|
|
app = FastAPI(
|
|
title="Know Foolery API Gateway",
|
|
description="API Gateway for Know Foolery quiz game",
|
|
version="1.0.0"
|
|
)
|
|
|
|
# Create Socket.IO ASGI app
|
|
socket_app = socketio.ASGIApp(socket_manager.sio, app)
|
|
|
|
app.add_middleware(
|
|
CORSMiddleware,
|
|
allow_origins=["http://localhost:3000", "http://localhost:5173"],
|
|
allow_credentials=True,
|
|
allow_methods=["*"],
|
|
allow_headers=["*"],
|
|
)
|
|
|
|
SERVICES = {
|
|
"game": os.getenv("GAME_SERVICE_URL", "http://game-service:8001"),
|
|
"question": os.getenv("QUESTION_SERVICE_URL", "http://question-service:8002"),
|
|
"player": os.getenv("PLAYER_SERVICE_URL", "http://player-service:8003"),
|
|
"admin": os.getenv("ADMIN_SERVICE_URL", "http://admin-service:8004"),
|
|
}
|
|
|
|
|
|
async def forward_request(service: str, path: str, method: str, **kwargs):
|
|
if service not in SERVICES:
|
|
raise HTTPException(status_code=404, detail="Service not found")
|
|
|
|
service_url = f"{SERVICES[service]}{path}"
|
|
|
|
async with httpx.AsyncClient() as client:
|
|
response = await client.request(method, service_url, **kwargs)
|
|
return JSONResponse(
|
|
content=response.json() if response.headers.get("content-type", "").startswith("application/json") else response.text,
|
|
status_code=response.status_code
|
|
)
|
|
|
|
|
|
@app.get("/health")
|
|
async def health_check():
|
|
return {"status": "healthy", "service": "api-gateway"}
|
|
|
|
|
|
@app.api_route("/api/game/{path:path}", methods=["GET", "POST", "PUT", "DELETE"])
|
|
async def game_proxy(path: str, request: Request):
|
|
body = await request.body()
|
|
return await forward_request("game", f"/{path}", request.method, content=body, headers=dict(request.headers))
|
|
|
|
|
|
@app.api_route("/api/questions/{path:path}", methods=["GET", "POST", "PUT", "DELETE"])
|
|
async def question_proxy(path: str, request: Request):
|
|
body = await request.body()
|
|
return await forward_request("question", f"/{path}", request.method, content=body, headers=dict(request.headers))
|
|
|
|
|
|
@app.api_route("/api/players/{path:path}", methods=["GET", "POST", "PUT", "DELETE"])
|
|
async def player_proxy(path: str, request: Request):
|
|
body = await request.body()
|
|
return await forward_request("player", f"/{path}", request.method, content=body, headers=dict(request.headers))
|
|
|
|
|
|
@app.api_route("/api/admin/{path:path}", methods=["GET", "POST", "PUT", "DELETE"])
|
|
async def admin_proxy(path: str, request: Request):
|
|
body = await request.body()
|
|
return await forward_request("admin", f"/{path}", request.method, content=body, headers=dict(request.headers))
|
|
|
|
|
|
if __name__ == "__main__":
|
|
import uvicorn
|
|
uvicorn.run(app, host="0.0.0.0", port=8000) |