from pathlib import Path import os import sys ROOT = Path(__file__).resolve().parent ROOT_ENV = ROOT / ".env" LOCAL_ENV = ROOT / "data" / "local.env" SRC = ROOT / "src" if str(SRC) not in sys.path: sys.path.insert(0, str(SRC)) def _load_local_env(path: Path, *, override: bool = False) -> None: if not path.exists(): return for raw_line in path.read_text(encoding="utf-8").splitlines(): line = raw_line.strip() if not line or line.startswith("#") or "=" not in line: continue key, value = line.split("=", 1) key = key.strip() value = value.strip().strip('"').strip("'") if key and (override or key not in os.environ): os.environ[key] = value _load_local_env(ROOT_ENV, override=False) _load_local_env(LOCAL_ENV, override=False) from time_machine.application.container import create_container from time_machine.ui.gradio_app import create_app from time_machine.ui.realtime import realtime_voice_socket import gradio as gr from fastapi import FastAPI, WebSocket from fastapi.responses import JSONResponse, RedirectResponse, Response from fastapi.staticfiles import StaticFiles gr.set_static_paths([ROOT / "static"]) container = create_container() demo = create_app(container) fastapi_app = FastAPI(title="AI Time Machine") fastapi_app.mount("/static", StaticFiles(directory=ROOT / "static"), name="static") @fastapi_app.websocket("/realtime/voice") async def websocket_realtime_voice(websocket: WebSocket): await realtime_voice_socket(websocket, container) @fastapi_app.get("/manifest.json") async def manifest(): return JSONResponse( { "name": "AI Time Machine", "short_name": "AI Time Machine", "start_url": "/", "display": "standalone", "background_color": "#0b1117", "theme_color": "#0b1117", } ) @fastapi_app.get("/favicon.ico") async def favicon(): return Response(status_code=204) @fastapi_app.get("/blank") @fastapi_app.get("/blank/") @fastapi_app.get("/app") @fastapi_app.get("/app/") async def blank_redirect(): return RedirectResponse(url="/") runtime_js = getattr(demo, "time_machine_js", None) fastapi_app_with_gradio = gr.mount_gradio_app(fastapi_app, demo, path="/app", js=runtime_js) app = fastapi_app_with_gradio if os.getenv("TIME_MACHINE_FASTAPI_WRAPPER") else demo if __name__ == "__main__": import uvicorn host = os.getenv("GRADIO_SERVER_NAME", "0.0.0.0") port = int(os.getenv("GRADIO_SERVER_PORT", "7860")) if os.getenv("TIME_MACHINE_FASTAPI_WRAPPER"): uvicorn.run(fastapi_app_with_gradio, host=host, port=port) else: demo.launch(server_name=host, server_port=port, js=runtime_js)