Spaces:
Paused
Paused
| from __future__ import annotations | |
| import html | |
| import json | |
| import os | |
| from pathlib import Path | |
| from typing import Any, Dict, List | |
| from fastapi import FastAPI, HTTPException | |
| from fastapi.responses import HTMLResponse, JSONResponse, PlainTextResponse | |
| from fastapi.staticfiles import StaticFiles | |
| from pygments import highlight | |
| from pygments.formatters import HtmlFormatter | |
| from pygments.lexers import PythonLexer | |
| from runtime import MarketRuntime, ensure_repo_engine_path | |
| ROOT = Path(__file__).resolve().parent | |
| FRONTEND = ROOT / "frontend" | |
| SOURCE_PATH = ensure_repo_engine_path() | |
| app = FastAPI(title="MAYTHOS Live Space", version="1.0.0") | |
| app.mount("/static", StaticFiles(directory=str(FRONTEND)), name="static") | |
| runtime = MarketRuntime( | |
| default_symbol=os.getenv("SYMBOL_DEFAULT", "frxEURUSD"), | |
| base_timeframe=int(os.getenv("BASE_TIMEFRAME", "30")), | |
| debug_mode=True, | |
| ) | |
| _SOURCE_RAW = SOURCE_PATH.read_text(encoding="utf-8") | |
| _SOURCE_LINE_COUNT = len(_SOURCE_RAW.splitlines()) | |
| _SOURCE_HTML = None | |
| def _render_source_html(source: str) -> str: | |
| lexer = PythonLexer() | |
| formatter = HtmlFormatter(nowrap=True) | |
| lines = [] | |
| for idx, line in enumerate(source.splitlines(), start=1): | |
| display = line if line.strip() else " " | |
| hl = highlight(display, lexer, formatter).rstrip("\n") | |
| data_text = html.escape(line) | |
| lines.append( | |
| f'<div class="code-line" data-line="{idx}" data-text="{data_text}">' | |
| f'<span class="ln">{idx}</span>' | |
| f'<span class="code">{hl or " "}</span>' | |
| f"</div>" | |
| ) | |
| return "\n".join(lines) | |
| _SOURCE_HTML = _render_source_html(_SOURCE_RAW) | |
| async def _startup() -> None: | |
| await runtime.start() | |
| async def _shutdown() -> None: | |
| await runtime.stop() | |
| async def index() -> HTMLResponse: | |
| html_path = FRONTEND / "index.html" | |
| if html_path.exists(): | |
| return HTMLResponse(html_path.read_text(encoding="utf-8")) | |
| raise HTTPException(404, "frontend/index.html missing") | |
| async def api_state() -> JSONResponse: | |
| return JSONResponse(await runtime.snapshot()) | |
| async def api_health() -> JSONResponse: | |
| return JSONResponse(await runtime.health()) | |
| async def health_plain() -> PlainTextResponse: | |
| data = await runtime.health() | |
| if data["ok"]: | |
| return PlainTextResponse("OK") | |
| return PlainTextResponse("ERROR", status_code=503) | |
| async def api_source() -> JSONResponse: | |
| return JSONResponse({"source": _SOURCE_RAW, "line_count": _SOURCE_LINE_COUNT}) | |
| async def api_source_html() -> HTMLResponse: | |
| return HTMLResponse(_SOURCE_HTML) | |
| async def api_symbols() -> JSONResponse: | |
| return JSONResponse( | |
| { | |
| "symbols": runtime.symbol_options(), | |
| "selected": runtime.selected_symbol, | |
| "market_type": runtime.market_type, | |
| } | |
| ) | |
| async def api_set_symbol(symbol: str) -> JSONResponse: | |
| await runtime.set_symbol(symbol) | |
| return JSONResponse({"ok": True, "symbol": runtime.selected_symbol, "market_type": runtime.market_type}) | |
| async def api_set_tf(tf_seconds: int) -> JSONResponse: | |
| await runtime.set_display_timeframe(tf_seconds) | |
| return JSONResponse({"ok": True, "display_timeframe": tf_seconds}) | |
| async def api_source_meta() -> JSONResponse: | |
| return JSONResponse({ | |
| "path": str(SOURCE_PATH), | |
| "line_count": _SOURCE_LINE_COUNT, | |
| }) | |