Spaces:
Sleeping
Sleeping
File size: 2,836 Bytes
8ab334f | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 | # HF Spaces requires all traffic through port 7860
# This proxy routes:
# /chat/* → Agent Zero (port 80)
# /sandbox/* → Marimo (port 8080)
# /api/* → OmniRoute (port 20128)
from fastapi import FastAPI, Request, HTTPException
from fastapi.responses import HTMLResponse, StreamingResponse
from fastapi.staticfiles import StaticFiles
import httpx
import asyncio
app = FastAPI()
# Service ports (internal)
AGENT_ZERO_PORT = 80
MARIMO_PORT = 8080
OMNIROUTE_PORT = 20128
HF_PORT = 7860
# HTTP client with connection pooling
http_client = httpx.AsyncClient(timeout=60.0)
@app.get("/health")
async def health():
"""HF Spaces healthcheck endpoint"""
return {"status": "healthy", "service": "marimo-zero"}
@app.get("/")
async def root():
"""Serve main UI"""
try:
with open("/app/static/index.html", "r") as f:
return HTMLResponse(content=f.read())
except FileNotFoundError:
return HTMLResponse("<h1>Marimo Zero</h1><p>UI not found</p>", status_code=404)
@app.api_route("/chat/{path:path}", methods=["GET", "POST", "PUT", "DELETE"])
async def proxy_agent_zero(request: Request, path: str):
"""Proxy to Agent Zero"""
return await proxy_request(AGENT_ZERO_PORT, path, request)
@app.api_route("/sandbox/{path:path}", methods=["GET", "POST", "PUT", "DELETE"])
async def proxy_marimo(request: Request, path: str):
"""Proxy to Marimo"""
return await proxy_request(MARIMO_PORT, path, request)
@app.api_route("/api/{path:path}", methods=["GET", "POST", "PUT", "DELETE"])
async def proxy_omniroute(request: Request, path: str):
"""Proxy to OmniRoute"""
return await proxy_request(OMNIROUTE_PORT, path, request)
async def proxy_request(target_port: int, path: str, request: Request):
"""Generic proxy handler"""
url = f"http://localhost:{target_port}/{path}"
try:
# Forward headers
headers = dict(request.headers)
headers.pop("host", None)
headers.pop("content-length", None)
# Get body
body = await request.body() if request.method in ["POST", "PUT"] else None
# Make request
response = await http_client.request(
method=request.method,
url=url,
headers=headers,
content=body
)
# Return response
return StreamingResponse(
response.aiter_bytes(),
status_code=response.status_code,
headers=dict(response.headers)
)
except httpx.ConnectError as e:
raise HTTPException(status_code=503, detail=f"Service unavailable (port {target_port})")
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host="0.0.0.0", port=HF_PORT)
|