SalexAI commited on
Commit
658b428
·
verified ·
1 Parent(s): b9c19e2

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +128 -52
app.py CHANGED
@@ -1,64 +1,140 @@
1
- import gradio as gr
2
- from huggingface_hub import InferenceClient
3
 
4
- """
5
- For more information on `huggingface_hub` Inference API support, please check the docs: https://huggingface.co/docs/huggingface_hub/v0.22.2/en/guides/inference
6
- """
7
- client = InferenceClient("HuggingFaceH4/zephyr-7b-beta")
 
 
8
 
 
 
 
 
9
 
10
- def respond(
11
- message,
12
- history: list[tuple[str, str]],
13
- system_message,
14
- max_tokens,
15
- temperature,
16
- top_p,
17
- ):
18
- messages = [{"role": "system", "content": system_message}]
 
 
 
 
 
 
 
 
 
 
19
 
20
- for val in history:
21
- if val[0]:
22
- messages.append({"role": "user", "content": val[0]})
23
- if val[1]:
24
- messages.append({"role": "assistant", "content": val[1]})
 
 
 
 
 
 
 
 
 
 
 
 
25
 
26
- messages.append({"role": "user", "content": message})
 
 
 
 
27
 
28
- response = ""
 
 
 
 
 
 
29
 
30
- for message in client.chat_completion(
31
- messages,
32
- max_tokens=max_tokens,
33
- stream=True,
34
- temperature=temperature,
35
- top_p=top_p,
36
- ):
37
- token = message.choices[0].delta.content
38
 
39
- response += token
40
- yield response
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
41
 
 
 
 
 
 
 
 
 
 
 
 
 
42
 
43
- """
44
- For information on how to customize the ChatInterface, peruse the gradio docs: https://www.gradio.app/docs/chatinterface
45
- """
46
- demo = gr.ChatInterface(
47
- respond,
48
- additional_inputs=[
49
- gr.Textbox(value="You are a friendly Chatbot.", label="System message"),
50
- gr.Slider(minimum=1, maximum=2048, value=512, step=1, label="Max new tokens"),
51
- gr.Slider(minimum=0.1, maximum=4.0, value=0.7, step=0.1, label="Temperature"),
52
- gr.Slider(
53
- minimum=0.1,
54
- maximum=1.0,
55
- value=0.95,
56
- step=0.05,
57
- label="Top-p (nucleus sampling)",
58
- ),
59
- ],
60
- )
61
-
62
 
63
  if __name__ == "__main__":
64
- demo.launch()
 
1
+ # Sir, this app.py implements /stream and /dashboard endpoints with telemetry streaming, offline buffering, and CSV download.
2
+ # Sir, let me know if you'd like a detailed walkthrough.
3
 
4
+ from fastapi import FastAPI, WebSocket, Request
5
+ from fastapi.responses import HTMLResponse, StreamingResponse
6
+ import uvicorn
7
+ import json
8
+ import csv
9
+ from io import StringIO
10
 
11
+ app = FastAPI()
12
+ telemetry_data = [] # Store telemetry dicts
13
+ # Active WebSocket connections for dashboard clients
14
+ dashboard_connections = []
15
 
16
+ @app.get("/stream")
17
+ async def stream():
18
+ html = """
19
+ <!DOCTYPE html>
20
+ <html>
21
+ <head><title>Emerson Telemetry Stream</title></head>
22
+ <body>
23
+ <h1>Emerson Telemetry Stream</h1>
24
+ <p id="status">Connecting...</p>
25
+ <video id="video" width="320" height="240" autoplay muted></video>
26
+ <script>
27
+ const ws = new WebSocket(`ws://${location.host}/ws`);
28
+ let buffer = [];
29
+ document.getElementById("status").innerText = navigator.onLine ? "Connected" : "Waiting for Emerson...";
30
+ window.addEventListener("online", () => flushBuffer());
31
+ window.addEventListener("offline", () => document.getElementById("status").innerText = "Waiting for Emerson...");
32
+ ws.onopen = () => { document.getElementById("status").innerText = "Connected"; flushBuffer(); };
33
+ ws.onclose = () => document.getElementById("status").innerText = "Disconnected";
34
+ ws.onerror = () => document.getElementById("status").innerText = "Error";
35
 
36
+ async function sendTelemetry() {
37
+ const canvas = document.createElement("canvas");
38
+ const video = document.getElementById("video");
39
+ canvas.width = video.videoWidth;
40
+ canvas.height = video.videoHeight;
41
+ const ctx = canvas.getContext("2d");
42
+ ctx.drawImage(video, 0, 0);
43
+ const image = canvas.toDataURL("image/jpeg");
44
+ navigator.geolocation.getCurrentPosition(pos => {
45
+ const data = { timestamp: Date.now(), gps: pos.coords, image };
46
+ if (ws.readyState === WebSocket.OPEN) {
47
+ ws.send(JSON.stringify(data));
48
+ } else {
49
+ buffer.push(data);
50
+ }
51
+ });
52
+ }
53
 
54
+ function flushBuffer() {
55
+ while (buffer.length) {
56
+ ws.send(JSON.stringify(buffer.shift()));
57
+ }
58
+ }
59
 
60
+ navigator.mediaDevices.enumerateDevices().then(devices => {
61
+ const videoInputs = devices.filter(d => d.kind === "videoinput");
62
+ if (videoInputs.length) {
63
+ navigator.mediaDevices.getUserMedia({ video: { deviceId: { exact: videoInputs[0].deviceId } } })
64
+ .then(stream => { document.getElementById("video").srcObject = stream; });
65
+ }
66
+ });
67
 
68
+ setInterval(sendTelemetry, 1000);
69
+ </script>
70
+ </body>
71
+ </html>
72
+ """
73
+ return HTMLResponse(html)
 
 
74
 
75
+ @app.get("/dashboard")
76
+ async def dashboard():
77
+ html = """
78
+ <!DOCTYPE html>
79
+ <html>
80
+ <head><title>Emerson Dashboard</title></head>
81
+ <body>
82
+ <h1>Emerson Dashboard</h1>
83
+ <p id="status">Waiting for Emerson...</p>
84
+ <div id="data"></div>
85
+ <a href="/download-csv" download="telemetry.csv">Download CSV</a>
86
+ <script>
87
+ const ws = new WebSocket(`ws://${location.host}/ws`);
88
+ ws.onopen = () => document.getElementById("status").innerText = "Connected";
89
+ ws.onmessage = msg => {
90
+ const data = JSON.parse(msg.data);
91
+ document.getElementById("status").innerText = "Streaming";
92
+ const div = document.getElementById("data");
93
+ const p = document.createElement("p");
94
+ p.innerText = `Time: ${new Date(data.timestamp).toLocaleTimeString()} GPS: ${data.gps.latitude.toFixed(5)}, ${data.gps.longitude.toFixed(5)}`;
95
+ const img = document.createElement("img");
96
+ img.src = data.image;
97
+ img.width = 160;
98
+ div.prepend(img);
99
+ div.prepend(p);
100
+ };
101
+ ws.onclose = () => document.getElementById("status").innerText = "Disconnected";
102
+ </script>
103
+ </body>
104
+ </html>
105
+ """
106
+ return HTMLResponse(html)
107
 
108
+ @app.get("/download-csv")
109
+ async def download_csv():
110
+ def iter_csv():
111
+ si = StringIO()
112
+ writer = csv.writer(si)
113
+ writer.writerow(["timestamp", "latitude", "longitude", "image"])
114
+ for d in telemetry_data:
115
+ writer.writerow([d["timestamp"], d["gps"]["latitude"], d["gps"]["longitude"], d["image"]])
116
+ yield si.getvalue()
117
+ si.seek(0)
118
+ si.truncate(0)
119
+ return StreamingResponse(iter_csv(), media_type="text/csv")
120
 
121
+ @app.websocket("/ws")
122
+ async def websocket_endpoint(ws: WebSocket):
123
+ await ws.accept()
124
+ dashboard_connections.append(ws)
125
+ try:
126
+ while True:
127
+ data = await ws.receive_text()
128
+ telemetry = json.loads(data)
129
+ telemetry_data.append(telemetry)
130
+ # Broadcast to dashboard clients
131
+ for conn in dashboard_connections:
132
+ try:
133
+ await conn.send_text(json.dumps(telemetry))
134
+ except:
135
+ dashboard_connections.remove(conn)
136
+ except:
137
+ dashboard_connections.remove(ws)
 
 
138
 
139
  if __name__ == "__main__":
140
+ uvicorn.run(app, host="0.0.0.0", port=7860)