flet 1.0.0.dev2__tar.gz → 1.0.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (334) hide show
  1. {flet-1.0.0.dev2 → flet-1.0.1}/PKG-INFO +14 -13
  2. {flet-1.0.0.dev2 → flet-1.0.1}/README.md +5 -4
  3. {flet-1.0.0.dev2 → flet-1.0.1}/pyproject.toml +9 -9
  4. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/app.py +24 -0
  5. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/base_control.py +23 -8
  6. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/core/icon.py +5 -2
  7. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/core/raw_image.py +7 -1
  8. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/object_patch.py +10 -6
  9. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/page.py +110 -18
  10. flet-1.0.1/src/flet/controls/services/service.py +54 -0
  11. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/messaging/session.py +16 -7
  12. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/testing/flet_test_app.py +14 -7
  13. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/version.py +1 -1
  14. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet.egg-info/PKG-INFO +14 -13
  15. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet.egg-info/SOURCES.txt +2 -0
  16. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet.egg-info/requires.txt +8 -8
  17. flet-1.0.1/tests/test_app_logging.py +53 -0
  18. {flet-1.0.0.dev2 → flet-1.0.1}/tests/test_component_diff.py +93 -0
  19. flet-1.0.1/tests/test_icons.py +105 -0
  20. {flet-1.0.0.dev2 → flet-1.0.1}/tests/test_raw_image_pixels.py +56 -0
  21. flet-1.0.1/tests/test_service_registration.py +705 -0
  22. {flet-1.0.0.dev2 → flet-1.0.1}/tests/test_skip_double_update.py +12 -4
  23. flet-1.0.0.dev2/src/flet/controls/services/service.py +0 -19
  24. flet-1.0.0.dev2/tests/test_icons.py +0 -27
  25. {flet-1.0.0.dev2 → flet-1.0.1}/setup.cfg +0 -0
  26. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/__init__.py +0 -0
  27. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/auth/__init__.py +0 -0
  28. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/auth/authorization.py +0 -0
  29. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/auth/authorization_service.py +0 -0
  30. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/auth/group.py +0 -0
  31. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/auth/oauth_provider.py +0 -0
  32. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/auth/oauth_token.py +0 -0
  33. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/auth/providers/__init__.py +0 -0
  34. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/auth/providers/auth0_oauth_provider.py +0 -0
  35. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/auth/providers/azure_oauth_provider.py +0 -0
  36. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/auth/providers/github_oauth_provider.py +0 -0
  37. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/auth/providers/google_oauth_provider.py +0 -0
  38. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/auth/user.py +0 -0
  39. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/canvas/__init__.py +0 -0
  40. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/cli.py +0 -0
  41. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/components/__init__.py +0 -0
  42. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/components/component.py +0 -0
  43. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/components/component_decorator.py +0 -0
  44. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/components/component_owned.py +0 -0
  45. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/components/hooks/__init__.py +0 -0
  46. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/components/hooks/hook.py +0 -0
  47. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/components/hooks/use_callback.py +0 -0
  48. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/components/hooks/use_context.py +0 -0
  49. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/components/hooks/use_dialog.py +0 -0
  50. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/components/hooks/use_effect.py +0 -0
  51. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/components/hooks/use_memo.py +0 -0
  52. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/components/hooks/use_ref.py +0 -0
  53. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/components/hooks/use_state.py +0 -0
  54. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/components/memo.py +0 -0
  55. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/components/observable.py +0 -0
  56. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/components/public_utils.py +0 -0
  57. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/components/router.py +0 -0
  58. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/components/utils.py +0 -0
  59. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/__init__.py +0 -0
  60. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/action_control.py +0 -0
  61. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/adaptive_control.py +0 -0
  62. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/alignment.py +0 -0
  63. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/animation.py +0 -0
  64. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/base_page.py +0 -0
  65. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/blur.py +0 -0
  66. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/border.py +0 -0
  67. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/border_radius.py +0 -0
  68. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/box.py +0 -0
  69. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/buttons.py +0 -0
  70. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/client_action.py +0 -0
  71. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/colors.py +0 -0
  72. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/context.py +0 -0
  73. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/control.py +0 -0
  74. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/control_event.py +0 -0
  75. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/control_state.py +0 -0
  76. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/core/__init__.py +0 -0
  77. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/core/animated_switcher.py +0 -0
  78. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/core/autofill_group.py +0 -0
  79. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/core/canvas/__init__.py +0 -0
  80. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/core/canvas/arc.py +0 -0
  81. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/core/canvas/canvas.py +0 -0
  82. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/core/canvas/circle.py +0 -0
  83. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/core/canvas/color.py +0 -0
  84. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/core/canvas/fill.py +0 -0
  85. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/core/canvas/image.py +0 -0
  86. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/core/canvas/line.py +0 -0
  87. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/core/canvas/oval.py +0 -0
  88. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/core/canvas/path.py +0 -0
  89. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/core/canvas/points.py +0 -0
  90. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/core/canvas/rect.py +0 -0
  91. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/core/canvas/shadow.py +0 -0
  92. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/core/canvas/shape.py +0 -0
  93. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/core/canvas/text.py +0 -0
  94. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/core/column.py +0 -0
  95. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/core/dismissible.py +0 -0
  96. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/core/drag_target.py +0 -0
  97. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/core/draggable.py +0 -0
  98. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/core/flet_app.py +0 -0
  99. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/core/gesture_detector.py +0 -0
  100. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/core/grid_view.py +0 -0
  101. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/core/hero.py +0 -0
  102. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/core/image.py +0 -0
  103. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/core/interactive_viewer.py +0 -0
  104. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/core/keyboard_listener.py +0 -0
  105. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/core/list_view.py +0 -0
  106. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/core/markdown.py +0 -0
  107. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/core/merge_semantics.py +0 -0
  108. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/core/page_view.py +0 -0
  109. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/core/pagelet.py +0 -0
  110. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/core/placeholder.py +0 -0
  111. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/core/reorderable_drag_handle.py +0 -0
  112. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/core/responsive_row.py +0 -0
  113. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/core/rotated_box.py +0 -0
  114. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/core/row.py +0 -0
  115. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/core/safe_area.py +0 -0
  116. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/core/screenshot.py +0 -0
  117. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/core/semantics.py +0 -0
  118. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/core/shader_mask.py +0 -0
  119. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/core/shimmer.py +0 -0
  120. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/core/stack.py +0 -0
  121. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/core/text.py +0 -0
  122. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/core/text_span.py +0 -0
  123. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/core/transparent_pointer.py +0 -0
  124. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/core/view.py +0 -0
  125. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/core/window.py +0 -0
  126. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/core/window_drag_area.py +0 -0
  127. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/cupertino/__init__.py +0 -0
  128. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/cupertino/cupertino_action_sheet.py +0 -0
  129. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/cupertino/cupertino_action_sheet_action.py +0 -0
  130. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/cupertino/cupertino_activity_indicator.py +0 -0
  131. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/cupertino/cupertino_alert_dialog.py +0 -0
  132. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/cupertino/cupertino_app_bar.py +0 -0
  133. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/cupertino/cupertino_bottom_sheet.py +0 -0
  134. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/cupertino/cupertino_button.py +0 -0
  135. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/cupertino/cupertino_checkbox.py +0 -0
  136. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/cupertino/cupertino_colors.py +0 -0
  137. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/cupertino/cupertino_context_menu.py +0 -0
  138. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/cupertino/cupertino_context_menu_action.py +0 -0
  139. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/cupertino/cupertino_date_picker.py +0 -0
  140. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/cupertino/cupertino_dialog_action.py +0 -0
  141. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/cupertino/cupertino_filled_button.py +0 -0
  142. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/cupertino/cupertino_icons.json +0 -0
  143. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/cupertino/cupertino_icons.py +0 -0
  144. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/cupertino/cupertino_icons.pyi +0 -0
  145. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/cupertino/cupertino_list_tile.py +0 -0
  146. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/cupertino/cupertino_navigation_bar.py +0 -0
  147. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/cupertino/cupertino_picker.py +0 -0
  148. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/cupertino/cupertino_radio.py +0 -0
  149. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/cupertino/cupertino_segmented_button.py +0 -0
  150. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/cupertino/cupertino_slider.py +0 -0
  151. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/cupertino/cupertino_sliding_segmented_button.py +0 -0
  152. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/cupertino/cupertino_switch.py +0 -0
  153. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/cupertino/cupertino_textfield.py +0 -0
  154. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/cupertino/cupertino_timer_picker.py +0 -0
  155. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/cupertino/cupertino_tinted_button.py +0 -0
  156. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/device_info.py +0 -0
  157. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/dialog_control.py +0 -0
  158. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/duration.py +0 -0
  159. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/embed_json_encoder.py +0 -0
  160. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/events.py +0 -0
  161. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/exceptions.py +0 -0
  162. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/geometry.py +0 -0
  163. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/gradients.py +0 -0
  164. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/icon_data.py +0 -0
  165. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/id_counter.py +0 -0
  166. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/keys.py +0 -0
  167. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/layout_control.py +0 -0
  168. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/margin.py +0 -0
  169. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/material/__init__.py +0 -0
  170. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/material/alert_dialog.py +0 -0
  171. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/material/app_bar.py +0 -0
  172. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/material/auto_complete.py +0 -0
  173. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/material/badge.py +0 -0
  174. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/material/banner.py +0 -0
  175. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/material/bottom_app_bar.py +0 -0
  176. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/material/bottom_sheet.py +0 -0
  177. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/material/button.py +0 -0
  178. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/material/card.py +0 -0
  179. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/material/checkbox.py +0 -0
  180. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/material/chip.py +0 -0
  181. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/material/circle_avatar.py +0 -0
  182. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/material/container.py +0 -0
  183. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/material/context_menu.py +0 -0
  184. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/material/datatable.py +0 -0
  185. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/material/date_picker.py +0 -0
  186. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/material/date_range_picker.py +0 -0
  187. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/material/divider.py +0 -0
  188. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/material/dropdown.py +0 -0
  189. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/material/dropdownm2.py +0 -0
  190. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/material/expansion_panel.py +0 -0
  191. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/material/expansion_tile.py +0 -0
  192. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/material/filled_button.py +0 -0
  193. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/material/filled_tonal_button.py +0 -0
  194. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/material/floating_action_button.py +0 -0
  195. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/material/form_field_control.py +0 -0
  196. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/material/icon_button.py +0 -0
  197. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/material/icons.json +0 -0
  198. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/material/icons.py +0 -0
  199. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/material/icons.pyi +0 -0
  200. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/material/list_tile.py +0 -0
  201. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/material/menu_bar.py +0 -0
  202. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/material/menu_item_button.py +0 -0
  203. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/material/navigation_bar.py +0 -0
  204. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/material/navigation_drawer.py +0 -0
  205. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/material/navigation_rail.py +0 -0
  206. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/material/outlined_button.py +0 -0
  207. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/material/popup_menu_button.py +0 -0
  208. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/material/progress_bar.py +0 -0
  209. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/material/progress_ring.py +0 -0
  210. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/material/radio.py +0 -0
  211. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/material/radio_group.py +0 -0
  212. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/material/range_slider.py +0 -0
  213. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/material/reorderable_list_view.py +0 -0
  214. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/material/search_bar.py +0 -0
  215. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/material/segmented_button.py +0 -0
  216. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/material/selection_area.py +0 -0
  217. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/material/slider.py +0 -0
  218. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/material/snack_bar.py +0 -0
  219. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/material/submenu_button.py +0 -0
  220. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/material/switch.py +0 -0
  221. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/material/tabs.py +0 -0
  222. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/material/text_button.py +0 -0
  223. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/material/textfield.py +0 -0
  224. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/material/time_picker.py +0 -0
  225. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/material/tooltip.py +0 -0
  226. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/material/vertical_divider.py +0 -0
  227. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/multi_view.py +0 -0
  228. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/padding.py +0 -0
  229. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/painting.py +0 -0
  230. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/query_string.py +0 -0
  231. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/ref.py +0 -0
  232. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/scrollable_control.py +0 -0
  233. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/services/__init__.py +0 -0
  234. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/services/accelerometer.py +0 -0
  235. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/services/barometer.py +0 -0
  236. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/services/battery.py +0 -0
  237. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/services/browser_context_menu.py +0 -0
  238. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/services/clipboard.py +0 -0
  239. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/services/connectivity.py +0 -0
  240. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/services/file_picker.py +0 -0
  241. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/services/gyroscope.py +0 -0
  242. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/services/haptic_feedback.py +0 -0
  243. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/services/magnetometer.py +0 -0
  244. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/services/screen_brightness.py +0 -0
  245. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/services/semantics_service.py +0 -0
  246. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/services/sensor_error_event.py +0 -0
  247. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/services/shake_detector.py +0 -0
  248. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/services/share.py +0 -0
  249. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/services/shared_preferences.py +0 -0
  250. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/services/storage_paths.py +0 -0
  251. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/services/url_launcher.py +0 -0
  252. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/services/user_accelerometer.py +0 -0
  253. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/services/wakelock.py +0 -0
  254. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/template_route.py +0 -0
  255. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/text_style.py +0 -0
  256. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/theme.py +0 -0
  257. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/transform.py +0 -0
  258. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/types.py +0 -0
  259. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/controls/value_types.py +0 -0
  260. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/data_channel.py +0 -0
  261. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/fastapi/__init__.py +0 -0
  262. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/messaging/connection.py +0 -0
  263. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/messaging/flet_dart_bridge_server.py +0 -0
  264. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/messaging/flet_socket_server.py +0 -0
  265. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/messaging/protocol.py +0 -0
  266. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/messaging/pyodide_connection.py +0 -0
  267. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/messaging/session_store.py +0 -0
  268. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/pubsub/__init__.py +0 -0
  269. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/pubsub/pubsub_client.py +0 -0
  270. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/pubsub/pubsub_hub.py +0 -0
  271. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/py.typed +0 -0
  272. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/pytest_plugin.py +0 -0
  273. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/security/__init__.py +0 -0
  274. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/testing/__init__.py +0 -0
  275. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/testing/finder.py +0 -0
  276. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/testing/remote_tester.py +0 -0
  277. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/testing/tester.py +0 -0
  278. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/utils/__init__.py +0 -0
  279. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/utils/browser.py +0 -0
  280. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/utils/classproperty.py +0 -0
  281. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/utils/deprecated.py +0 -0
  282. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/utils/deprecated_enum.py +0 -0
  283. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/utils/environment.py +0 -0
  284. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/utils/files.py +0 -0
  285. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/utils/from_dict.py +0 -0
  286. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/utils/griffe_deprecations.py +0 -0
  287. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/utils/hashing.py +0 -0
  288. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/utils/json_utils.py +0 -0
  289. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/utils/locks.py +0 -0
  290. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/utils/network.py +0 -0
  291. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/utils/object_model.py +0 -0
  292. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/utils/once.py +0 -0
  293. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/utils/pip.py +0 -0
  294. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/utils/platform_utils.py +0 -0
  295. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/utils/slugify.py +0 -0
  296. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/utils/strings.py +0 -0
  297. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/utils/typing_utils.py +0 -0
  298. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/utils/validation.py +0 -0
  299. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet/utils/vector.py +0 -0
  300. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet.egg-info/dependency_links.txt +0 -0
  301. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet.egg-info/entry_points.txt +0 -0
  302. {flet-1.0.0.dev2 → flet-1.0.1}/src/flet.egg-info/top_level.txt +0 -0
  303. {flet-1.0.0.dev2 → flet-1.0.1}/tests/test_assets_dir_resolution.py +0 -0
  304. {flet-1.0.0.dev2 → flet-1.0.1}/tests/test_auth_lazy_imports.py +0 -0
  305. {flet-1.0.0.dev2 → flet-1.0.1}/tests/test_base_control.py +0 -0
  306. {flet-1.0.0.dev2 → flet-1.0.1}/tests/test_client_actions.py +0 -0
  307. {flet-1.0.0.dev2 → flet-1.0.1}/tests/test_colors.py +0 -0
  308. {flet-1.0.0.dev2 → flet-1.0.1}/tests/test_component_effects.py +0 -0
  309. {flet-1.0.0.dev2 → flet-1.0.1}/tests/test_component_owned_identity.py +0 -0
  310. {flet-1.0.0.dev2 → flet-1.0.1}/tests/test_component_renderer.py +0 -0
  311. {flet-1.0.0.dev2 → flet-1.0.1}/tests/test_context_auto_update.py +0 -0
  312. {flet-1.0.0.dev2 → flet-1.0.1}/tests/test_dataclasses.py +0 -0
  313. {flet-1.0.0.dev2 → flet-1.0.1}/tests/test_datetime.py +0 -0
  314. {flet-1.0.0.dev2 → flet-1.0.1}/tests/test_deprecated.py +0 -0
  315. {flet-1.0.0.dev2 → flet-1.0.1}/tests/test_environment.py +0 -0
  316. {flet-1.0.0.dev2 → flet-1.0.1}/tests/test_events.py +0 -0
  317. {flet-1.0.0.dev2 → flet-1.0.1}/tests/test_files.py +0 -0
  318. {flet-1.0.0.dev2 → flet-1.0.1}/tests/test_from_dict.py +0 -0
  319. {flet-1.0.0.dev2 → flet-1.0.1}/tests/test_generator_handler_yield.py +0 -0
  320. {flet-1.0.0.dev2 → flet-1.0.1}/tests/test_griffe_deprecations.py +0 -0
  321. {flet-1.0.0.dev2 → flet-1.0.1}/tests/test_object_diff_frozen.py +0 -0
  322. {flet-1.0.0.dev2 → flet-1.0.1}/tests/test_object_diff_in_place.py +0 -0
  323. {flet-1.0.0.dev2 → flet-1.0.1}/tests/test_object_diff_memory_churn.py +0 -0
  324. {flet-1.0.0.dev2 → flet-1.0.1}/tests/test_object_diff_performance.py +0 -0
  325. {flet-1.0.0.dev2 → flet-1.0.1}/tests/test_observable.py +0 -0
  326. {flet-1.0.0.dev2 → flet-1.0.1}/tests/test_patch_dataclass.py +0 -0
  327. {flet-1.0.0.dev2 → flet-1.0.1}/tests/test_router_modal.py +0 -0
  328. {flet-1.0.0.dev2 → flet-1.0.1}/tests/test_router_pop.py +0 -0
  329. {flet-1.0.0.dev2 → flet-1.0.1}/tests/test_router_recursive.py +0 -0
  330. {flet-1.0.0.dev2 → flet-1.0.1}/tests/test_session_disconnect_buffering.py +0 -0
  331. {flet-1.0.0.dev2 → flet-1.0.1}/tests/test_use_dialog.py +0 -0
  332. {flet-1.0.0.dev2 → flet-1.0.1}/tests/test_validation.py +0 -0
  333. {flet-1.0.0.dev2 → flet-1.0.1}/tests/test_validation_benchmark.py +0 -0
  334. {flet-1.0.0.dev2 → flet-1.0.1}/tests/test_version.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: flet
3
- Version: 1.0.0.dev2
3
+ Version: 1.0.1
4
4
  Summary: Flet for Python - easily build interactive multi-platform apps in Python
5
5
  Author-email: "Appveyor Systems Inc." <hello@flet.dev>
6
6
  License-Expression: Apache-2.0
@@ -9,23 +9,23 @@ Project-URL: Repository, https://github.com/flet-dev/flet
9
9
  Project-URL: Documentation, https://flet.dev/docs/
10
10
  Requires-Python: >=3.10
11
11
  Description-Content-Type: text/markdown
12
- Requires-Dist: flet-cli==1.0.0.dev2; extra == "cli"
13
- Requires-Dist: flet-web==1.0.0.dev2; extra == "web"
12
+ Requires-Dist: flet-cli==1.0.1; extra == "cli"
13
+ Requires-Dist: flet-web==1.0.1; extra == "web"
14
14
  Requires-Dist: oauthlib>=3.2.2; platform_system != "Emscripten"
15
15
  Requires-Dist: httpx>=0.28.1; platform_system != "Emscripten"
16
16
  Requires-Dist: repath>=0.9.0
17
17
  Requires-Dist: msgpack>=1.1.0
18
18
  Requires-Dist: typing-extensions; python_version < "3.11"
19
19
  Provides-Extra: all
20
- Requires-Dist: flet-cli==1.0.0.dev2; extra == "all"
21
- Requires-Dist: flet-web==1.0.0.dev2; extra == "all"
22
- Requires-Dist: flet-desktop==1.0.0.dev2; extra == "all"
20
+ Requires-Dist: flet-cli==1.0.1; extra == "all"
21
+ Requires-Dist: flet-web==1.0.1; extra == "all"
22
+ Requires-Dist: flet-desktop==1.0.1; extra == "all"
23
23
  Provides-Extra: cli
24
- Requires-Dist: flet-cli==1.0.0.dev2; extra == "cli"
24
+ Requires-Dist: flet-cli==1.0.1; extra == "cli"
25
25
  Provides-Extra: desktop
26
- Requires-Dist: flet-desktop==1.0.0.dev2; extra == "desktop"
26
+ Requires-Dist: flet-desktop==1.0.1; extra == "desktop"
27
27
  Provides-Extra: web
28
- Requires-Dist: flet-web==1.0.0.dev2; extra == "web"
28
+ Requires-Dist: flet-web==1.0.1; extra == "web"
29
29
  Provides-Extra: test
30
30
  Requires-Dist: pytest>=7.2.0; extra == "test"
31
31
  Requires-Dist: pytest-asyncio>=1.1.0; extra == "test"
@@ -41,7 +41,7 @@ Requires-Dist: scikit-image>=0.25.2; extra == "test"
41
41
  </p>
42
42
 
43
43
  <p align="center">
44
- <em>Build multi-platform apps in Python. No frontend experience required.</em>
44
+ <em>Build cross-platform apps in Python. No frontend experience required.</em>
45
45
  </p>
46
46
 
47
47
  <p align="center">
@@ -59,10 +59,11 @@ Requires-Dist: scikit-image>=0.25.2; extra == "test"
59
59
  <img src="https://flet.dev/docs/assets/badges/docs-coverage/flet.svg" alt="Docstring coverage" /></a>
60
60
  </p>
61
61
 
62
- ---
62
+ Flet is a Python framework for building web, desktop, and mobile apps without prior experience in frontend development.
63
63
 
64
- Flet is a framework that allows building mobile, desktop and web applications
65
- in Python only without prior experience in frontend development.
64
+ > **[Try Flet online in Flet Studio](https://studio.flet.dev)**
65
+ >
66
+ > Create, run, and share Python apps in your browser. Start from an example, write your own code, or get help from the AI agent. No installation required.
66
67
 
67
68
  ### <img src="https://flet.dev/img/pages/home/single-code-base.svg" width="25" align="top" />&nbsp;&nbsp;&nbsp;Single code base for any device
68
69
 
@@ -6,7 +6,7 @@
6
6
  </p>
7
7
 
8
8
  <p align="center">
9
- <em>Build multi-platform apps in Python. No frontend experience required.</em>
9
+ <em>Build cross-platform apps in Python. No frontend experience required.</em>
10
10
  </p>
11
11
 
12
12
  <p align="center">
@@ -24,10 +24,11 @@
24
24
  <img src="https://flet.dev/docs/assets/badges/docs-coverage/flet.svg" alt="Docstring coverage" /></a>
25
25
  </p>
26
26
 
27
- ---
27
+ Flet is a Python framework for building web, desktop, and mobile apps without prior experience in frontend development.
28
28
 
29
- Flet is a framework that allows building mobile, desktop and web applications
30
- in Python only without prior experience in frontend development.
29
+ > **[Try Flet online in Flet Studio](https://studio.flet.dev)**
30
+ >
31
+ > Create, run, and share Python apps in your browser. Start from an example, write your own code, or get help from the AI agent. No installation required.
31
32
 
32
33
  ### <img src="https://flet.dev/img/pages/home/single-code-base.svg" width="25" align="top" />&nbsp;&nbsp;&nbsp;Single code base for any device
33
34
 
@@ -1,14 +1,14 @@
1
1
  [project]
2
2
  name = "flet"
3
- version = "1.0.0.dev2"
3
+ version = "1.0.1"
4
4
  description = "Flet for Python - easily build interactive multi-platform apps in Python"
5
5
  authors = [{name = "Appveyor Systems Inc.", email = "hello@flet.dev"}]
6
6
  license = "Apache-2.0"
7
7
  readme = "README.md"
8
8
  requires-python = ">=3.10"
9
9
  dependencies = [
10
- "flet-cli==1.0.0.dev2; extra == 'cli'",
11
- "flet-web==1.0.0.dev2; extra == 'web'",
10
+ "flet-cli==1.0.1; extra == 'cli'",
11
+ "flet-web==1.0.1; extra == 'web'",
12
12
  "oauthlib >=3.2.2; platform_system != 'Emscripten'",
13
13
  "httpx >=0.28.1; platform_system != 'Emscripten'",
14
14
  "repath >=0.9.0",
@@ -23,15 +23,15 @@ Documentation = "https://flet.dev/docs/"
23
23
 
24
24
  [project.optional-dependencies]
25
25
  all = [
26
- "flet-cli==1.0.0.dev2",
27
- "flet-web==1.0.0.dev2",
28
- "flet-desktop==1.0.0.dev2",
26
+ "flet-cli==1.0.1",
27
+ "flet-web==1.0.1",
28
+ "flet-desktop==1.0.1",
29
29
  ]
30
- cli = ["flet-cli==1.0.0.dev2"]
30
+ cli = ["flet-cli==1.0.1"]
31
31
  desktop = [
32
- "flet-desktop==1.0.0.dev2",
32
+ "flet-desktop==1.0.1",
33
33
  ]
34
- web = ["flet-web==1.0.0.dev2"]
34
+ web = ["flet-web==1.0.1"]
35
35
  # Dependencies needed to run integration tests written with `flet.testing`
36
36
  # (the `flet test` command / the pytest plugin). Pillow/numpy/scikit-image
37
37
  # back screenshot and GIF comparison.
@@ -45,6 +45,26 @@ Used for both `main` and `before_main` handlers.
45
45
  """
46
46
 
47
47
 
48
+ def __configure_logging_from_env() -> None:
49
+ """
50
+ Applies the log level named by the `FLET_LOG_LEVEL` environment variable.
51
+
52
+ `flet run -v` sets this so the framework's own logging reaches the console
53
+ without the app having to configure it. `basicConfig` does nothing once the
54
+ root logger has a handler, so an app that configures logging itself keeps
55
+ the setup it chose.
56
+ """
57
+ level = os.getenv("FLET_LOG_LEVEL")
58
+ if not level:
59
+ return
60
+
61
+ resolved = logging.getLevelName(level.strip().upper())
62
+ if isinstance(resolved, int):
63
+ logging.basicConfig(level=resolved)
64
+ else:
65
+ logger.warning("Unknown FLET_LOG_LEVEL: %s", level)
66
+
67
+
48
68
  def run(
49
69
  main: AppCallable,
50
70
  before_main: Optional[AppCallable] = None,
@@ -83,6 +103,8 @@ def run(
83
103
  A FastAPI ASGI app when `export_asgi_app=True`.
84
104
  Otherwise, runs the app and returns `None`.
85
105
  """
106
+ __configure_logging_from_env()
107
+
86
108
  if is_pyodide():
87
109
  __run_pyodide(main=main, before_main=before_main)
88
110
  return
@@ -156,6 +178,8 @@ async def run_async(
156
178
  no_cdn: Whether to avoid loading CanvasKit, Pyodide, and fonts from CDN.
157
179
  """
158
180
 
181
+ __configure_logging_from_env()
182
+
159
183
  if is_pyodide():
160
184
  __run_pyodide(main=main, before_main=before_main)
161
185
  return
@@ -328,6 +328,9 @@ class BaseControl:
328
328
 
329
329
  Override this hook to perform lightweight setup that depends on initialized
330
330
  fields. Do not call `update()` here.
331
+
332
+ See :class:`~flet.Service` for service registration timing and page access
333
+ during this hook.
331
334
  """
332
335
  pass
333
336
 
@@ -395,22 +398,34 @@ class BaseControl:
395
398
 
396
399
  def get_data_channel(self, channel_id: int):
397
400
  """
398
- Resolve the [DataChannel] allocated on the Dart side for this
399
- widget. Pattern:
401
+ Resolve the :class:`~flet.DataChannel` allocated on the Dart side for this
402
+ control or service.
403
+
404
+ Example:
405
+ A custom service whose Dart implementation opens a data channel and
406
+ raises `data_channel_open` can capture it during initialization:
407
+
408
+ ```python
409
+ import flet as ft
400
410
 
401
- on_data_channel_open: Optional[ft.EventHandler[DataChannelOpenEvent]] = None
402
411
 
403
- def init(self):
404
- self.on_data_channel_open = self._on_open
412
+ @ft.control("MyService")
413
+ class MyService(ft.Service):
414
+ on_data_channel_open: ft.EventHandler[ft.DataChannelOpenEvent] | None = None
405
415
 
406
- def _on_open(self, e):
407
- self._channel = self.get_data_channel(e.channel_id)
416
+ def init(self):
417
+ super().init()
418
+ self.on_data_channel_open = self._on_open
419
+
420
+ def _on_open(self, e: ft.DataChannelOpenEvent):
421
+ self._channel = self.get_data_channel(e.channel_id)
422
+ ```
408
423
 
409
424
  Idempotent — the underlying Connection caches DataChannels by id,
410
425
  so repeated calls return the same instance. No error path: the id
411
426
  always comes from a framework-fired event, so by the time this
412
427
  runs the channel exists on both sides.
413
- """
428
+ """ # noqa: E501
414
429
  return self.page.session.connection.data_channel_for(channel_id)
415
430
 
416
431
  # public methods
@@ -27,8 +27,11 @@ class Icon(LayoutControl):
27
27
  """
28
28
  The icon to display, selected from a predefined icon set.
29
29
 
30
- You can explore available icons using the
31
- [Flet Icons Browser](https://studio.flet.dev/gallery/run/apps/icons_browser/).
30
+ Browse every available icon on the
31
+ [Icons](https://flet.dev/docs/types/icons) and
32
+ [CupertinoIcons](https://flet.dev/docs/types/cupertinoicons) pages, or run the
33
+ [icons browser](https://studio.flet.dev/gallery/run/apps/icons_browser/) as a
34
+ live Flet app.
32
35
  """
33
36
 
34
37
  color: Optional[ColorValue] = None
@@ -154,7 +154,13 @@ class RawImage(LayoutControl):
154
154
  def _capture_channel(self, e: DataChannelOpenEvent) -> None:
155
155
  # Single-channel widget; no need to dispatch on e.channel_name.
156
156
  self._channel = self.get_data_channel(e.channel_id)
157
- self._channel.on_bytes(self._on_dart_message)
157
+ loop = asyncio.get_running_loop()
158
+ # Embedded DataChannel callbacks arrive on a native bridge thread.
159
+ # Resolve acknowledgements on the event loop so Future callbacks wake
160
+ # the renderer immediately and the pending-ack queue stays on one thread.
161
+ self._channel.on_bytes(
162
+ lambda payload: loop.call_soon_threadsafe(self._on_dart_message, payload)
163
+ )
158
164
  # Acks pending on a previous channel will never arrive; resolve
159
165
  # them so old `render` awaits return instead of hanging.
160
166
  while self._pending_acks:
@@ -1015,12 +1015,8 @@ class DiffBuilder:
1015
1015
  new_item, "fn", None
1016
1016
  )
1017
1017
 
1018
- if (not frozen_local and old_item is new_item) or (
1019
- frozen_local
1020
- and old_item is not new_item
1021
- and same_type
1022
- and same_component_fn
1023
- and _keys_match()
1018
+ if old_item is new_item or (
1019
+ frozen_local and same_type and same_component_fn and _keys_match()
1024
1020
  ):
1025
1021
  self._compare_dataclasses(
1026
1022
  parent, _path_join(path, idx), old_item, new_item, frozen_local
@@ -1138,6 +1134,14 @@ class DiffBuilder:
1138
1134
  """
1139
1135
  logger.debug("\n_compare_dataclasses: %s\n\n%s\n%s\n", path, src, dst)
1140
1136
 
1137
+ if frozen and src is dst:
1138
+ # Retained immutable children have no new description to reconcile.
1139
+ # In particular, a Component must not migrate state to itself or
1140
+ # render over its old body before that body can be diffed.
1141
+ if parent is not None and parent is not dst:
1142
+ dst._parent = weakref.ref(parent)
1143
+ return
1144
+
1141
1145
  if (
1142
1146
  self.control_cls
1143
1147
  and isinstance(parent, self.control_cls)
@@ -6,12 +6,13 @@ import threading
6
6
  import weakref
7
7
  from collections.abc import Awaitable, Coroutine
8
8
  from concurrent.futures import CancelledError, Future, ThreadPoolExecutor
9
- from dataclasses import InitVar, dataclass, field
9
+ from dataclasses import InitVar, dataclass, field, fields, is_dataclass
10
10
  from functools import partial
11
11
  from typing import (
12
12
  TYPE_CHECKING,
13
13
  Any,
14
14
  Callable,
15
+ ClassVar,
15
16
  Optional,
16
17
  ParamSpec,
17
18
  TypeVar,
@@ -103,28 +104,31 @@ class ServiceRegistry(Service):
103
104
  Tracked service instances currently attached to this page.
104
105
  """
105
106
 
107
+ _auto_register: ClassVar[bool] = False
108
+ """
109
+ Disabled so each registry belongs only to its own page. An embedded `FletApp`
110
+ can construct a page while the host page is the current context; automatic
111
+ registration would incorrectly add the new registry to the host's services.
112
+ The client has no service binding for type "ServiceRegistry".
113
+ """
114
+
106
115
  def __post_init__(self, ref: Optional[Ref[Any]]):
107
116
  super().__post_init__(ref)
108
117
  self._internals["uid"] = random_string(10)
109
118
  self._lock: threading.Lock = threading.Lock()
110
119
 
111
- def init(self):
112
- # Deliberately skips Service.init(), which registers the instance into
113
- # `context.page._services`. A registry is the *container* for services,
114
- # not a service itself, and self-registering leaks across pages: when a
115
- # second Page is constructed while another page is still the current
116
- # context — an embedded `FletApp` inside a host app — the new page's
117
- # registry is registered inside the HOST's registry. The client has no
118
- # service binding for type "ServiceRegistry", so building it throws
119
- # "Unknown service" inside the host's service loop, and every service
120
- # registered after it is never built: invoking one then fails with
121
- # "Timeout waiting for invoke method listener".
122
- BaseControl.init(self)
123
-
124
120
  def register_service(self, service: Service):
125
121
  """
126
122
  Registers a service in this registry and pushes an update.
127
123
 
124
+ If the page hasn't been sent to the client yet, the service is only added
125
+ to the registry and goes out with the page.
126
+
127
+ If the update fails before sending, remove the service and restore the
128
+ subtree's update tracking before re-raising. A failure after sending, such
129
+ as a `did_mount()` exception, leaves the service registered so later patches
130
+ account for the addition already sent.
131
+
128
132
  Args:
129
133
  service: Service instance to register.
130
134
  """
@@ -133,7 +137,93 @@ class ServiceRegistry(Service):
133
137
  f"Registering service {service._c}({service._i}) to registry {self._i}"
134
138
  )
135
139
  self._services.append(service)
136
- self.__internal_update()
140
+ if self.parent is None:
141
+ return
142
+ restore = self.__snapshot_update_state()
143
+ try:
144
+ self.__internal_update()
145
+ except BaseException:
146
+ if not self.__was_sent(service):
147
+ for i in range(len(self._services) - 1, -1, -1):
148
+ if self._services[i] is service:
149
+ del self._services[i]
150
+ break
151
+ restore()
152
+ raise
153
+
154
+ def __snapshot_update_state(self) -> Callable[[], None]:
155
+ """Save diff bookkeeping without copying controls or application state.
156
+
157
+ Both current fields and previous snapshots can contain controls: a child
158
+ pending removal is only reachable through the previous snapshot. Restore
159
+ missing attributes too, since configuring new children attaches parents
160
+ and creates snapshots before serialization can fail.
161
+ """
162
+ attributes = (
163
+ "_dirty",
164
+ "__changes",
165
+ "__prev_lists",
166
+ "__prev_dicts",
167
+ "__prev_classes",
168
+ "_parent",
169
+ "_initialized",
170
+ "_frozen",
171
+ )
172
+ saved = []
173
+ visited = set()
174
+
175
+ def capture(value):
176
+ if id(value) in visited:
177
+ return
178
+ visited.add(id(value))
179
+ if is_dataclass(value) and not isinstance(value, type):
180
+ state = {}
181
+ for name in attributes:
182
+ if not hasattr(value, name):
183
+ continue
184
+ attr = getattr(value, name)
185
+ if isinstance(attr, dict):
186
+ attr = attr.copy()
187
+ if name in ("__prev_lists", "__prev_dicts"):
188
+ attr = {k: v.copy() for k, v in attr.items()}
189
+ state[name] = attr
190
+ saved.append((value, state))
191
+ for name in ("__prev_lists", "__prev_dicts", "__prev_classes"):
192
+ capture(state.get(name))
193
+ for f in fields(value):
194
+ if not f.metadata.get("skip", False):
195
+ capture(getattr(value, f.name))
196
+ elif isinstance(value, dict):
197
+ for item in value.values():
198
+ capture(item)
199
+ elif isinstance(value, (list, tuple)):
200
+ for item in value:
201
+ capture(item)
202
+
203
+ capture(self)
204
+
205
+ def restore():
206
+ for value, state in saved:
207
+ for name in attributes:
208
+ if name in state:
209
+ object.__setattr__(value, name, state[name])
210
+ elif hasattr(value, name):
211
+ object.__delattr__(value, name)
212
+
213
+ return restore
214
+
215
+ def __was_sent(self, service: Service) -> bool:
216
+ """
217
+ Returns whether the patch adding `service` was sent to the client.
218
+
219
+ The session indexes all additions after submitting the patch to the
220
+ connection, before calling `did_mount()`. This remains true if another
221
+ control's `did_mount()` raises; it does not confirm delivery to the client.
222
+ """
223
+ try:
224
+ return self.page.session.index.get(service._i) is service
225
+ except RuntimeError:
226
+ return False
137
227
 
138
228
  def unregister_services(self):
139
229
  """
@@ -165,9 +255,11 @@ class ServiceRegistry(Service):
165
255
  based solely on whether the user called `.update()` themselves.
166
256
  """
167
257
  was_called = context.was_update_called()
168
- self.update()
169
- if not was_called:
170
- context.reset_update_called()
258
+ try:
259
+ self.update()
260
+ finally:
261
+ if not was_called:
262
+ context.reset_update_called()
171
263
 
172
264
 
173
265
  @dataclass
@@ -0,0 +1,54 @@
1
+ from dataclasses import dataclass
2
+ from typing import Any, ClassVar, Optional
3
+
4
+ from flet.controls.base_control import BaseControl
5
+ from flet.controls.context import context
6
+ from flet.controls.ref import Ref
7
+
8
+ __all__ = ["Service"]
9
+
10
+
11
+ @dataclass(kw_only=True)
12
+ class Service(BaseControl):
13
+ """
14
+ Base class for user services.
15
+
16
+ By default, construction registers the service with the current page after
17
+ `init()` returns, whether or not the override calls `super().init()`. Set client
18
+ properties and event handlers in `init()` so they are included in registration
19
+ and available when the Dart service initializes. Without a current page context,
20
+ the service is constructed but not registered.
21
+
22
+ Note:
23
+ Inside `init()`, the service isn't attached to the page yet: `self.page`
24
+ and `self.update()` raise. Use `ft.context.page` to access the current page.
25
+
26
+ Declared fields participate in serialization unless excluded with
27
+ `metadata={"skip": True}`; a leading underscore does not exclude a field.
28
+ Keep Python-only state, such as clients or handles, in excluded fields or
29
+ attributes assigned in `init()` without declaring them as fields.
30
+ """
31
+
32
+ _auto_register: ClassVar[bool] = True
33
+ """
34
+ Whether constructing an instance registers it with the current page.
35
+
36
+ Set to `False` as a class attribute to opt out.
37
+ """
38
+
39
+ def __post_init__(self, ref: Optional[Ref[Any]]):
40
+ """
41
+ Finalize the service and register it with the current page.
42
+
43
+ Prefer overriding `init()` for setup. If this method is overridden,
44
+ registration occurs inside `super().__post_init__(ref)`: fields assigned
45
+ after that call require a later update to reach the client.
46
+ """
47
+ super().__post_init__(ref)
48
+ if not self._auto_register:
49
+ return
50
+ try:
51
+ page = context.page
52
+ except RuntimeError:
53
+ return
54
+ page._services.register_service(self)
@@ -248,6 +248,9 @@ class Session:
248
248
  and then applied to the local session index by unmounting removed controls and
249
249
  mounting added controls.
250
250
 
251
+ Every added control is indexed before any of them runs `did_mount()`, so the
252
+ index includes all additions in the submitted patch even if a callback raises.
253
+
251
254
  Args:
252
255
  control: Current control state to patch from.
253
256
  prev_control: Previous control snapshot. If `None`, `control` is used.
@@ -267,12 +270,6 @@ class Session:
267
270
  for c in removed_controls:
268
271
  patch_logger.debug(" %s", c)
269
272
 
270
- added_ids = {added_control._i for added_control in added_controls}
271
- for removed_control in removed_controls:
272
- if removed_control._i not in added_ids:
273
- removed_control.will_unmount()
274
- self.__index.pop(removed_control._i, None)
275
-
276
273
  if len(patch) > 1:
277
274
  self.__send_message(
278
275
  Message(
@@ -285,9 +282,21 @@ class Session:
285
282
  for ac in added_controls:
286
283
  patch_logger.debug(" %s", ac)
287
284
 
288
- removed_ids = {removed_control._i for removed_control in removed_controls}
285
+ # Commit the entire index before lifecycle callbacks. A failed send must
286
+ # neither unmount existing controls nor remove them from the index, and
287
+ # a failed callback must not roll back an already-submitted service.
288
+ for removed_control in removed_controls:
289
+ self.__index.pop(removed_control._i, None)
289
290
  for added_control in added_controls:
290
291
  self.__index[added_control._i] = added_control
292
+
293
+ added_ids = {added_control._i for added_control in added_controls}
294
+ for removed_control in removed_controls:
295
+ if removed_control._i not in added_ids:
296
+ removed_control.will_unmount()
297
+
298
+ removed_ids = {removed_control._i for removed_control in removed_controls}
299
+ for added_control in added_controls:
291
300
  if added_control._i not in removed_ids:
292
301
  added_control.did_mount()
293
302
 
@@ -481,13 +481,20 @@ class FletTestApp:
481
481
  Wraps provided controls in a Screenshot control.
482
482
  """
483
483
  controls = list(self.page.controls)
484
- self.page.controls = [
485
- self.__scrollable_screenshot_host(
486
- scr := ft.Screenshot(
487
- ft.Column(controls, margin=margin, intrinsic_width=True)
488
- )
489
- )
490
- ] # type: ignore
484
+ # Controls that expand need a bounded host to expand into: shrink-wrapping
485
+ # them (intrinsic width, scrollable height) is flex-in-unbounded and fails
486
+ # layout. Give those the whole page instead.
487
+ expand = True if any(c.expand for c in controls) else None
488
+ scr = ft.Screenshot(
489
+ ft.Column(
490
+ controls,
491
+ margin=margin,
492
+ intrinsic_width=expand is None,
493
+ expand=expand,
494
+ ),
495
+ expand=expand,
496
+ )
497
+ self.page.controls = [scr if expand else self.__scrollable_screenshot_host(scr)] # type: ignore
491
498
  self.page.update()
492
499
  await self.__pump_and_settle_with_timeout("wrap_page_controls_in_screenshot")
493
500
  for _ in range(0, pump_times):
@@ -16,7 +16,7 @@ __all__ = [
16
16
  ]
17
17
 
18
18
  # set by CI
19
- flet_version = "1.0.0.dev2"
19
+ flet_version = "1.0.1"
20
20
  """
21
21
  The Flet version in use.
22
22
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: flet
3
- Version: 1.0.0.dev2
3
+ Version: 1.0.1
4
4
  Summary: Flet for Python - easily build interactive multi-platform apps in Python
5
5
  Author-email: "Appveyor Systems Inc." <hello@flet.dev>
6
6
  License-Expression: Apache-2.0
@@ -9,23 +9,23 @@ Project-URL: Repository, https://github.com/flet-dev/flet
9
9
  Project-URL: Documentation, https://flet.dev/docs/
10
10
  Requires-Python: >=3.10
11
11
  Description-Content-Type: text/markdown
12
- Requires-Dist: flet-cli==1.0.0.dev2; extra == "cli"
13
- Requires-Dist: flet-web==1.0.0.dev2; extra == "web"
12
+ Requires-Dist: flet-cli==1.0.1; extra == "cli"
13
+ Requires-Dist: flet-web==1.0.1; extra == "web"
14
14
  Requires-Dist: oauthlib>=3.2.2; platform_system != "Emscripten"
15
15
  Requires-Dist: httpx>=0.28.1; platform_system != "Emscripten"
16
16
  Requires-Dist: repath>=0.9.0
17
17
  Requires-Dist: msgpack>=1.1.0
18
18
  Requires-Dist: typing-extensions; python_version < "3.11"
19
19
  Provides-Extra: all
20
- Requires-Dist: flet-cli==1.0.0.dev2; extra == "all"
21
- Requires-Dist: flet-web==1.0.0.dev2; extra == "all"
22
- Requires-Dist: flet-desktop==1.0.0.dev2; extra == "all"
20
+ Requires-Dist: flet-cli==1.0.1; extra == "all"
21
+ Requires-Dist: flet-web==1.0.1; extra == "all"
22
+ Requires-Dist: flet-desktop==1.0.1; extra == "all"
23
23
  Provides-Extra: cli
24
- Requires-Dist: flet-cli==1.0.0.dev2; extra == "cli"
24
+ Requires-Dist: flet-cli==1.0.1; extra == "cli"
25
25
  Provides-Extra: desktop
26
- Requires-Dist: flet-desktop==1.0.0.dev2; extra == "desktop"
26
+ Requires-Dist: flet-desktop==1.0.1; extra == "desktop"
27
27
  Provides-Extra: web
28
- Requires-Dist: flet-web==1.0.0.dev2; extra == "web"
28
+ Requires-Dist: flet-web==1.0.1; extra == "web"
29
29
  Provides-Extra: test
30
30
  Requires-Dist: pytest>=7.2.0; extra == "test"
31
31
  Requires-Dist: pytest-asyncio>=1.1.0; extra == "test"
@@ -41,7 +41,7 @@ Requires-Dist: scikit-image>=0.25.2; extra == "test"
41
41
  </p>
42
42
 
43
43
  <p align="center">
44
- <em>Build multi-platform apps in Python. No frontend experience required.</em>
44
+ <em>Build cross-platform apps in Python. No frontend experience required.</em>
45
45
  </p>
46
46
 
47
47
  <p align="center">
@@ -59,10 +59,11 @@ Requires-Dist: scikit-image>=0.25.2; extra == "test"
59
59
  <img src="https://flet.dev/docs/assets/badges/docs-coverage/flet.svg" alt="Docstring coverage" /></a>
60
60
  </p>
61
61
 
62
- ---
62
+ Flet is a Python framework for building web, desktop, and mobile apps without prior experience in frontend development.
63
63
 
64
- Flet is a framework that allows building mobile, desktop and web applications
65
- in Python only without prior experience in frontend development.
64
+ > **[Try Flet online in Flet Studio](https://studio.flet.dev)**
65
+ >
66
+ > Create, run, and share Python apps in your browser. Start from an example, write your own code, or get help from the AI agent. No installation required.
66
67
 
67
68
  ### <img src="https://flet.dev/img/pages/home/single-code-base.svg" width="25" align="top" />&nbsp;&nbsp;&nbsp;Single code base for any device
68
69