]> git.mar77i.info Git - hublib/blob - hub/app.py
functioning basic chat app
[hublib] / hub / app.py
1 from argparse import ArgumentParser
2 from itertools import chain
3 from secrets import token_urlsafe
4 import socket
5 from subprocess import run
6 import sys
7 from traceback import print_exception
8 from typing import List, Optional
9 from urllib.parse import urlunsplit
10
11 from falcon.asgi import App
12 from falcon.constants import MEDIA_HTML
13 from uvicorn import Config, Server
14
15 from .staticresource import StaticResource
16 from .hub import Hub
17
18
19 class HubApp(App):
20 def __init__(self, secret, browser, hubapp, *args, **kwargs):
21 kwargs.setdefault("media_type", MEDIA_HTML)
22 super().__init__(*args, **kwargs)
23 self.secret = secret or token_urlsafe(64)
24 self.hub = Hub(self.secret)
25 self.sr = StaticResource(self.secret, hubapp, self.hub.master_ws_uri)
26 self.browser = browser
27 self.hub.add_routes(self)
28 self.sr.add_routes(self)
29 self.add_error_handler(Exception, self.print_exception)
30
31 async def print_exception(self, req, resp, ex, params):
32 print_exception(*sys.exc_info())
33
34
35 def get_app():
36 ap = ArgumentParser()
37 ap.add_argument("--secret")
38 ap.add_argument("--browser", default="firefox")
39 ap.add_argument("--hubapp", default="first")
40 args = ap.parse_args()
41 return HubApp(args.secret, args.browser, args.hubapp)
42
43
44 class HubServer(Server):
45 async def startup(self, sockets: Optional[List[socket.socket]] = None) -> None:
46 await super().startup(sockets)
47 config = self.config
48 protocol_name = "https" if config.ssl else "http"
49 host = "0.0.0.0" if config.host is None else config.host
50 if ":" in host:
51 # It's an IPv6 address.
52 host = f"[{host.rstrip(']').lstrip('[')}]"
53
54 port = config.port
55 if port == 0:
56 try:
57 port = next(
58 chain.from_iterable((server.sockets for server in getattr(self, "servers", ())))
59 ).getsockname()[1]
60 except StopIteration:
61 pass
62 if {"http": 80, "https": 443}[protocol_name] != port:
63 host = f"{host}:{port}"
64 app = config.loaded_app.app
65 print("master_uri", app.sr.master_uri)
66 master_url = urlunsplit((protocol_name, host, app.sr.master_uri, "", ""))
67 print("secret:", app.secret)
68 if not app.browser:
69 print("master url", master_url)
70 else:
71 run([app.browser, master_url])
72
73
74 def main():
75 HubServer(
76 Config("hub.app:get_app", factory=True, port=5000, log_level="info")
77 ).run()