From 4c59f129db6341afb135a3aa9b3683774b90d202 Mon Sep 17 00:00:00 2001 From: "2569718930@qq.com" <2569718930@qq.com> Date: Sun, 8 Mar 2026 04:35:04 +0800 Subject: [PATCH] release: stable professional quant UI v1.0 and backend stabilization --- README.md | 8 +++++++- frontend/.env.local | 1 + web/app.py | 50 +++++++++++++++++++++++++++------------------ 3 files changed, 38 insertions(+), 21 deletions(-) create mode 100644 frontend/.env.local diff --git a/README.md b/README.md index f70bea59..10ca2e73 100644 --- a/README.md +++ b/README.md @@ -138,4 +138,10 @@ Associate the `frontend` directory as the project root on Vercel for automatic C --- -**📅 Last Updated**: 2026-03-06 +--- + +**📅 Last Updated**: 2026-03-08 +**🚀 Status**: v1.0 Stable - Professional Quant UI Locked + +> [!TIP] +> **Production Note**: The current dashboard utilizes the high-density "Professional Quant" UI (v1.0-legacy) which integrates real-time METAR/MGM data, DEB ensemble blending, and multi-model probability distribution in a single high-performance view. diff --git a/frontend/.env.local b/frontend/.env.local new file mode 100644 index 00000000..c049a0d8 --- /dev/null +++ b/frontend/.env.local @@ -0,0 +1 @@ +POLYWEATHER_API_BASE_URL=http://127.0.0.1:8000 diff --git a/web/app.py b/web/app.py index 3ca42847..d75bb73a 100644 --- a/web/app.py +++ b/web/app.py @@ -1,4 +1,4 @@ -""" +""" PolyWeather Web Map API ~~~~~~~~~~~~~~~~~~~~~~~ FastAPI backend that reuses existing weather data collection and analysis modules. @@ -13,9 +13,13 @@ from datetime import datetime, timezone, timedelta from typing import Dict, Any, Optional # Project root setup -_root = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) +_file_dir = os.path.dirname(os.path.abspath(__file__)) +_root = os.path.dirname(_file_dir) if _root not in sys.path: sys.path.insert(0, _root) +# Ensure current dir is also in path for local imports if any +if _file_dir not in sys.path: + sys.path.insert(0, _file_dir) from fastapi import FastAPI, HTTPException from fastapi.middleware.cors import CORSMiddleware @@ -539,24 +543,30 @@ def _analyze(city: str, force_refresh: bool = False) -> Dict[str, Any]: @app.get("/api/cities") async def list_cities(): """Return all supported cities with coordinates and risk level.""" - out = [] - for name, info in CITIES.items(): - risk = CITY_RISK_PROFILES.get(name, {}) - out.append( - { - "name": name, - "display_name": name.title(), - "lat": info["lat"], - "lon": info["lon"], - "risk_level": risk.get("risk_level", "low"), - "risk_emoji": risk.get("risk_emoji", "🟢"), - "airport": risk.get("airport_name", ""), - "icao": risk.get("icao", ""), - "temp_unit": "fahrenheit" if info["f"] else "celsius", - "is_major": CITY_REGISTRY.get(name, {}).get("is_major", True), - } - ) - return {"cities": out} + try: + out = [] + for name, info in CITIES.items(): + risk = CITY_RISK_PROFILES.get(name, {}) + out.append( + { + "name": name, + "display_name": name.title(), + "lat": info["lat"], + "lon": info["lon"], + "risk_level": risk.get("risk_level", "low"), + "risk_emoji": risk.get("risk_emoji", "🟢"), + "airport": risk.get("airport_name", ""), + "icao": risk.get("icao", ""), + "temp_unit": "fahrenheit" if info["f"] else "celsius", + "is_major": CITY_REGISTRY.get(name, {}).get("is_major", True), + } + ) + return {"cities": out} + except Exception as e: + logger.error(f"❌ Error in list_cities: {str(e)}") + import traceback + logger.error(traceback.format_exc()) + raise HTTPException(status_code=500, detail=str(e)) @app.get("/api/city/{name}")