File size: 1,934 Bytes
80b34d1 152733f cffa613 152733f 95b4e2c 152733f 95b4e2c 152733f 95b4e2c 152733f 95b4e2c 152733f cffa613 | 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 58 59 60 61 62 63 64 | from fastapi import FastAPI, Request
from fastapi.responses import HTMLResponse, StreamingResponse
import asyncio
import os
import uvicorn
import logging
# Disable uvicorn access logs to prevent stdout pollution for OpenEnv
logging.getLogger("uvicorn.access").setLevel(logging.WARNING)
app = FastAPI(title="Dynamic Guardrail Env")
METRICS_FILE = "metrics.jsonl"
async def event_generator(request: Request):
if not os.path.exists(METRICS_FILE):
open(METRICS_FILE, "w").close()
with open(METRICS_FILE, "r", encoding="utf-8") as f:
last_pos = f.tell()
while True:
if await request.is_disconnected():
break
try:
file_size = os.path.getsize(METRICS_FILE)
except OSError:
await asyncio.sleep(0.2)
continue
# Handle truncation or log rotation safely.
if file_size < last_pos:
f.seek(0)
last_pos = 0
f.seek(last_pos)
new_lines = f.readlines()
if not new_lines:
await asyncio.sleep(0.1)
continue
last_pos = f.tell()
for line in new_lines:
payload = line.strip()
if not payload:
continue
yield f"data: {payload}\n\n"
@app.get("/stream")
async def stream(request: Request):
return StreamingResponse(event_generator(request), media_type="text/event-stream")
@app.get("/")
async def get_index():
ui_path = os.path.join(os.path.dirname(os.path.dirname(__file__)), "ui", "index.html")
if os.path.exists(ui_path):
with open(ui_path, "r", encoding="utf-8") as f:
return HTMLResponse(content=f.read())
return {"detail": "Frontend not found"}
if __name__ == "__main__":
uvicorn.run("src.api.server:app", host="0.0.0.0", port=8000, log_level="warning")
|