""" HugPanel — Multi-zone workspace for HuggingFace Spaces. Open/Closed Principle: routers are auto-discovered from the routers/ package. Adding a new feature = adding a new file in routers/ — no changes here. """ from contextlib import asynccontextmanager import uvicorn from fastapi import FastAPI from fastapi.staticfiles import StaticFiles from fastapi.responses import FileResponse from routers import discover_routers from routers.terminal import active_terminals, kill_terminal @asynccontextmanager async def lifespan(app: FastAPI): yield for zone_name in list(active_terminals.keys()): kill_terminal(zone_name) app = FastAPI(title="HugPanel", lifespan=lifespan) # Auto-register all routers (Open/Closed — new router files are picked up automatically) for router in discover_routers(): app.include_router(router) # ── Static Files & SPA ────────────────────────────────── app.mount("/static", StaticFiles(directory="static"), name="static") @app.get("/") def index(): return FileResponse("static/index.html") if __name__ == "__main__": uvicorn.run(app, host="0.0.0.0", port=7860)