Quellcode durchsuchen

not working: try hosting behind reverse proxy

Rodja Trappe vor 2 Jahren
Ursprung
Commit
efc8d4de11
5 geänderte Dateien mit 25 neuen und 15 gelöschten Zeilen
  1. 7 7
      main.py
  2. 6 3
      nicegui/client.py
  3. 9 2
      nicegui/page.py
  4. 1 1
      nicegui/templates/index.html
  5. 2 2
      nicegui/vue.py

+ 7 - 7
main.py

@@ -19,14 +19,14 @@ def add_head_html() -> None:
     ui.add_head_html(docutils.core.publish_parts('', writer_name='html')['stylesheet'])
     ui.add_head_html(f'<style>{HtmlFormatter(nobackground=True).get_style_defs(".codehilite")}</style>')
     ui.add_head_html('''
-        <link rel="apple-touch-icon" sizes="180x180" href="/favicon/apple-touch-icon.png">
-        <link rel="icon" type="image/png" sizes="32x32" href="/favicon/favicon-32x32.png">
-        <link rel="icon" type="image/png" sizes="16x16" href="/favicon/favicon-16x16.png">
-        <link rel="manifest" href="/favicon/site.webmanifest">
-        <link rel="mask-icon" href="/favicon/safari-pinned-tab.svg" color="#000000">
-        <link rel="shortcut icon" href="/favicon/favicon.ico">
+        <link rel="apple-touch-icon" sizes="180x180" href="favicon/apple-touch-icon.png">
+        <link rel="icon" type="image/png" sizes="32x32" href="favicon/favicon-32x32.png">
+        <link rel="icon" type="image/png" sizes="16x16" href="favicon/favicon-16x16.png">
+        <link rel="manifest" href="favicon/site.webmanifest">
+        <link rel="mask-icon" href="favicon/safari-pinned-tab.svg" color="#000000">
+        <link rel="shortcut icon" href="favicon/favicon.ico">
         <meta name="msapplication-TileColor" content="#ffffff">
-        <meta name="msapplication-config" content="/favicon/browserconfig.xml">
+        <meta name="msapplication-config" content="favicon/browserconfig.xml">
         <meta name="theme-color" content="#ffffff">
     ''')  # https://realfavicongenerator.net/
     ui.add_head_html(r'''

+ 6 - 3
nicegui/client.py

@@ -5,6 +5,7 @@ import uuid
 from pathlib import Path
 from typing import TYPE_CHECKING, Any, Awaitable, Callable, Dict, List, Optional, Union
 
+from fastapi import Request
 from fastapi.responses import HTMLResponse
 
 from . import globals, vue
@@ -20,7 +21,8 @@ TEMPLATE = (Path(__file__).parent / 'templates' / 'index.html').read_text()
 
 class Client:
 
-    def __init__(self, page: 'page', *, shared: bool = False) -> None:
+    def __init__(self, page: 'page', *, request: Optional[Request] = None, shared: bool = False) -> None:
+        self.request = request
         self.id = globals.next_client_id
         globals.next_client_id += 1
         globals.clients[self.id] = self
@@ -63,10 +65,10 @@ class Client:
     def build_response(self, status_code: int = 200) -> HTMLResponse:
         vue_html, vue_styles, vue_scripts = vue.generate_vue_content()
         elements = json.dumps({id: element.to_dict() for id, element in self.elements.items()})
+        prefix = self.request.headers.get('X-Forwarded-Prefix', '') if self.request else ''
         return HTMLResponse(
             TEMPLATE
             .replace(r'{{ client_id }}', str(self.id))
-            .replace(r'{{ socket_address }}', f'ws://{globals.host}:{globals.port}')
             .replace(r'{{ elements | safe }}', elements)
             .replace(r'{{ head_html | safe }}', self.head_html)
             .replace(r'{{ body_html | safe }}', f'{self.body_html}\n{vue_html}\n{vue_styles}')
@@ -74,7 +76,8 @@ class Client:
             .replace(r'{{ js_imports | safe }}', vue.generate_js_imports())
             .replace(r'{{ title }}', self.page.resolve_title())
             .replace(r'{{ favicon_url }}', get_favicon_url(self.page))
-            .replace(r'{{ dark }}', str(self.page.resolve_dark())),
+            .replace(r'{{ dark }}', str(self.page.resolve_dark()))
+            .replace(r'{{ prefix | safe }}', prefix),
             status_code
         )
 

+ 9 - 2
nicegui/page.py

@@ -3,7 +3,7 @@ import inspect
 import time
 from typing import Callable, Optional
 
-from fastapi import Response
+from fastapi import Request, Response
 
 from . import globals
 from .async_updater import AsyncUpdater
@@ -47,9 +47,13 @@ class page:
     def __call__(self, func: Callable) -> Callable:
         # NOTE we need to remove existing routes for this path to make sure only the latest definition is used
         globals.app.routes[:] = [r for r in globals.app.routes if r.path != self.path]
+        parameters_of_decorated_func = list(inspect.signature(func).parameters.keys())
 
         async def decorated(*dec_args, **dec_kwargs) -> Response:
-            with Client(self) as client:
+            request = dec_kwargs['request']
+            # NOTE cleaning up the keyword args so the signature is consistent with "func" again
+            dec_kwargs = {k: v for k, v in dec_kwargs.items() if k in parameters_of_decorated_func}
+            with Client(self, request=request) as client:
                 if any(p.name == 'client' for p in inspect.signature(func).parameters.values()):
                     dec_kwargs['client'] = client
                 result = func(*dec_args, **dec_kwargs)
@@ -69,6 +73,9 @@ class page:
             return client.build_response()
 
         parameters = [p for p in inspect.signature(func).parameters.values() if p.name != 'client']
+        # NOTE adding request as a parameter so we can pass it to the client in the decorated function
+        if 'request' not in [p.name for p in parameters]:
+            parameters.append(inspect.Parameter('request', inspect.Parameter.POSITIONAL_OR_KEYWORD, annotation=Request))
         decorated.__signature__ = inspect.Signature(parameters)
 
         globals.page_routes[decorated] = self.path

+ 1 - 1
nicegui/templates/index.html

@@ -78,7 +78,7 @@
         },
         mounted() {
           const query = { client_id: {{ client_id }} };
-          window.socket = io("{{ socket_address }}", { path: "/ws/socket.io", query });
+          window.socket = io("{{ prefix | safe }}/ws/socket.io", query);
           window.socket.on("update", (msg) => {
             Object.entries(msg.elements).forEach(([id, element]) => this.elements[element.id] = element);
           });

+ 2 - 2
nicegui/vue.py

@@ -44,12 +44,12 @@ def generate_js_imports() -> str:
         if name in globals.excludes:
             continue
         for path in js_dependencies[name]:
-            result += f'import "/_vue/dependencies/{path}";\n'
+            result += f'import "_vue/dependencies/{path}";\n'
     for name, path in js_components.items():
         if name in globals.excludes:
             continue
         for path in js_dependencies[name]:
-            result += f'import "/_vue/dependencies/{path}";\n'
+            result += f'import "_vue/dependencies/{path}";\n'
         result += f'import {{ default as {name} }} from "/_vue/components/{name}";\n'
         result += f'app.component("{name}", {name});\n'
     return result