gateway / app.py
ndwdgda's picture
Upload folder using huggingface_hub
a501d19 verified
"""
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"
)
# Service URLs from environment
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)
)
# Convenience endpoints
@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}
))
# Gradio interface
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)