Spaces:
Sleeping
Sleeping
File size: 2,070 Bytes
6078ec2 dccc925 6078ec2 3739378 70b69aa dccc925 a43aaf6 70b69aa 3739378 70b69aa 3739378 70b69aa 3739378 00dd25e 3739378 70b69aa 3739378 70b69aa 9088c1f dccc925 3739378 dccc925 a43aaf6 dccc925 9088c1f dccc925 3739378 |
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 |
"""
Main entry point for Rubric AI.
Runs both FastAPI backend and NiceGUI frontend on a single Uvicorn process.
Designed for deployment on Hugging Face Spaces (port 7860).
"""
import re
from starlette.middleware.base import BaseHTTPMiddleware
from backend.app import create_app
from backend.core.config import settings
from frontend.ui import init_frontend
from nicegui import ui
# Create FastAPI application
app = create_app()
# Import API routes (registers @app decorators)
import frontend.api_routes # noqa: F401
# Middleware to allow iframe embedding on HF Spaces
class AllowIframeMiddleware(BaseHTTPMiddleware):
async def dispatch(self, request, call_next):
response = await call_next(request)
# Remove X-Frame-Options to allow HF Spaces iframe embedding
if "x-frame-options" in response.headers:
del response.headers["x-frame-options"]
# Remove or modify Content-Security-Policy frame-ancestors directive
if "content-security-policy" in response.headers:
csp = response.headers["content-security-policy"]
# Remove frame-ancestors directive entirely to allow any iframe embedding
csp = re.sub(r"frame-ancestors\s+[^;]+;?\s*", "", csp)
if csp.strip():
response.headers["content-security-policy"] = csp
else:
del response.headers["content-security-policy"]
return response
app.add_middleware(AllowIframeMiddleware)
# Initialize NiceGUI frontend routes BEFORE mounting
init_frontend()
# Mount NiceGUI onto FastAPI (modifies app in place)
# This must happen at module level so Uvicorn can import 'main:app'
ui.run_with(
app,
title="Rubric AI",
favicon="favicon.png",
storage_secret=settings.SUPABASE_ANON_KEY or "rubric-ai-secret",
mount_path="/",
reconnect_timeout=10, # Handle HF Spaces proxy timeouts
)
if __name__ == "__main__":
import uvicorn
uvicorn.run(
"main:app",
host=settings.HOST,
port=settings.PORT,
reload=True,
)
|