# Code , complete app.py with full code for /stream, /dashboard, CSV download, and WebSocket handling. from fastapi import FastAPI, WebSocket from fastapi.responses import HTMLResponse, StreamingResponse import uvicorn import json import csv from io import StringIO app = FastAPI() telemetry_data = [] # list to hold telemetry data dashboard_connections = [] # active dashboard WebSocket connections @app.get("/stream") async def stream(): html = """ Emerson Telemetry Stream

Emerson Telemetry Stream

Click "Start Streaming" to begin.

""" return HTMLResponse(html) @app.get("/dashboard") async def dashboard(): html = """ Emerson Dashboard

Emerson Dashboard

Waiting for Emerson...

Speed:
-- m/s
Altitude:
-- m
Back Camera Front Camera
Download CSV """ return HTMLResponse(html) @app.get("/download-csv") async def download_csv(): def iter_csv(): si = StringIO() writer = csv.writer(si) writer.writerow(["timestamp","latitude","longitude","altitude","speed","back_image","front_image"]) for d in telemetry_data: writer.writerow([ d["timestamp"], d["gps"]["latitude"], d["gps"]["longitude"], d["gps"]["altitude"], d["gps"]["speed"], d["images"]["back"], d["images"]["front"] ]) yield si.getvalue(); si.seek(0); si.truncate(0) return StreamingResponse(iter_csv(), media_type="text/csv") @app.websocket("/ws") async def websocket_endpoint(ws: WebSocket): await ws.accept() dashboard_connections.append(ws) try: while True: msg = await ws.receive_text() obj = json.loads(msg) telemetry_data.append(obj) for conn in dashboard_connections: try: await conn.send_text(json.dumps(obj)) except: dashboard_connections.remove(conn) except: dashboard_connections.remove(ws) if __name__ == "__main__": uvicorn.run(app, host="0.0.0.0", port=7860)