flet 1.0.0.dev2__tar.gz → 1.0.2__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 (335) hide show
  1. {flet-1.0.0.dev2 → flet-1.0.2}/PKG-INFO +14 -13
  2. {flet-1.0.0.dev2 → flet-1.0.2}/README.md +5 -4
  3. {flet-1.0.0.dev2 → flet-1.0.2}/pyproject.toml +9 -9
  4. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/app.py +24 -0
  5. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/auth/authorization_service.py +25 -21
  6. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/auth/providers/github_oauth_provider.py +23 -25
  7. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/components/hooks/use_callback.py +6 -3
  8. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/components/hooks/use_effect.py +4 -2
  9. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/components/hooks/use_memo.py +6 -4
  10. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/base_control.py +23 -8
  11. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/core/icon.py +5 -2
  12. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/core/interactive_viewer.py +13 -1
  13. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/core/raw_image.py +7 -1
  14. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/core/semantics.py +13 -0
  15. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/material/container.py +1 -1
  16. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/object_patch.py +10 -6
  17. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/page.py +110 -18
  18. flet-1.0.2/src/flet/controls/services/service.py +54 -0
  19. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/messaging/session.py +16 -7
  20. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/testing/flet_test_app.py +14 -7
  21. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/testing/remote_tester.py +6 -0
  22. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/testing/tester.py +15 -0
  23. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/version.py +1 -1
  24. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet.egg-info/PKG-INFO +14 -13
  25. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet.egg-info/SOURCES.txt +3 -0
  26. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet.egg-info/requires.txt +8 -8
  27. flet-1.0.2/tests/test_app_logging.py +53 -0
  28. {flet-1.0.0.dev2 → flet-1.0.2}/tests/test_component_diff.py +93 -0
  29. flet-1.0.2/tests/test_icons.py +105 -0
  30. {flet-1.0.0.dev2 → flet-1.0.2}/tests/test_raw_image_pixels.py +56 -0
  31. flet-1.0.2/tests/test_semantics.py +16 -0
  32. flet-1.0.2/tests/test_service_registration.py +705 -0
  33. {flet-1.0.0.dev2 → flet-1.0.2}/tests/test_skip_double_update.py +12 -4
  34. flet-1.0.0.dev2/src/flet/controls/services/service.py +0 -19
  35. flet-1.0.0.dev2/tests/test_icons.py +0 -27
  36. {flet-1.0.0.dev2 → flet-1.0.2}/setup.cfg +0 -0
  37. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/__init__.py +0 -0
  38. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/auth/__init__.py +0 -0
  39. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/auth/authorization.py +0 -0
  40. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/auth/group.py +0 -0
  41. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/auth/oauth_provider.py +0 -0
  42. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/auth/oauth_token.py +0 -0
  43. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/auth/providers/__init__.py +0 -0
  44. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/auth/providers/auth0_oauth_provider.py +0 -0
  45. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/auth/providers/azure_oauth_provider.py +0 -0
  46. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/auth/providers/google_oauth_provider.py +0 -0
  47. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/auth/user.py +0 -0
  48. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/canvas/__init__.py +0 -0
  49. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/cli.py +0 -0
  50. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/components/__init__.py +0 -0
  51. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/components/component.py +0 -0
  52. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/components/component_decorator.py +0 -0
  53. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/components/component_owned.py +0 -0
  54. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/components/hooks/__init__.py +0 -0
  55. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/components/hooks/hook.py +0 -0
  56. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/components/hooks/use_context.py +0 -0
  57. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/components/hooks/use_dialog.py +0 -0
  58. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/components/hooks/use_ref.py +0 -0
  59. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/components/hooks/use_state.py +0 -0
  60. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/components/memo.py +0 -0
  61. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/components/observable.py +0 -0
  62. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/components/public_utils.py +0 -0
  63. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/components/router.py +0 -0
  64. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/components/utils.py +0 -0
  65. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/__init__.py +0 -0
  66. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/action_control.py +0 -0
  67. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/adaptive_control.py +0 -0
  68. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/alignment.py +0 -0
  69. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/animation.py +0 -0
  70. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/base_page.py +0 -0
  71. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/blur.py +0 -0
  72. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/border.py +0 -0
  73. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/border_radius.py +0 -0
  74. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/box.py +0 -0
  75. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/buttons.py +0 -0
  76. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/client_action.py +0 -0
  77. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/colors.py +0 -0
  78. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/context.py +0 -0
  79. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/control.py +0 -0
  80. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/control_event.py +0 -0
  81. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/control_state.py +0 -0
  82. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/core/__init__.py +0 -0
  83. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/core/animated_switcher.py +0 -0
  84. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/core/autofill_group.py +0 -0
  85. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/core/canvas/__init__.py +0 -0
  86. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/core/canvas/arc.py +0 -0
  87. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/core/canvas/canvas.py +0 -0
  88. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/core/canvas/circle.py +0 -0
  89. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/core/canvas/color.py +0 -0
  90. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/core/canvas/fill.py +0 -0
  91. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/core/canvas/image.py +0 -0
  92. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/core/canvas/line.py +0 -0
  93. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/core/canvas/oval.py +0 -0
  94. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/core/canvas/path.py +0 -0
  95. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/core/canvas/points.py +0 -0
  96. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/core/canvas/rect.py +0 -0
  97. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/core/canvas/shadow.py +0 -0
  98. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/core/canvas/shape.py +0 -0
  99. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/core/canvas/text.py +0 -0
  100. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/core/column.py +0 -0
  101. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/core/dismissible.py +0 -0
  102. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/core/drag_target.py +0 -0
  103. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/core/draggable.py +0 -0
  104. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/core/flet_app.py +0 -0
  105. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/core/gesture_detector.py +0 -0
  106. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/core/grid_view.py +0 -0
  107. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/core/hero.py +0 -0
  108. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/core/image.py +0 -0
  109. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/core/keyboard_listener.py +0 -0
  110. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/core/list_view.py +0 -0
  111. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/core/markdown.py +0 -0
  112. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/core/merge_semantics.py +0 -0
  113. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/core/page_view.py +0 -0
  114. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/core/pagelet.py +0 -0
  115. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/core/placeholder.py +0 -0
  116. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/core/reorderable_drag_handle.py +0 -0
  117. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/core/responsive_row.py +0 -0
  118. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/core/rotated_box.py +0 -0
  119. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/core/row.py +0 -0
  120. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/core/safe_area.py +0 -0
  121. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/core/screenshot.py +0 -0
  122. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/core/shader_mask.py +0 -0
  123. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/core/shimmer.py +0 -0
  124. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/core/stack.py +0 -0
  125. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/core/text.py +0 -0
  126. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/core/text_span.py +0 -0
  127. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/core/transparent_pointer.py +0 -0
  128. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/core/view.py +0 -0
  129. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/core/window.py +0 -0
  130. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/core/window_drag_area.py +0 -0
  131. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/cupertino/__init__.py +0 -0
  132. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/cupertino/cupertino_action_sheet.py +0 -0
  133. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/cupertino/cupertino_action_sheet_action.py +0 -0
  134. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/cupertino/cupertino_activity_indicator.py +0 -0
  135. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/cupertino/cupertino_alert_dialog.py +0 -0
  136. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/cupertino/cupertino_app_bar.py +0 -0
  137. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/cupertino/cupertino_bottom_sheet.py +0 -0
  138. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/cupertino/cupertino_button.py +0 -0
  139. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/cupertino/cupertino_checkbox.py +0 -0
  140. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/cupertino/cupertino_colors.py +0 -0
  141. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/cupertino/cupertino_context_menu.py +0 -0
  142. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/cupertino/cupertino_context_menu_action.py +0 -0
  143. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/cupertino/cupertino_date_picker.py +0 -0
  144. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/cupertino/cupertino_dialog_action.py +0 -0
  145. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/cupertino/cupertino_filled_button.py +0 -0
  146. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/cupertino/cupertino_icons.json +0 -0
  147. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/cupertino/cupertino_icons.py +0 -0
  148. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/cupertino/cupertino_icons.pyi +0 -0
  149. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/cupertino/cupertino_list_tile.py +0 -0
  150. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/cupertino/cupertino_navigation_bar.py +0 -0
  151. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/cupertino/cupertino_picker.py +0 -0
  152. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/cupertino/cupertino_radio.py +0 -0
  153. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/cupertino/cupertino_segmented_button.py +0 -0
  154. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/cupertino/cupertino_slider.py +0 -0
  155. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/cupertino/cupertino_sliding_segmented_button.py +0 -0
  156. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/cupertino/cupertino_switch.py +0 -0
  157. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/cupertino/cupertino_textfield.py +0 -0
  158. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/cupertino/cupertino_timer_picker.py +0 -0
  159. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/cupertino/cupertino_tinted_button.py +0 -0
  160. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/device_info.py +0 -0
  161. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/dialog_control.py +0 -0
  162. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/duration.py +0 -0
  163. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/embed_json_encoder.py +0 -0
  164. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/events.py +0 -0
  165. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/exceptions.py +0 -0
  166. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/geometry.py +0 -0
  167. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/gradients.py +0 -0
  168. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/icon_data.py +0 -0
  169. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/id_counter.py +0 -0
  170. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/keys.py +0 -0
  171. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/layout_control.py +0 -0
  172. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/margin.py +0 -0
  173. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/material/__init__.py +0 -0
  174. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/material/alert_dialog.py +0 -0
  175. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/material/app_bar.py +0 -0
  176. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/material/auto_complete.py +0 -0
  177. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/material/badge.py +0 -0
  178. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/material/banner.py +0 -0
  179. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/material/bottom_app_bar.py +0 -0
  180. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/material/bottom_sheet.py +0 -0
  181. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/material/button.py +0 -0
  182. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/material/card.py +0 -0
  183. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/material/checkbox.py +0 -0
  184. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/material/chip.py +0 -0
  185. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/material/circle_avatar.py +0 -0
  186. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/material/context_menu.py +0 -0
  187. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/material/datatable.py +0 -0
  188. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/material/date_picker.py +0 -0
  189. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/material/date_range_picker.py +0 -0
  190. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/material/divider.py +0 -0
  191. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/material/dropdown.py +0 -0
  192. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/material/dropdownm2.py +0 -0
  193. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/material/expansion_panel.py +0 -0
  194. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/material/expansion_tile.py +0 -0
  195. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/material/filled_button.py +0 -0
  196. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/material/filled_tonal_button.py +0 -0
  197. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/material/floating_action_button.py +0 -0
  198. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/material/form_field_control.py +0 -0
  199. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/material/icon_button.py +0 -0
  200. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/material/icons.json +0 -0
  201. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/material/icons.py +0 -0
  202. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/material/icons.pyi +0 -0
  203. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/material/list_tile.py +0 -0
  204. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/material/menu_bar.py +0 -0
  205. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/material/menu_item_button.py +0 -0
  206. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/material/navigation_bar.py +0 -0
  207. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/material/navigation_drawer.py +0 -0
  208. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/material/navigation_rail.py +0 -0
  209. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/material/outlined_button.py +0 -0
  210. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/material/popup_menu_button.py +0 -0
  211. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/material/progress_bar.py +0 -0
  212. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/material/progress_ring.py +0 -0
  213. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/material/radio.py +0 -0
  214. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/material/radio_group.py +0 -0
  215. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/material/range_slider.py +0 -0
  216. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/material/reorderable_list_view.py +0 -0
  217. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/material/search_bar.py +0 -0
  218. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/material/segmented_button.py +0 -0
  219. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/material/selection_area.py +0 -0
  220. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/material/slider.py +0 -0
  221. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/material/snack_bar.py +0 -0
  222. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/material/submenu_button.py +0 -0
  223. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/material/switch.py +0 -0
  224. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/material/tabs.py +0 -0
  225. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/material/text_button.py +0 -0
  226. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/material/textfield.py +0 -0
  227. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/material/time_picker.py +0 -0
  228. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/material/tooltip.py +0 -0
  229. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/material/vertical_divider.py +0 -0
  230. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/multi_view.py +0 -0
  231. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/padding.py +0 -0
  232. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/painting.py +0 -0
  233. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/query_string.py +0 -0
  234. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/ref.py +0 -0
  235. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/scrollable_control.py +0 -0
  236. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/services/__init__.py +0 -0
  237. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/services/accelerometer.py +0 -0
  238. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/services/barometer.py +0 -0
  239. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/services/battery.py +0 -0
  240. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/services/browser_context_menu.py +0 -0
  241. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/services/clipboard.py +0 -0
  242. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/services/connectivity.py +0 -0
  243. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/services/file_picker.py +0 -0
  244. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/services/gyroscope.py +0 -0
  245. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/services/haptic_feedback.py +0 -0
  246. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/services/magnetometer.py +0 -0
  247. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/services/screen_brightness.py +0 -0
  248. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/services/semantics_service.py +0 -0
  249. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/services/sensor_error_event.py +0 -0
  250. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/services/shake_detector.py +0 -0
  251. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/services/share.py +0 -0
  252. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/services/shared_preferences.py +0 -0
  253. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/services/storage_paths.py +0 -0
  254. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/services/url_launcher.py +0 -0
  255. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/services/user_accelerometer.py +0 -0
  256. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/services/wakelock.py +0 -0
  257. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/template_route.py +0 -0
  258. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/text_style.py +0 -0
  259. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/theme.py +0 -0
  260. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/transform.py +0 -0
  261. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/types.py +0 -0
  262. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/controls/value_types.py +0 -0
  263. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/data_channel.py +0 -0
  264. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/fastapi/__init__.py +0 -0
  265. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/messaging/connection.py +0 -0
  266. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/messaging/flet_dart_bridge_server.py +0 -0
  267. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/messaging/flet_socket_server.py +0 -0
  268. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/messaging/protocol.py +0 -0
  269. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/messaging/pyodide_connection.py +0 -0
  270. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/messaging/session_store.py +0 -0
  271. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/pubsub/__init__.py +0 -0
  272. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/pubsub/pubsub_client.py +0 -0
  273. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/pubsub/pubsub_hub.py +0 -0
  274. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/py.typed +0 -0
  275. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/pytest_plugin.py +0 -0
  276. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/security/__init__.py +0 -0
  277. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/testing/__init__.py +0 -0
  278. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/testing/finder.py +0 -0
  279. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/utils/__init__.py +0 -0
  280. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/utils/browser.py +0 -0
  281. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/utils/classproperty.py +0 -0
  282. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/utils/deprecated.py +0 -0
  283. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/utils/deprecated_enum.py +0 -0
  284. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/utils/environment.py +0 -0
  285. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/utils/files.py +0 -0
  286. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/utils/from_dict.py +0 -0
  287. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/utils/griffe_deprecations.py +0 -0
  288. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/utils/hashing.py +0 -0
  289. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/utils/json_utils.py +0 -0
  290. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/utils/locks.py +0 -0
  291. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/utils/network.py +0 -0
  292. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/utils/object_model.py +0 -0
  293. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/utils/once.py +0 -0
  294. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/utils/pip.py +0 -0
  295. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/utils/platform_utils.py +0 -0
  296. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/utils/slugify.py +0 -0
  297. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/utils/strings.py +0 -0
  298. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/utils/typing_utils.py +0 -0
  299. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/utils/validation.py +0 -0
  300. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet/utils/vector.py +0 -0
  301. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet.egg-info/dependency_links.txt +0 -0
  302. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet.egg-info/entry_points.txt +0 -0
  303. {flet-1.0.0.dev2 → flet-1.0.2}/src/flet.egg-info/top_level.txt +0 -0
  304. {flet-1.0.0.dev2 → flet-1.0.2}/tests/test_assets_dir_resolution.py +0 -0
  305. {flet-1.0.0.dev2 → flet-1.0.2}/tests/test_auth_lazy_imports.py +0 -0
  306. {flet-1.0.0.dev2 → flet-1.0.2}/tests/test_base_control.py +0 -0
  307. {flet-1.0.0.dev2 → flet-1.0.2}/tests/test_client_actions.py +0 -0
  308. {flet-1.0.0.dev2 → flet-1.0.2}/tests/test_colors.py +0 -0
  309. {flet-1.0.0.dev2 → flet-1.0.2}/tests/test_component_effects.py +0 -0
  310. {flet-1.0.0.dev2 → flet-1.0.2}/tests/test_component_owned_identity.py +0 -0
  311. {flet-1.0.0.dev2 → flet-1.0.2}/tests/test_component_renderer.py +0 -0
  312. {flet-1.0.0.dev2 → flet-1.0.2}/tests/test_context_auto_update.py +0 -0
  313. {flet-1.0.0.dev2 → flet-1.0.2}/tests/test_dataclasses.py +0 -0
  314. {flet-1.0.0.dev2 → flet-1.0.2}/tests/test_datetime.py +0 -0
  315. {flet-1.0.0.dev2 → flet-1.0.2}/tests/test_deprecated.py +0 -0
  316. {flet-1.0.0.dev2 → flet-1.0.2}/tests/test_environment.py +0 -0
  317. {flet-1.0.0.dev2 → flet-1.0.2}/tests/test_events.py +0 -0
  318. {flet-1.0.0.dev2 → flet-1.0.2}/tests/test_files.py +0 -0
  319. {flet-1.0.0.dev2 → flet-1.0.2}/tests/test_from_dict.py +0 -0
  320. {flet-1.0.0.dev2 → flet-1.0.2}/tests/test_generator_handler_yield.py +0 -0
  321. {flet-1.0.0.dev2 → flet-1.0.2}/tests/test_griffe_deprecations.py +0 -0
  322. {flet-1.0.0.dev2 → flet-1.0.2}/tests/test_object_diff_frozen.py +0 -0
  323. {flet-1.0.0.dev2 → flet-1.0.2}/tests/test_object_diff_in_place.py +0 -0
  324. {flet-1.0.0.dev2 → flet-1.0.2}/tests/test_object_diff_memory_churn.py +0 -0
  325. {flet-1.0.0.dev2 → flet-1.0.2}/tests/test_object_diff_performance.py +0 -0
  326. {flet-1.0.0.dev2 → flet-1.0.2}/tests/test_observable.py +0 -0
  327. {flet-1.0.0.dev2 → flet-1.0.2}/tests/test_patch_dataclass.py +0 -0
  328. {flet-1.0.0.dev2 → flet-1.0.2}/tests/test_router_modal.py +0 -0
  329. {flet-1.0.0.dev2 → flet-1.0.2}/tests/test_router_pop.py +0 -0
  330. {flet-1.0.0.dev2 → flet-1.0.2}/tests/test_router_recursive.py +0 -0
  331. {flet-1.0.0.dev2 → flet-1.0.2}/tests/test_session_disconnect_buffering.py +0 -0
  332. {flet-1.0.0.dev2 → flet-1.0.2}/tests/test_use_dialog.py +0 -0
  333. {flet-1.0.0.dev2 → flet-1.0.2}/tests/test_validation.py +0 -0
  334. {flet-1.0.0.dev2 → flet-1.0.2}/tests/test_validation_benchmark.py +0 -0
  335. {flet-1.0.0.dev2 → flet-1.0.2}/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.2
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.2; extra == "cli"
13
+ Requires-Dist: flet-web==1.0.2; 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.2; extra == "all"
21
+ Requires-Dist: flet-web==1.0.2; extra == "all"
22
+ Requires-Dist: flet-desktop==1.0.2; 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.2; 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.2; 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.2; 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.2"
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.2; extra == 'cli'",
11
+ "flet-web==1.0.2; 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.2",
27
+ "flet-web==1.0.2",
28
+ "flet-desktop==1.0.2",
29
29
  ]
30
- cli = ["flet-cli==1.0.0.dev2"]
30
+ cli = ["flet-cli==1.0.2"]
31
31
  desktop = [
32
- "flet-desktop==1.0.0.dev2",
32
+ "flet-desktop==1.0.2",
33
33
  ]
34
- web = ["flet-web==1.0.0.dev2"]
34
+ web = ["flet-web==1.0.2"]
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
@@ -1,4 +1,3 @@
1
- import json
2
1
  import secrets
3
2
  import time
4
3
  from collections.abc import Mapping
@@ -116,6 +115,7 @@ class AuthorizationService(Authorization):
116
115
  Raises:
117
116
  httpx.HTTPStatusError: If token endpoint returns a non-success status.
118
117
  """
118
+
119
119
  import httpx
120
120
  from oauthlib.oauth2 import WebApplicationClient
121
121
 
@@ -129,11 +129,11 @@ class AuthorizationService(Authorization):
129
129
  )
130
130
  headers = self.__get_default_headers()
131
131
  headers["content-type"] = "application/x-www-form-urlencoded"
132
- req = httpx.Request(
133
- "POST", self.provider.token_endpoint, content=data, headers=headers
134
- )
132
+
135
133
  async with httpx.AsyncClient(follow_redirects=True) as client:
136
- resp = await client.send(req)
134
+ resp = await client.post(
135
+ self.provider.token_endpoint, content=data, headers=headers
136
+ )
137
137
  resp.raise_for_status()
138
138
  client = WebApplicationClient(self.provider.client_id)
139
139
  t = client.parse_request_body_response(resp.text)
@@ -217,19 +217,21 @@ class AuthorizationService(Authorization):
217
217
  )
218
218
  headers = self.__get_default_headers()
219
219
  headers["content-type"] = "application/x-www-form-urlencoded"
220
- refresh_req = httpx.Request(
221
- "POST", url=self.provider.token_endpoint, content=data, headers=headers
222
- )
223
- if refresh_req:
224
- async with httpx.AsyncClient(follow_redirects=True) as client:
225
- refresh_resp = await client.send(refresh_req)
226
- refresh_resp.raise_for_status()
227
- assert self.__token is not None
228
- client = WebApplicationClient(self.provider.client_id)
229
- t = client.parse_request_body_response(refresh_resp.text)
230
- if t.get("refresh_token") is None:
231
- t["refresh_token"] = self.__token.refresh_token
232
- self.__token = self.__convert_token(t)
220
+
221
+ async with httpx.AsyncClient(follow_redirects=True) as client:
222
+ refresh_resp = await client.post(
223
+ self.provider.token_endpoint, content=data, headers=headers
224
+ )
225
+ refresh_resp.raise_for_status()
226
+ assert self.__token is not None
227
+
228
+ client = WebApplicationClient(self.provider.client_id)
229
+ t = client.parse_request_body_response(refresh_resp.text)
230
+
231
+ if t.get("refresh_token") is None:
232
+ t["refresh_token"] = self.__token.refresh_token
233
+
234
+ self.__token = self.__convert_token(t)
233
235
 
234
236
  async def __get_user(self) -> User:
235
237
  """
@@ -242,18 +244,20 @@ class AuthorizationService(Authorization):
242
244
  Raises:
243
245
  httpx.HTTPStatusError: If user endpoint request fails.
244
246
  """
247
+
245
248
  import httpx
246
249
 
247
250
  assert self.__token is not None
248
251
  assert self.provider.user_endpoint is not None
252
+
249
253
  headers = self.__get_default_headers()
250
254
  headers["Authorization"] = f"Bearer {self.__token.access_token}"
251
- user_req = httpx.Request("GET", self.provider.user_endpoint, headers=headers)
255
+
252
256
  async with httpx.AsyncClient(follow_redirects=True) as client:
253
- user_resp = await client.send(user_req)
257
+ user_resp = await client.get(self.provider.user_endpoint, headers=headers)
254
258
  user_resp.raise_for_status()
255
259
  assert self.provider.user_id_fn is not None
256
- uj = json.loads(user_resp.text)
260
+ uj = user_resp.json()
257
261
  return User(uj, str(self.provider.user_id_fn(uj)))
258
262
 
259
263
  def __get_default_headers(self) -> dict[str, str]:
@@ -1,4 +1,3 @@
1
- import json
2
1
  from typing import Optional
3
2
 
4
3
  from flet.auth.group import Group
@@ -8,6 +7,8 @@ from flet.version import flet_version
8
7
 
9
8
  __all__ = ["GitHubOAuthProvider"]
10
9
 
10
+ GITHUB_API_BASE_URL = "https://api.github.com"
11
+
11
12
 
12
13
  class GitHubOAuthProvider(OAuthProvider):
13
14
  """
@@ -38,20 +39,20 @@ class GitHubOAuthProvider(OAuthProvider):
38
39
  Returns:
39
40
  A list of :class:`~flet.auth.Group` mapped from `/user/teams`.
40
41
  """
42
+
41
43
  import httpx
42
44
 
43
- async with httpx.AsyncClient(follow_redirects=True) as client:
44
- teams_resp = await client.send(
45
- httpx.Request(
46
- "GET",
47
- "https://api.github.com/user/teams",
48
- headers=self.__get_client_headers(access_token),
49
- )
45
+ async with httpx.AsyncClient(
46
+ base_url=GITHUB_API_BASE_URL, follow_redirects=True
47
+ ) as client:
48
+
49
+ teams_resp = await client.get(
50
+ "/user/teams", headers=self.__get_client_headers(access_token)
50
51
  )
51
52
  teams_resp.raise_for_status()
52
53
  groups = []
53
- tj = json.loads(teams_resp.text)
54
- for t in tj:
54
+
55
+ for t in teams_resp.json():
55
56
  groups.append(
56
57
  Group(
57
58
  t,
@@ -71,28 +72,25 @@ class GitHubOAuthProvider(OAuthProvider):
71
72
  A :class:`~flet.auth.User` built from `/user`; its `email` is populated
72
73
  from the primary address in `/user/emails` when available.
73
74
  """
75
+
74
76
  import httpx
75
77
 
76
- async with httpx.AsyncClient(follow_redirects=True) as client:
77
- user_resp = await client.send(
78
- httpx.Request(
79
- "GET",
80
- "https://api.github.com/user",
81
- headers=self.__get_client_headers(access_token),
82
- )
78
+ async with httpx.AsyncClient(
79
+ base_url=GITHUB_API_BASE_URL, follow_redirects=True
80
+ ) as client:
81
+
82
+ user_resp = await client.get(
83
+ "/user", headers=self.__get_client_headers(access_token)
83
84
  )
84
85
  user_resp.raise_for_status()
85
- uj = json.loads(user_resp.text)
86
+ uj = user_resp.json()
86
87
 
87
- emails_resp = await client.send(
88
- httpx.Request(
89
- "GET",
90
- "https://api.github.com/user/emails",
91
- headers=self.__get_client_headers(access_token),
92
- )
88
+ emails_resp = await client.get(
89
+ "/user/emails", headers=self.__get_client_headers(access_token)
93
90
  )
94
91
  emails_resp.raise_for_status()
95
- ej = json.loads(emails_resp.text)
92
+ ej = emails_resp.json()
93
+
96
94
  for e in ej:
97
95
  if e["primary"]:
98
96
  uj["email"] = e["email"]
@@ -18,11 +18,14 @@ def use_callback(
18
18
 
19
19
  Args:
20
20
  fn: A function to memoize.
21
- dependencies: If present, fn is only re-memoized when one of the dependencies
22
- has changed. If absent, fn is only memoized on initial render.
21
+ dependencies: Values the function depends on. If absent, the `fn` passed on
22
+ each render is returned as is. If empty, the `fn` from the first render
23
+ is kept. Otherwise, it is replaced only when one of the dependencies has
24
+ changed.
23
25
 
24
26
  Returns:
25
- A memoized version of the function whose identity is stable between renders.
27
+ The memoized function. The same function object is returned on every render
28
+ until it is replaced.
26
29
  """
27
30
  # Just memoize the function object itself
28
31
  return use_memo(lambda: fn, dependencies)
@@ -50,8 +50,10 @@ def use_effect(
50
50
  Args:
51
51
  setup: A function that performs the side effect. It may optionally return
52
52
  a cleanup function.
53
- dependencies: If present, the effect is only re-run when one of the dependencies
54
- has changed. If absent, the effect is only run on initial render.
53
+ dependencies: Values the effect depends on. The effect always runs after the
54
+ component mounts. If absent, it also re-runs after every render. If
55
+ empty, it runs only on mount. Otherwise, it re-runs only when one of the
56
+ dependencies has changed.
55
57
  cleanup: An optional function that cleans up after the effect. It is run
56
58
  before the effect is re-run, and when the component unmounts.
57
59
  """
@@ -30,12 +30,14 @@ def use_memo(
30
30
 
31
31
  Args:
32
32
  calculate_value: A function that computes the value to be memoized.
33
- dependencies: If present, the value is only recomputed when one of
34
- the dependencies has changed. If absent, the value is only computed
35
- on the initial render.
33
+ dependencies: Values the computation depends on. If absent, the value is
34
+ recomputed on every render. If empty, it is computed only on the first
35
+ render. Otherwise, it is recomputed only when one of the dependencies
36
+ has changed.
36
37
 
37
38
  Returns:
38
- A memoized value whose identity is stable between renders.
39
+ The memoized value. The same object is returned on every render until the
40
+ value is recomputed.
39
41
  """
40
42
  component = current_component()
41
43
 
@@ -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
@@ -135,7 +135,19 @@ class InteractiveViewer(LayoutControl):
135
135
 
136
136
  alignment: Optional[Alignment] = None
137
137
  """
138
- The alignment of the :attr:`content` within this viewer.
138
+ The origin of the transformation applied to the :attr:`content` when it is
139
+ zoomed or panned, relative to the content's size.
140
+
141
+ :meth:`zoom` scales the content around this point. It does not change where the
142
+ content is placed in this viewer; to position the content, wrap it in a control
143
+ that aligns its child, such as a :class:`~flet.Container` with
144
+ :attr:`~flet.Container.alignment` set.
145
+
146
+ Note:
147
+ Gestures and the limits of :meth:`pan` treat the top-left corner as the
148
+ origin. With any other value, the content drifts away from the pointer while
149
+ zooming with a gesture, and once zoomed in, panning stops short of one edge
150
+ of the content and goes past the opposite one, leaving empty space.
139
151
  """
140
152
 
141
153
  boundary_margin: MarginValue = field(default_factory=lambda: Margin.all(0))
@@ -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:
@@ -30,6 +30,19 @@ class Semantics(Control):
30
30
  A textual description of the :attr:`content`.
31
31
  """
32
32
 
33
+ identifier: Optional[str] = None
34
+ """
35
+ A stable identifier for this node in the native accessibility hierarchy.
36
+
37
+ Unlike :attr:`label`, this value is not announced to users. Native testing
38
+ tools use it as Android ``resource-id``, iOS ``accessibilityIdentifier``,
39
+ and the web ``flt-semantics-identifier`` DOM attribute. Widget tests can
40
+ match it with :meth:`flet.testing.Tester.find_by_semantics_identifier`.
41
+
42
+ Setting this property forces a dedicated semantics node, equivalent to
43
+ setting :attr:`container` to ``True``.
44
+ """
45
+
33
46
  expanded: Optional[bool] = None
34
47
  """
35
48
  Whether this subtree represents something that can be in an "expanded" or \
@@ -139,7 +139,7 @@ class Container(LayoutControl, AdaptiveControl, ActionControl):
139
139
  controls=[
140
140
  ft.Container(
141
141
  content=ft.Text("Hello"),
142
- image_src="https://picsum.photos/100/100",
142
+ image=ft.DecorationImage(src="https://picsum.photos/100/100"),
143
143
  width=100,
144
144
  height=100,
145
145
  ),
@@ -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)