Skip to content

Commit 1fe5acf

Browse files
introduce shared pages
1 parent 850a6c1 commit 1fe5acf

File tree

1 file changed

+15
-1
lines changed

1 file changed

+15
-1
lines changed

nicegui/page.py

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import asyncio
44
import inspect
5+
import weakref
56
from functools import wraps
67
from pathlib import Path
78
from typing import TYPE_CHECKING, Any, Callable
@@ -30,13 +31,15 @@ def __init__(self,
3031
response_timeout: float = 3.0,
3132
reconnect_timeout: float | None = None,
3233
api_router: APIRouter | None = None,
34+
shared: bool = False,
3335
**kwargs: Any,
3436
) -> None:
3537
"""Page
3638
3739
This decorator marks a function to be a page builder.
38-
Each user accessing the given route will see a new instance of the page.
40+
By default, each user accessing the given route will see a new instance of the page.
3941
This means it is private to the user and not shared with others.
42+
If ``shared`` is True, all users will see and interact with the same page instance.
4043
4144
Notes:
4245
@@ -56,6 +59,7 @@ def __init__(self,
5659
:param response_timeout: maximum time for the decorated function to build the page (default: 3.0 seconds)
5760
:param reconnect_timeout: maximum time the server waits for the browser to reconnect (defaults to `reconnect_timeout` argument of `run` command))
5861
:param api_router: APIRouter instance to use, can be left `None` to use the default
62+
:param shared: whether all users should see the same page instance (default: ``False``)
5963
:param kwargs: additional keyword arguments passed to FastAPI's @app.get method
6064
"""
6165
self._path = path
@@ -68,6 +72,8 @@ def __init__(self,
6872
self.kwargs = kwargs
6973
self.api_router = api_router or core.app.router
7074
self.reconnect_timeout = reconnect_timeout
75+
self._shared = shared
76+
self._shared_client: weakref.ref[Client] | None = None
7177

7278
create_favicon_route(self.path, favicon)
7379

@@ -152,7 +158,15 @@ async def decorated(*dec_args, **dec_kwargs) -> Response:
152158
request = dec_kwargs['request']
153159
# NOTE cleaning up the keyword args so the signature is consistent with "func" again
154160
dec_kwargs = {k: v for k, v in dec_kwargs.items() if k in parameters_of_decorated_func}
161+
162+
if self._shared and self._shared_client and (client := self._shared_client()):
163+
client._request = request # pylint: disable=protected-access
164+
binding._refresh_step() # pylint: disable=protected-access
165+
return client.build_response(request)
166+
155167
with Client(self, request=request) as client:
168+
if self._shared:
169+
self._shared_client = weakref.ref(client)
156170
if any(p.name == 'client' for p in inspect.signature(func).parameters.values()):
157171
dec_kwargs['client'] = client
158172
try:

0 commit comments

Comments
 (0)