浏览代码

began with storage documentation
for this to work we need to handle already registered SessionMiddleware

Rodja Trappe 2 年之前
父节点
当前提交
50b8d06176
共有 4 个文件被更改,包括 63 次插入2 次删除
  1. 6 1
      nicegui/run.py
  2. 1 1
      nicegui/storage.py
  3. 2 0
      website/documentation.py
  4. 54 0
      website/more_documentation/storage_documentation.py

+ 6 - 1
nicegui/run.py

@@ -7,6 +7,7 @@ from typing import Any, List, Optional, Tuple
 
 
 import __main__
 import __main__
 import uvicorn
 import uvicorn
+from starlette.middleware import Middleware
 from starlette.middleware.sessions import SessionMiddleware
 from starlette.middleware.sessions import SessionMiddleware
 from uvicorn.main import STARTUP_FAILURE
 from uvicorn.main import STARTUP_FAILURE
 from uvicorn.supervisors import ChangeReload, Multiprocess
 from uvicorn.supervisors import ChangeReload, Multiprocess
@@ -26,7 +27,11 @@ class Server(uvicorn.Server):
         native_module.response_queue = self.config.response_queue
         native_module.response_queue = self.config.response_queue
         if native_module.method_queue is not None:
         if native_module.method_queue is not None:
             globals.app.native.main_window = native_module.WindowProxy()
             globals.app.native.main_window = native_module.WindowProxy()
-        if self.config.storage_secret is not None:
+
+        if any(m.cls == SessionMiddleware for m in globals.app.user_middleware):
+            # NOTE not using "add_middleware" because it would be the wrong order
+            globals.app.user_middleware.append(Middleware(RequestTrackingMiddleware))
+        elif self.config.storage_secret is not None:
             globals.app.add_middleware(RequestTrackingMiddleware)
             globals.app.add_middleware(RequestTrackingMiddleware)
             globals.app.add_middleware(SessionMiddleware, secret_key=self.config.storage_secret)
             globals.app.add_middleware(SessionMiddleware, secret_key=self.config.storage_secret)
         super().run(sockets=sockets)
         super().run(sockets=sockets)

+ 1 - 1
nicegui/storage.py

@@ -95,7 +95,7 @@ class Storage:
         """Small storage that is saved directly within the user's browser (encrypted cookie).
         """Small storage that is saved directly within the user's browser (encrypted cookie).
 
 
         The data is shared between all browser tab and can only be modified before the initial request has been submitted.
         The data is shared between all browser tab and can only be modified before the initial request has been submitted.
-        Normally it is better to use `app.storage.user` instead to reduce payload, improved security and larger storage capacity)."""
+        It is normally better to use `app.storage.user` instead to reduce payload, gain improved security and have larger storage capacity)."""
         request: Request = request_contextvar.get()
         request: Request = request_contextvar.get()
         if request is None:
         if request is None:
             raise RuntimeError('storage.browser needs a storage_secret passed in ui.run()')
             raise RuntimeError('storage.browser needs a storage_secret passed in ui.run()')

+ 2 - 0
website/documentation.py

@@ -413,6 +413,8 @@ def create_full() -> None:
     load_demo(ui.open)
     load_demo(ui.open)
     load_demo(ui.download)
     load_demo(ui.download)
 
 
+    load_demo('storage')
+
     @text_demo('Sessions', '''
     @text_demo('Sessions', '''
         The optional `request` argument provides insights about the client's URL parameters etc.
         The optional `request` argument provides insights about the client's URL parameters etc.
         It also enables you to identify sessions using a [session middleware](https://www.starlette.io/middleware/#sessionmiddleware).
         It also enables you to identify sessions using a [session middleware](https://www.starlette.io/middleware/#sessionmiddleware).

+ 54 - 0
website/more_documentation/storage_documentation.py

@@ -0,0 +1,54 @@
+import logging
+
+from nicegui import ui
+
+from ..documentation_tools import text_demo
+
+
+def main_demo() -> None:
+    """Storage
+    With `app.storage` you can easily persist data.
+    By default there are three types of storage. 
+    `app.storage.user` is a dictionary stored on the server and identified by a generated id in a browser session cookie.
+    That means each user gets their own storage which is shared between all browser tabs.
+    `app.storage.general` is a dictionary stored on the server and shared between all users.
+
+    Lastly `app.storage.browser` is a dictionary directly stored as the browser session cookie and shared between all browser tabs.
+    It is normally better to use `app.storage.user` instead to reduce payload, gain improved security and have larger storage capacity).
+    """
+    from nicegui import app
+
+    # @ui.page('/')
+    # def index():
+    #     app.storage.user['count'] = app.storage.user.get('count', 0) + 1
+    #     with ui.row():
+    #        ui.label('your own page visits:')
+    #        ui.label().bind_text_from(app.storage.user, 'count')
+    #
+    # ui.run(storage_secret='private key to secure the browser session cookie')
+    # END OF DEMO
+    app.storage.user['count'] = app.storage.user.get('count', 0) + 1
+    with ui.row():
+        ui.label('your own page visits:')
+        ui.label().bind_text_from(app.storage.user, 'count')
+
+
+def more() -> None:
+    @text_demo('Counting page visits', '''
+        Here we are using the automatically available browser stored session id to count the number of unique page visits.
+    ''')
+    def page_visits():
+        from collections import Counter
+        from datetime import datetime
+
+        from nicegui import app
+
+        counter = Counter()
+        start = datetime.now().strftime('%H:%M, %d %B %Y')
+
+        @ui.page('/')
+        def index():
+            counter[app.storage.session.browser[id]] += 1
+            ui.label(f'{len(counter)} unique views ({sum(counter.values())} overall) since {start}')
+
+        # ui.run(storage_secret='private key to secure the browser session cookie')