Skip to content

Commit f21dbdd

Browse files
v1: Move UpdateBehavior methods to ft.context, rename DataView decorator to cache (#5570)
* Refactor auto update control to context API Replaces usage of UpdateBehavior with a new context API for managing auto update state across the codebase. Updates examples, main app logic, and event handling to use ft.context methods. Removes UpdateBehavior from public API and documentation, adds integration tests for auto update behavior, and updates documentation and navigation to reflect the new context API. * Add docstrings and improve type hints in Context class Added detailed docstrings to Context class methods for better clarity and documentation. Improved type hints and assertions, including stricter return type for page property and assertion to ensure context is associated with a page. * Replace data_view decorator with cache decorator Renamed and enhanced the data_view decorator to cache, adding a freeze option for control freezing. Updated imports, __all__, and all usages in tests to use the new cache decorator. * Add type annotations and overloads to cache decorator Introduces ParamSpec and TypeVar for improved type safety in the cache decorator. Adds overloads to the cache function and updates argument and return type annotations for better compatibility with type checkers. * Add context exception test and update autoupdate app Added assertions for ft.context.page in autoupdate.py to ensure context is associated with a page. Renamed test_autoupdate.py to test_context.py and added a test to verify that accessing ft.context.page outside of a Flet app raises an exception. * Refactor Context docs and API exposure Updated documentation for the Context class with usage examples and improved docstrings. Exposed Context in the public API via __init__.py and reorganized mkdocs navigation to move Context under Utility. Minor code reordering for clarity. * Copilot fix: Add docs to UpdateBehavior class Co-authored-by: Copilot <[email protected]> * Delete update_behavior.py * Add context usage examples and update docs Added example scripts for disabling auto update and accessing page via context. Updated documentation to include new examples and improved references to ft.context. Renamed window_width and window_height to web_popup_window_width and web_popup_window_height in Page class for clarity. * Add decorators docs and refactor control decorator Added documentation for 'cache' and 'control' decorators. Updated mkdocs navigation to include new decorator docs. Refactored the 'control' decorator in base_control.py to rename 'cls_or_type_name' to 'dart_widget_name' and improved docstring for clarity. Renamed test functions in test_object_diff_frozen.py for consistency. * Add cache decorator example and improve docs Introduces a basic example for the cache decorator in Flet, updates documentation to include usage and example, and refines the cache decorator implementation with improved comments and docstring. Also fixes a minor docstring typo in base_control.py. * Update control decorator docstring for clarity Improved the docstring for the control decorator by clarifying references to @DataClass and its keyword arguments, and enhancing formatting for better readability. --------- Co-authored-by: Copilot <[email protected]>
1 parent 868e2ad commit f21dbdd

File tree

25 files changed

+464
-143
lines changed

25 files changed

+464
-143
lines changed

sdk/python/examples/apps/controls-gallery/main.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,16 @@
11
import logging
22

3-
import flet as ft
4-
import flet.version
53
from components.gallery_view import GalleryView
64
from gallerydata import GalleryData
75

6+
import flet as ft
7+
import flet.version
8+
89
gallery = GalleryData()
910

1011
logging.basicConfig(level=logging.DEBUG)
1112

12-
# ft.UpdateBehavior.disable_auto_update()
13+
ft.context.disable_auto_update()
1314

1415

1516
def main(page: ft.Page):

sdk/python/examples/apps/counter/counter.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import flet as ft
22

3+
ft.context.disable_auto_update()
4+
35

46
def main(page: ft.Page):
57
page.title = "Flet counter example"

sdk/python/examples/controls/canvas/brush.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ def handle_pan_start(e: ft.DragStartEvent):
2727
state.y = e.local_position.y
2828

2929
async def handle_pan_update(e: ft.DragUpdateEvent):
30-
ft.UpdateBehavior.disable_auto_update()
30+
ft.context.disable_auto_update()
3131
canvas.shapes.append(
3232
cv.Line(
3333
x1=state.x,
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import logging
2+
from dataclasses import dataclass, field
3+
4+
import flet as ft
5+
6+
logging.basicConfig(level=logging.DEBUG)
7+
8+
9+
@dataclass
10+
class AppState:
11+
number: int = 0
12+
items: list[int] = field(default_factory=list)
13+
14+
def __post_init__(self):
15+
for _ in range(10):
16+
self.add_item()
17+
18+
def add_item(self):
19+
self.items.append(self.number)
20+
self.number += 1
21+
22+
23+
@ft.cache
24+
def item_view(i: int):
25+
return ft.Container(
26+
ft.Text(f"Item {i}"),
27+
padding=10,
28+
bgcolor=ft.Colors.AMBER_100,
29+
key=i,
30+
)
31+
32+
33+
def main(page: ft.Page):
34+
state = AppState()
35+
36+
page.floating_action_button = ft.FloatingActionButton(
37+
icon=ft.Icons.ADD, on_click=state.add_item
38+
)
39+
page.add(
40+
ft.ControlBuilder(
41+
state,
42+
lambda state: ft.SafeArea(
43+
ft.Row([item_view(i) for i in state.items], wrap=True)
44+
),
45+
expand=True,
46+
)
47+
)
48+
49+
50+
ft.run(main)
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import flet as ft
2+
3+
4+
def main(page: ft.Page):
5+
def button_click():
6+
ft.context.disable_auto_update()
7+
b.content = "Button clicked!"
8+
# update just the button
9+
b.update()
10+
11+
page.controls.append(ft.Text("This won't appear"))
12+
# no page.update() will be called here
13+
14+
page.controls.append(b := ft.Button("Action!", on_click=button_click))
15+
# page.update() - auto-update is enabled by default
16+
17+
18+
ft.run(main)
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import flet as ft
2+
3+
4+
def main(page: ft.Page):
5+
def button_click(e):
6+
print("Page width:", ft.context.page.width)
7+
8+
page.add(ft.Button("Get page width", on_click=button_click))
9+
10+
11+
ft.run(main)

sdk/python/packages/flet-web/src/flet_web/fastapi/flet_app.py

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,11 @@
1010

1111
import msgpack
1212
from fastapi import WebSocket, WebSocketDisconnect
13+
14+
import flet_web.fastapi as flet_fastapi
1315
from flet.controls.base_control import BaseControl
14-
from flet.controls.context import _context_page
16+
from flet.controls.context import _context_page, context
1517
from flet.controls.exceptions import FletPageDisconnectedException
16-
from flet.controls.update_behavior import UpdateBehavior
1718
from flet.messaging.connection import Connection
1819
from flet.messaging.protocol import (
1920
ClientAction,
@@ -28,8 +29,6 @@
2829
)
2930
from flet.messaging.session import Session
3031
from flet.utils import random_string, sha1
31-
32-
import flet_web.fastapi as flet_fastapi
3332
from flet_web.fastapi.flet_app_manager import app_manager
3433
from flet_web.fastapi.oauth_state import OAuthState
3534
from flet_web.uploads import build_upload_url
@@ -140,24 +139,24 @@ async def __on_session_created(self):
140139
try:
141140
assert self.__main is not None
142141
_context_page.set(self.__session.page)
143-
UpdateBehavior.reset()
142+
context.reset_auto_update()
144143

145144
if asyncio.iscoroutinefunction(self.__main):
146145
await self.__main(self.__session.page)
147146

148147
elif inspect.isasyncgenfunction(self.__main):
149148
async for _ in self.__main(self.__session.page):
150-
if UpdateBehavior.auto_update_enabled():
149+
if context.auto_update_enabled():
151150
await self.__session.auto_update(self.__session.page)
152151

153152
elif inspect.isgeneratorfunction(self.__main):
154153
for _ in self.__main(self.__session.page):
155-
if UpdateBehavior.auto_update_enabled():
154+
if context.auto_update_enabled():
156155
await self.__session.auto_update(self.__session.page)
157156
else:
158157
self.__main(self.__session.page)
159158

160-
if UpdateBehavior.auto_update_enabled():
159+
if context.auto_update_enabled():
161160
await self.__session.auto_update(self.__session.page)
162161
except FletPageDisconnectedException:
163162
logger.debug(

sdk/python/packages/flet/docs/types/aliases.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
::: flet.BorderSideStrokeAlignValue
66
::: flet.BoxShadowValue
77
::: flet.ColorValue
8+
::: flet.context
89
::: flet.ControlEvent
910
::: flet.ControlEventHandler
1011
::: flet.ControlStateValue
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
::: flet.cache
2+
3+
## Examples
4+
5+
### Cached item view
6+
7+
```python
8+
--8<-- "../../examples/controls/decorators/cache/basic.py"
9+
```
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
Manages the context for Flet controls, including page reference
2+
and auto-update behavior.
3+
4+
Context instance is accessed via [`ft.context`][flet.context].
5+
6+
## Examples
7+
8+
### Get page
9+
10+
```python
11+
--8<-- "../../examples/controls/types/context/get_page.py"
12+
```
13+
14+
### Disable auto update
15+
16+
```python
17+
--8<-- "../../examples/controls/types/context/disable_auto_update.py"
18+
```
19+
20+
::: flet.Context

0 commit comments

Comments
 (0)