| 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) |
|
|