Spaces:
Running on Zero
Running on Zero
Upload 2 files
Browse files- app.py +5 -9
- trace_sync.py +47 -0
app.py
CHANGED
|
@@ -26,9 +26,14 @@ import geo
|
|
| 26 |
import globe as globe_mod
|
| 27 |
import liquid
|
| 28 |
import sidebar as sidebar_mod
|
|
|
|
| 29 |
import transit_agent
|
| 30 |
import transit_map
|
| 31 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 32 |
# ---- Preset regions (north, south, west, east) -----------------------------
|
| 33 |
REGIONS = {
|
| 34 |
"Europe": (60.0, 36.0, -11.0, 30.0),
|
|
@@ -44,15 +49,6 @@ REGIONS = {
|
|
| 44 |
MAX_FLIGHTS = 220 # keep the globe/LLM responsive
|
| 45 |
|
| 46 |
|
| 47 |
-
def ensure_trace_directory():
|
| 48 |
-
"""Creates the traces directory at runtime to ensure the agent can save output."""
|
| 49 |
-
base_dir = os.path.dirname(os.path.abspath(__file__))
|
| 50 |
-
trace_dir = os.path.join(base_dir, "traces")
|
| 51 |
-
os.makedirs(trace_dir, exist_ok=True)
|
| 52 |
-
return trace_dir
|
| 53 |
-
|
| 54 |
-
ensure_trace_directory()
|
| 55 |
-
|
| 56 |
def normalize_flight(raw: dict) -> dict | None:
|
| 57 |
"""Map an FR24 record to the fields the rest of the app expects."""
|
| 58 |
lat = raw.get("lat")
|
|
|
|
| 26 |
import globe as globe_mod
|
| 27 |
import liquid
|
| 28 |
import sidebar as sidebar_mod
|
| 29 |
+
import trace_sync
|
| 30 |
import transit_agent
|
| 31 |
import transit_map
|
| 32 |
|
| 33 |
+
# Mirror ./traces/ to a HF dataset repo (no-op without HF_TOKEN); the container
|
| 34 |
+
# disk on Spaces is ephemeral, so this is what makes traces survive restarts.
|
| 35 |
+
print(f"[flightdeck] {trace_sync.start()}")
|
| 36 |
+
|
| 37 |
# ---- Preset regions (north, south, west, east) -----------------------------
|
| 38 |
REGIONS = {
|
| 39 |
"Europe": (60.0, 36.0, -11.0, 30.0),
|
|
|
|
| 49 |
MAX_FLIGHTS = 220 # keep the globe/LLM responsive
|
| 50 |
|
| 51 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 52 |
def normalize_flight(raw: dict) -> dict | None:
|
| 53 |
"""Map an FR24 record to the fields the rest of the app expects."""
|
| 54 |
lat = raw.get("lat")
|
trace_sync.py
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Persist agent traces to a Hugging Face dataset repo.
|
| 2 |
+
|
| 3 |
+
On Spaces the container filesystem is ephemeral: traces written to ./traces/
|
| 4 |
+
survive only until the Space restarts, and never show up in the repo Files tab.
|
| 5 |
+
This module starts a `CommitScheduler` that periodically commits new/changed
|
| 6 |
+
files from ./traces/ to a dataset repo, so every agent run stays auditable.
|
| 7 |
+
|
| 8 |
+
Requires an HF_TOKEN (write) — set it as a Space secret. Without a token this
|
| 9 |
+
is a silent no-op so local runs keep working unchanged. Override the target
|
| 10 |
+
repo with TRACES_REPO (default: <your-username>/flightdeck-traces).
|
| 11 |
+
"""
|
| 12 |
+
from __future__ import annotations
|
| 13 |
+
|
| 14 |
+
import os
|
| 15 |
+
|
| 16 |
+
from agent import TRACES_DIR
|
| 17 |
+
|
| 18 |
+
# Keep a module-level reference so the scheduler thread isn't garbage-collected.
|
| 19 |
+
_SCHEDULER = None
|
| 20 |
+
|
| 21 |
+
|
| 22 |
+
def start() -> str:
|
| 23 |
+
"""Start the background sync. Returns a one-line status for logging."""
|
| 24 |
+
global _SCHEDULER
|
| 25 |
+
if _SCHEDULER is not None:
|
| 26 |
+
return "trace sync already running"
|
| 27 |
+
token = os.environ.get("HF_TOKEN") or os.environ.get("HUGGINGFACE_TOKEN")
|
| 28 |
+
if not token:
|
| 29 |
+
return "trace sync off — set HF_TOKEN (write) to push traces to a dataset repo"
|
| 30 |
+
try:
|
| 31 |
+
from huggingface_hub import CommitScheduler, whoami
|
| 32 |
+
|
| 33 |
+
repo_id = os.environ.get("TRACES_REPO")
|
| 34 |
+
if not repo_id:
|
| 35 |
+
user = whoami(token=token)["name"]
|
| 36 |
+
repo_id = f"{user}/flightdeck-traces"
|
| 37 |
+
_SCHEDULER = CommitScheduler(
|
| 38 |
+
repo_id=repo_id,
|
| 39 |
+
repo_type="dataset",
|
| 40 |
+
folder_path=TRACES_DIR,
|
| 41 |
+
path_in_repo="traces",
|
| 42 |
+
every=2, # minutes
|
| 43 |
+
token=token,
|
| 44 |
+
)
|
| 45 |
+
return f"trace sync on → https://huggingface.co/datasets/{repo_id} (every 2 min)"
|
| 46 |
+
except Exception as e: # noqa: BLE001 — tracing must never take the app down
|
| 47 |
+
return f"trace sync failed ({type(e).__name__}: {e}) — app continues without it"
|