SatCat commited on
Commit
8a10f4e
1 Parent(s): a82c671

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +130 -0
app.py ADDED
@@ -0,0 +1,130 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import asyncio
2
+ from starlette.applications import Starlette
3
+ from starlette.endpoints import WebSocketEndpoint, HTTPEndpoint
4
+ from starlette.responses import HTMLResponse
5
+ from starlette.routing import Route, WebSocketRoute, Mount
6
+ from starlette.websockets import WebSocket
7
+ from starlette.types import Message, Receive, Scope, Send
8
+
9
+ # -------------------- gradio ------------------------
10
+ import gradio as gr
11
+
12
+ async def name_fn(name):
13
+ await mbase.add_msg(f'gradio_name: {name}')
14
+ return "Name: " + name + "!"
15
+
16
+ io = gr.Interface(fn=name_fn, inputs=gr.Textbox(lines=2, placeholder="Name Here..."), outputs="text")
17
+ gradio_app = gr.routes.App.create_app(io)
18
+
19
+ # -------------------- shiny ------------------------
20
+ import shiny
21
+ from shiny import App, render, ui, reactive
22
+ import numpy as np
23
+ import matplotlib.pyplot as plt
24
+
25
+ app_ui = ui.page_fluid(
26
+ ui.input_slider("n", "Number of bins", 1, 100, 20),
27
+ ui.output_plot("plot", width='30%', height='120px'),
28
+ )
29
+
30
+ def server(input, output, session):
31
+ @output
32
+ @render.plot(alt="A histogram")
33
+ async def plot():
34
+ await mbase.add_msg(f'shiny_bin: {input.n()}')
35
+ x = 100 + 15 * np.random.randn(120)
36
+ fig, ax = plt.subplots()
37
+ ax.hist(x, input.n(), density=True)
38
+ return fig
39
+
40
+
41
+ app_shiny = App(ui = app_ui, server = server)
42
+
43
+ # -------------------- main + msg store and dispatch ------------------------
44
+ ws_list = []
45
+
46
+ class MsgBase():
47
+ """ Store and send messages to clients """
48
+ msg_history = ['start logging..',]
49
+
50
+ async def add_msg(self, msg):
51
+ self.msg_history.insert(0, msg)
52
+ if len(self.msg_history) > 15:
53
+ self.msg_history.pop()
54
+ for ws in ws_list:
55
+ await ws.send_text(msg)
56
+
57
+ async def send_all_msg(self, ws):
58
+ """ Restore all messages in new page or reloaded page"""
59
+ ws_list.append(ws)
60
+ for msg in self.msg_history:
61
+ await ws.send_text(msg)
62
+
63
+ mbase = MsgBase()
64
+
65
+
66
+ html = """
67
+ <!DOCTYPE html>
68
+ <html><head><title>Shiny and Gradio Test App</title>
69
+ <style>
70
+ .bottom_div { position:absolute; background: #E8F8E8; bottom:0; width:99%; height:100px; max-height: 30%; overflow-y: auto;}
71
+ .log_msg { font-size: 0.75em; font-family: sans-serif; padding: .2em; margin: 0; line-height: 1em;}
72
+ </style>
73
+ </head>
74
+ <body>
75
+ <script type="text/javascript">
76
+ var ws = new WebSocket("ws://localhost:8000/ws");
77
+ ws.onmessage = function(event) {
78
+ var newNode = document.createElement('li');
79
+ var content = document.createTextNode(event.data);
80
+ newNode.appendChild(content);
81
+ var messages = document.getElementById('log_msg');
82
+ messages.insertBefore(newNode, messages.children[0]);
83
+
84
+ // remove last evement
85
+ remove_idx = messages.getElementsByTagName("li").length -1;
86
+ if (remove_idx > 15) {
87
+ messages.children[remove_idx].remove();
88
+ }
89
+
90
+ }
91
+ </script>
92
+ Shiny App
93
+ <iframe src="/shiny/" width="100%" height="250" style="border:1px solid blue;"></iframe>
94
+ Gradio App
95
+ <iframe src="/gradio/" width="100%" height="250" style="border:1px solid red;"></iframe>
96
+ <div class="bottom_div"><ul class="log_msg" id="log_msg"></ul></div>
97
+ </body>
98
+ </html>"""
99
+
100
+ class Homepage(HTTPEndpoint):
101
+ async def get(self, request):
102
+ return HTMLResponse(html)
103
+
104
+ class Echo(WebSocketEndpoint):
105
+ async def on_connect(self, websocket: WebSocket) -> None:
106
+ await websocket.accept()
107
+ await mbase.send_all_msg(websocket)
108
+
109
+ async def on_disconnect(self, websocket: WebSocket, close_code: int) -> None:
110
+ ws_list.remove(websocket)
111
+
112
+ routes = [
113
+ Route("/", Homepage),
114
+ WebSocketRoute("/ws", Echo),
115
+ Mount('/shiny', app=app_shiny),
116
+ Mount('/gradio', app=gradio_app)
117
+ ]
118
+ app = Starlette(routes=routes)
119
+
120
+
121
+ # as a main work loop..
122
+ @app.on_event("startup")
123
+ async def startup_event():
124
+ asyncio.create_task(dispatch_task())
125
+
126
+ async def dispatch_task():
127
+ """ background task to dispatch autonomous events """
128
+ for i in range(20):
129
+ await mbase.add_msg(f'(main loop) I am work!({i})')
130
+ await asyncio.sleep(8)