Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Provide app.storage.client as a location to store volatile data which only matters for the current connection #2820

Merged
merged 29 commits into from
Apr 9, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
db6b065
Implemented app.storage.session which enables the user to store data …
Alyxion Apr 4, 2024
d9403b4
Merge branch 'main' into feature/per_session_data
Alyxion Apr 4, 2024
3fedd36
Replaced Client.state by ObservableDict
Alyxion Apr 5, 2024
8fc9208
Merge branch 'main' into feature/per_session_data
Alyxion Apr 5, 2024
ea8dad5
Renamed app.storage.session to app.storage.client.
Alyxion Apr 6, 2024
e627934
Merge remote-tracking branch 'origin/feature/per_session_data' into f…
Alyxion Apr 6, 2024
df3335a
Merge branch 'main' into feature/per_session_data
Alyxion Apr 6, 2024
9dd4227
Exchanged quotes
Alyxion Apr 6, 2024
ca99fcf
Merge remote-tracking branch 'origin/feature/per_session_data' into f…
Alyxion Apr 6, 2024
08d73bd
Added documentation for app.storage.client
Alyxion Apr 7, 2024
06d6393
Removed imports, simplified client availability check
Alyxion Apr 7, 2024
bb6f44b
Merge branch 'main' into feature/per_session_data
Alyxion Apr 7, 2024
040ebb8
Updated documentation
Alyxion Apr 8, 2024
8013ea0
Merge remote-tracking branch 'origin/feature/per_session_data' into f…
Alyxion Apr 8, 2024
f02d9e9
Removed connection test_clear from
Alyxion Apr 8, 2024
c57a93f
Removed random import, not required for demo anymore
Alyxion Apr 8, 2024
0714c51
Merge remote-tracking branch 'nicegui/main' into feature/per_session_…
Alyxion Apr 8, 2024
ac4ecb1
Resolved merging conflicts with tab extension
Alyxion Apr 8, 2024
edca313
Merge fix
Alyxion Apr 8, 2024
6e85268
Merge fix
Alyxion Apr 8, 2024
bad5cec
minimal updates to documentation
rodja Apr 8, 2024
c01d0d1
code review
falkoschindler Apr 8, 2024
26ba191
Removed line duplication
Alyxion Apr 8, 2024
9ade1f9
improve clearing of client storage
falkoschindler Apr 9, 2024
44f70c7
Merge branch 'feature/per_session_data' of github.com:Alyxion/nicegui…
falkoschindler Apr 9, 2024
6563825
fix typo
falkoschindler Apr 9, 2024
ff58c03
add overview table
falkoschindler Apr 9, 2024
7f856b4
renaming
falkoschindler Apr 9, 2024
0f72368
review documentation
falkoschindler Apr 9, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions nicegui/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ def __init__(self, page: page, *, shared: bool = False) -> None:
self._body_html = ''

self.page = page
self.state = {}
rodja marked this conversation as resolved.
Show resolved Hide resolved

self.connect_handlers: List[Union[Callable[..., Any], Awaitable]] = []
self.disconnect_handlers: List[Union[Callable[..., Any], Awaitable]] = []
Expand All @@ -84,6 +85,12 @@ def is_auto_index_client(self) -> bool:
"""Return True if this client is the auto-index client."""
return self is self.auto_index_client

@staticmethod
def current_client() -> Optional[Client]:
Alyxion marked this conversation as resolved.
Show resolved Hide resolved
"""Returns the current client if obtainable from the current context."""
from .context import get_client
rodja marked this conversation as resolved.
Show resolved Hide resolved
return get_client()

@property
def ip(self) -> Optional[str]:
"""Return the IP address of the client, or None if the client is not connected."""
Expand Down
12 changes: 12 additions & 0 deletions nicegui/storage.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
from starlette.responses import Response

from . import background_tasks, context, core, json, observables
from .context import get_slot_stack
from .logging import log

request_contextvar: contextvars.ContextVar[Optional[Request]] = contextvars.ContextVar('request_var', default=None)
Expand Down Expand Up @@ -149,10 +150,21 @@ def general(self) -> Dict:
"""General storage shared between all users that is persisted on the server (where NiceGUI is executed)."""
return self._general

@property
def session(self) -> Dict:
"""Volatile client storage that is persisted on the server (where NiceGUI is
executed) on a per client/per connection basis.
Note that this kind of storage can only be used in single page applications
rodja marked this conversation as resolved.
Show resolved Hide resolved
where the client connection is preserved between page changes."""
client = context.get_client()
Alyxion marked this conversation as resolved.
Show resolved Hide resolved
return client.state

def clear(self) -> None:
"""Clears all storage."""
self._general.clear()
self._users.clear()
if get_slot_stack():
self.session.clear()
for filepath in self.path.glob('storage-*.json'):
filepath.unlink()

Expand Down
17 changes: 17 additions & 0 deletions tests/test_session_state.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
from nicegui import ui, app
from nicegui.testing import Screen


def test_session_state(screen: Screen):
app.storage.session["counter"] = 123

def increment():
app.storage.session["counter"] = app.storage.session["counter"] + 1

ui.button("Increment").on_click(increment)
ui.label().bind_text(app.storage.session, "counter")

screen.open('/')
screen.should_contain('123')
screen.click('Increment')
screen.wait_for('124')