File size: 2,133 Bytes
79c4cf2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
"""FloodGate v1 on a Hugging Face Space: the OpenEnv server (reset, step, state, the MCP tools, the Task API and the web
UI at /web, whose Explore tab holds the 3D replay and every committed run's results) and the replay at /twin/.

The Space serves live mode (FLOOD_MODE=live): the agent commits the dams' releases block by block on forecast scenarios
that carry real 2025 NWS forecast errors. It runs on ZeroGPU hardware but never asks for a GPU; ZeroGPU wants one
decorated function, so `_noop` exists and is never called.

    python app.py            # http://127.0.0.1:7860/web/ (the Space's page), /twin/
"""

from __future__ import annotations

import os
import sys
from pathlib import Path

ROOT = Path(__file__).resolve().parent
sys.path[:0] = [str(ROOT / "core"), str(ROOT / "openenv")]
os.environ.setdefault("FLOOD_TASKS_DIR", str(ROOT / "tasks" / "flood-v1-sample"))
os.environ.setdefault("FLOOD_RUNS_DIR", str(ROOT / "runs"))
os.environ.setdefault("FLOOD_DATA_DIR", str(ROOT / "data" / "cumberland"))
os.environ.setdefault("FLOOD_MODE", "live")
os.environ.setdefault("ENABLE_WEB_INTERFACE", "true")
# Spaces turn on Gradio's server-side rendering, whose Node server takes port 7860 before uvicorn can.
os.environ["GRADIO_SSR_MODE"] = "false"

card = (ROOT / "README.md").read_text(encoding="utf-8")
if card.startswith("---"):
    card = card.split("---", 2)[2].lstrip()
readme = Path(os.environ.get("TMPDIR", "/tmp")) / "floodgate_readme.md"
readme.write_text(card, encoding="utf-8")
os.environ.setdefault("ENV_README_PATH", str(readme))

try:
    import spaces
except ImportError:  # running elsewhere
    spaces = None

if spaces is not None:
    @spaces.GPU(duration=1)
    def _noop():  # ZeroGPU requires one decorated function; nothing calls it
        pass

import uvicorn  # noqa: E402

from flood_openenv.server import build_app  # noqa: E402

app = build_app()

if __name__ == "__main__":
    if spaces is not None:
        from spaces import zero

        zero.startup()
    uvicorn.run(app, host="0.0.0.0", port=int(os.environ.get("PORT", "7860")), ws_ping_interval=60,
                ws_ping_timeout=600)