import os import flet as ft import httpx import designer as ds from router import setup_router import theme_manager as tm from starlette.applications import Starlette from starlette.routing import Route, Mount from starlette.responses import Response as StarletteResponse _API_URL = os.getenv("API_URL", "http://api:8000") async def _radar_image(request): """Проксирует SVG-диаграмму с API — браузер скачивает с собственного хоста.""" response_id = request.path_params["response_id"] try: async with httpx.AsyncClient(timeout=10) as client: r = await client.get(f"{_API_URL}/responses/{response_id}/radar/image") if r.status_code == 200: return StarletteResponse( content=r.content, media_type="image/svg+xml", headers={"Content-Disposition": 'attachment; filename="diagram.svg"'}, ) except Exception: pass return StarletteResponse(status_code=404) async def main(page: ft.Page): page.title = "COPP" # Применяем сохранённые тему и масштаб до построения любых виджетов tm.apply_scale(page) tm.apply_theme(page) # Масштабирование глобального text_theme синхронно с ds.SCALE: # покрывает ft.Text() без явного size (body_medium по умолчанию = 14) _ts = lambda base: ft.TextStyle(size=ds.s(base)) page.theme = ft.Theme( text_theme=ft.TextTheme( body_large=_ts(16), body_medium=_ts(14), body_small=_ts(12), label_large=_ts(14), label_medium=_ts(12), label_small=_ts(11), title_large=_ts(22), title_medium=_ts(16), title_small=_ts(14), headline_medium=_ts(28), headline_small=_ts(24), display_small=_ts(36), ), ) setup_router(page) initial = page.route if page.route and page.route not in ("/", "") else "/login" await page.push_route(initial) _flet_app = ft.run(main, export_asgi_app=True, assets_dir="assets") app = Starlette( routes=[ Route("/radar-image/{response_id}", _radar_image), Mount("/", _flet_app), ] )