memex-in commited on
Commit
84c35be
·
verified ·
1 Parent(s): a6db038

Create main.py

Browse files
Files changed (1) hide show
  1. main.py +50 -0
main.py ADDED
@@ -0,0 +1,50 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import asyncio, gradio as gr
2
+ from fastapi import FastAPI, WebSocket, WebSocketDisconnect
3
+ from fastapi.middleware.cors import CORSMiddleware
4
+
5
+ app = FastAPI()
6
+ app.add_middleware(CORSMiddleware, allow_origins=["*"], allow_methods=["*"], allow_headers=["*"])
7
+
8
+ # WebSocket terminal
9
+ @app.websocket("/ws")
10
+ async def ws_terminal(ws: WebSocket):
11
+ await ws.accept()
12
+ await ws.send_text("Connected to terminal\n")
13
+ try:
14
+ while True:
15
+ cmd = await ws.receive_text()
16
+ proc = await asyncio.create_subprocess_shell(cmd,
17
+ stdout=asyncio.subprocess.PIPE,
18
+ stderr=asyncio.subprocess.PIPE)
19
+ out, err = await proc.communicate()
20
+ msg = (out + err).decode()
21
+ await ws.send_text(msg)
22
+ except WebSocketDisconnect:
23
+ print("Client disconnected")
24
+
25
+ # Gradio UI
26
+ JS = """
27
+ <script>
28
+ const ws = new WebSocket(`ws://${location.host}/ws`);
29
+ ws.onmessage = e => {
30
+ const o = document.getElementById("out");
31
+ o.value += e.data + "\\n";
32
+ o.scrollTop = o.scrollHeight;
33
+ };
34
+ function sendCmd(e) {
35
+ if (e.key === "Enter") {
36
+ ws.send(e.target.value);
37
+ e.target.value = "";
38
+ }
39
+ }
40
+ </script>
41
+ <textarea id="out" rows="20" style="width:100%;" readonly></textarea>
42
+ <input id="inp" style="width:100%;" placeholder="cmd…" onkeydown="sendCmd(event)">
43
+ """
44
+
45
+ with gr.Blocks() as demo:
46
+ gr.Markdown("## 🖥️ Interactive Terminal")
47
+ gr.HTML(JS)
48
+
49
+ # Launch Gradio on port 7861
50
+ gr_app = gr.mount_gradio_app(app, demo, path="/gradio", server_port=7861)