kanishcr7 commited on
Commit
76a58d5
Β·
1 Parent(s): 00ed537

Merged Proxy: Streamlit Dashboard now primary UI on port 7860

Browse files
Files changed (3) hide show
  1. requirements.txt +1 -0
  2. server/app.py +51 -38
  3. start.sh +13 -2
requirements.txt CHANGED
@@ -1,6 +1,7 @@
1
  # Core
2
  openenv-core[ui]>=0.2.0
3
  openai>=1.0.0
 
4
  numpy>=1.24.0
5
  PyYAML>=6.0
6
  python-dotenv>=1.0.0
 
1
  # Core
2
  openenv-core[ui]>=0.2.0
3
  openai>=1.0.0
4
+ httpx>=0.25.0
5
  numpy>=1.24.0
6
  PyYAML>=6.0
7
  python-dotenv>=1.0.0
server/app.py CHANGED
@@ -30,7 +30,10 @@ from openenv.core import create_app
30
 
31
  from patchhawk.agent.environment import PatchHawkEnv
32
  from patchhawk.env_models import PatchHawkAction, PatchHawkObservation
33
- from fastapi.responses import HTMLResponse
 
 
 
34
 
35
 
36
  def _env_factory() -> PatchHawkEnv:
@@ -51,44 +54,54 @@ def create_openenv_app():
51
 
52
  app = create_openenv_app()
53
 
54
- @app.get("/", response_class=HTMLResponse)
55
- def root_dashboard():
56
- return """
57
- <!DOCTYPE html>
58
- <html>
59
- <head>
60
- <title>PatchHawk | Autonomous DevSecOps SOC</title>
61
- <style>
62
- body { font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; background-color: #0d1117; color: #c9d1d9; display: flex; flex-direction: column; align-items: center; justify-content: center; height: 100vh; margin: 0; }
63
- .container { background: #161b22; padding: 40px; border-radius: 12px; border: 1px solid #30363d; box-shadow: 0 10px 30px rgba(0,0,0,0.5); text-align: center; max-width: 600px; }
64
- h1 { color: #58a6ff; margin-bottom: 10px; }
65
- p { font-size: 1.1em; color: #8b949e; line-height: 1.6; }
66
- .status { display: inline-block; padding: 5px 15px; border-radius: 20px; background: #238636; color: white; font-weight: bold; margin: 20px 0; }
67
- .links { display: flex; gap: 10px; justify-content: center; margin-top: 30px; }
68
- .btn { text-decoration: none; padding: 12px 25px; border-radius: 6px; font-weight: bold; transition: 0.3s; }
69
- .btn-blue { background: #1f6feb; color: white; }
70
- .btn-blue:hover { background: #388bfd; }
71
- .btn-outline { border: 1px solid #30363d; color: #58a6ff; }
72
- .btn-outline:hover { background: #30363d; }
73
- .badge { background: #30363d; padding: 4px 10px; border-radius: 4px; font-family: monospace; }
74
- </style>
75
- </head>
76
- <body>
77
- <div class="container">
78
- <h1>πŸ¦… PatchHawk SOC</h1>
79
- <p>Autonomous Supply-Chain Vulnerability & Patching Agent</p>
80
- <div class="status">● ENVIRONMENT LIVE</div>
81
- <p>The OpenEnv API Spec is running correctly at <span class="badge">port: 7860</span>.</p>
82
-
83
- <div class="links">
84
- <a href="/web" class="btn btn-blue">Open Env Explorer</a>
85
- <a href="/docs" class="btn btn-outline">API Docs (Swagger)</a>
86
- </div>
87
- <p style="margin-top:20px; font-size:0.9em;">Evaluation URL: <span class="badge">/reset</span></p>
88
- </div>
89
- </body>
90
- </html>
91
  """
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
92
 
93
 
94
  def main(port: int | None = None) -> None:
 
30
 
31
  from patchhawk.agent.environment import PatchHawkEnv
32
  from patchhawk.env_models import PatchHawkAction, PatchHawkObservation
33
+ from fastapi.responses import HTMLResponse, StreamingResponse
34
+ import httpx
35
+ from starlette.requests import Request
36
+ from starlette.background import BackgroundTask
37
 
38
 
39
  def _env_factory() -> PatchHawkEnv:
 
54
 
55
  app = create_openenv_app()
56
 
57
+ # ── Streamlit Proxy Configuration ─────────────────────────────────────
58
+ STREAMLIT_URL = "http://localhost:8501"
59
+
60
+ @app.api_route("/{path:path}", methods=["GET", "POST", "PUT", "DELETE", "OPTIONS"])
61
+ async def proxy_streamlit(request: Request, path: str):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
62
  """
63
+ Proxies all requests not handled by OpenEnv routes to the local Streamlit server.
64
+ This ensures the Streamlit Dashboard is the primary UI on port 7860.
65
+ """
66
+ # Skip proxying for OpenEnv specific routes so the grader still works
67
+ openenv_routes = ["reset", "step", "docs", "openapi.json", "web", "assets"]
68
+ if any(path.startswith(r) for r in openenv_routes) or path == "":
69
+ if path == "":
70
+ # Redirect root to Streamlit
71
+ pass
72
+ else:
73
+ # Let FastAPI handle it
74
+ return
75
+
76
+ client = httpx.AsyncClient(base_url=STREAMLIT_URL)
77
+ url = httpx.URL(path=request.url.path, query=request.url.query.encode("utf-8"))
78
+
79
+ # Filter out headers that might cause issues with the proxy
80
+ headers = {k: v for k, v in request.headers.items() if k.lower() not in ["host", "connection"]}
81
+
82
+ # Handle the request body
83
+ body = await request.body()
84
+
85
+ # Forward the request to Streamlit
86
+ rp_resp = await client.request(
87
+ method=request.method,
88
+ url=url,
89
+ headers=headers,
90
+ content=body,
91
+ follow_redirects=True,
92
+ )
93
+
94
+ return StreamingResponse(
95
+ rp_resp.aiter_raw(),
96
+ status_code=rp_resp.status_code,
97
+ headers=dict(rp_resp.headers),
98
+ background=BackgroundTask(client.aclose)
99
+ )
100
+
101
+ @app.get("/", response_class=HTMLResponse)
102
+ async def root_redirect(request: Request):
103
+ """Force the root to proxy to Streamlit."""
104
+ return await proxy_streamlit(request, "")
105
 
106
 
107
  def main(port: int | None = None) -> None:
start.sh CHANGED
@@ -3,6 +3,17 @@
3
  echo "Starting OpenEnv API server on port 7860..."
4
  uvicorn server.app:app --host 0.0.0.0 --port 7860 &
5
 
6
- # Start the Streamlit Dashboard (User UI)
7
  echo "Starting Streamlit Dashboard on port 8501..."
8
- streamlit run patchhawk/app/dashboard.py --server.port 8501 --server.address 0.0.0.0
 
 
 
 
 
 
 
 
 
 
 
 
3
  echo "Starting OpenEnv API server on port 7860..."
4
  uvicorn server.app:app --host 0.0.0.0 --port 7860 &
5
 
6
+ # Start the Streamlit Dashboard (User UI) in the background with Proxy-friendly settings
7
  echo "Starting Streamlit Dashboard on port 8501..."
8
+ streamlit run patchhawk/app/dashboard.py \
9
+ --server.port 8501 \
10
+ --server.address 0.0.0.0 \
11
+ --server.enableCORS false \
12
+ --server.enableXsrfProtection false \
13
+ --server.headless true \
14
+ --browser.gatherUsageStats false &
15
+
16
+ # Start the OpenEnv API server (Hackathon Compliance) on Port 7860
17
+ # This server now PROXIES all UI requests to Streamlit on 8501
18
+ echo "Starting OpenEnv API server on port 7860..."
19
+ uvicorn server.app:app --host 0.0.0.0 --port 7860