| """ |
| HuggingFace Space: API Gateway |
| Routes requests to appropriate services |
| """ |
| from fastapi import FastAPI, HTTPException |
| from pydantic import BaseModel |
| from typing import Optional, Dict, Any |
| import httpx |
| import os |
|
|
| app = FastAPI( |
| title="API Gateway Space", |
| description="Routes requests to other spaces" |
| ) |
|
|
| |
| SERVICES = { |
| "code_exec": os.getenv("CODE_EXEC_URL", ""), |
| "search": os.getenv("SEARCH_URL", ""), |
| "llm": os.getenv("LLM_URL", "") |
| } |
|
|
|
|
| class RouteRequest(BaseModel): |
| service: str |
| endpoint: str = "/api" |
| data: Dict[str, Any] = {} |
| timeout: int = 30 |
|
|
|
|
| class RouteResponse(BaseModel): |
| service: str |
| response: Any |
| error: Optional[str] = None |
|
|
|
|
| @app.get("/") |
| async def root(): |
| return { |
| "status": "running", |
| "services": {k: bool(v) for k, v in SERVICES.items()} |
| } |
|
|
|
|
| @app.get("/health") |
| async def health(): |
| """Check health of all services""" |
| health_status = {} |
| |
| async with httpx.AsyncClient(timeout=5.0) as client: |
| for name, url in SERVICES.items(): |
| if not url: |
| health_status[name] = {"status": "not_configured"} |
| continue |
| |
| try: |
| response = await client.get(f"{url}/") |
| health_status[name] = { |
| "status": "healthy" if response.status_code == 200 else "unhealthy", |
| "code": response.status_code |
| } |
| except Exception as e: |
| health_status[name] = {"status": "unreachable", "error": str(e)} |
| |
| return health_status |
|
|
|
|
| @app.post("/route", response_model=RouteResponse) |
| async def route(request: RouteRequest): |
| """Route a request to a service""" |
| |
| if request.service not in SERVICES: |
| raise HTTPException(404, f"Service '{request.service}' not found") |
| |
| url = SERVICES[request.service] |
| if not url: |
| raise HTTPException(503, f"Service '{request.service}' not configured") |
| |
| try: |
| async with httpx.AsyncClient(timeout=request.timeout) as client: |
| response = await client.post( |
| f"{url}{request.endpoint}", |
| json=request.data |
| ) |
| |
| if response.status_code == 200: |
| return RouteResponse( |
| service=request.service, |
| response=response.json() |
| ) |
| else: |
| return RouteResponse( |
| service=request.service, |
| response=None, |
| error=f"Service returned {response.status_code}" |
| ) |
| |
| except httpx.TimeoutException: |
| return RouteResponse( |
| service=request.service, |
| response=None, |
| error="Request timeout" |
| ) |
| except Exception as e: |
| return RouteResponse( |
| service=request.service, |
| response=None, |
| error=str(e) |
| ) |
|
|
|
|
| |
| @app.post("/execute") |
| async def execute_code(code: str): |
| """Shortcut to code execution""" |
| return await route(RouteRequest( |
| service="code_exec", |
| endpoint="/api/execute", |
| data={"code": code} |
| )) |
|
|
|
|
| @app.post("/search") |
| async def search(query: str, max_results: int = 5): |
| """Shortcut to web search""" |
| return await route(RouteRequest( |
| service="search", |
| endpoint="/api/search", |
| data={"query": query, "max_results": max_results} |
| )) |
|
|
|
|
| @app.post("/generate") |
| async def generate(prompt: str, max_tokens: int = 200): |
| """Shortcut to LLM generation""" |
| return await route(RouteRequest( |
| service="llm", |
| endpoint="/api/generate", |
| data={"prompt": prompt, "max_tokens": max_tokens} |
| )) |
|
|
|
|
| |
| def gradio_interface(): |
| import gradio as gr |
| |
| async def unified_interface(service, input_text): |
| if service == "code": |
| response = await execute_code(input_text) |
| elif service == "search": |
| response = await search(input_text) |
| else: |
| response = await generate(input_text) |
| |
| if response.error: |
| return f"Error: {response.error}" |
| return str(response.response) |
| |
| iface = gr.Interface( |
| fn=unified_interface, |
| inputs=[ |
| gr.Dropdown(["code", "search", "llm"], label="Service"), |
| gr.Textbox(lines=5, label="Input") |
| ], |
| outputs=gr.Textbox(lines=10, label="Output"), |
| title="API Gateway", |
| description="Unified interface to all services" |
| ) |
| |
| return iface |
|
|
|
|
| if __name__ == "__main__": |
| import uvicorn |
| uvicorn.run(app, host="0.0.0.0", port=7860) |
|
|