reflex 0.5.5a1__py3-none-any.whl → 0.5.6__py3-none-any.whl

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.

Potentially problematic release.


This version of reflex might be problematic. Click here for more details.

Files changed (264) hide show
  1. reflex/.templates/jinja/web/pages/_app.js.jinja2 +0 -1
  2. reflex/.templates/jinja/web/utils/context.js.jinja2 +2 -0
  3. reflex/.templates/web/components/reflex/radix_themes_color_mode_provider.js +20 -2
  4. reflex/.templates/web/utils/helpers/paste.js +59 -0
  5. reflex/__init__.py +9 -1
  6. reflex/__init__.pyi +89 -87
  7. reflex/app.py +64 -126
  8. reflex/app_mixins/__init__.py +5 -0
  9. reflex/app_mixins/lifespan.py +57 -0
  10. reflex/app_mixins/middleware.py +93 -0
  11. reflex/app_mixins/mixin.py +14 -0
  12. reflex/compiler/compiler.py +6 -1
  13. reflex/components/__init__.pyi +0 -2
  14. reflex/components/base/__init__.pyi +1 -3
  15. reflex/components/base/app_wrap.pyi +21 -22
  16. reflex/components/base/body.pyi +21 -20
  17. reflex/components/base/document.pyi +85 -85
  18. reflex/components/base/fragment.pyi +21 -20
  19. reflex/components/base/head.pyi +37 -36
  20. reflex/components/base/link.pyi +37 -37
  21. reflex/components/base/meta.pyi +69 -70
  22. reflex/components/base/script.py +6 -2
  23. reflex/components/base/script.pyi +31 -27
  24. reflex/components/chakra/base.pyi +54 -56
  25. reflex/components/chakra/datadisplay/badge.pyi +21 -21
  26. reflex/components/chakra/datadisplay/code.pyi +21 -20
  27. reflex/components/chakra/datadisplay/divider.pyi +21 -22
  28. reflex/components/chakra/datadisplay/keyboard_key.pyi +21 -20
  29. reflex/components/chakra/datadisplay/list.pyi +69 -71
  30. reflex/components/chakra/datadisplay/stat.pyi +101 -102
  31. reflex/components/chakra/datadisplay/table.pyi +149 -153
  32. reflex/components/chakra/datadisplay/tag.pyi +85 -89
  33. reflex/components/chakra/disclosure/accordion.pyi +87 -93
  34. reflex/components/chakra/disclosure/tabs.pyi +85 -90
  35. reflex/components/chakra/disclosure/transition.pyi +104 -105
  36. reflex/components/chakra/disclosure/visuallyhidden.pyi +21 -20
  37. reflex/components/chakra/feedback/alert.pyi +69 -70
  38. reflex/components/chakra/feedback/circularprogress.pyi +38 -40
  39. reflex/components/chakra/feedback/progress.pyi +22 -23
  40. reflex/components/chakra/feedback/skeleton.pyi +53 -53
  41. reflex/components/chakra/feedback/spinner.pyi +21 -21
  42. reflex/components/chakra/forms/button.pyi +37 -42
  43. reflex/components/chakra/forms/checkbox.pyi +38 -39
  44. reflex/components/chakra/forms/colormodeswitch.pyi +72 -71
  45. reflex/components/chakra/forms/date_picker.pyi +24 -24
  46. reflex/components/chakra/forms/date_time_picker.pyi +24 -24
  47. reflex/components/chakra/forms/editable.pyi +73 -74
  48. reflex/components/chakra/forms/email.pyi +24 -24
  49. reflex/components/chakra/forms/form.pyi +112 -141
  50. reflex/components/chakra/forms/iconbutton.pyi +21 -22
  51. reflex/components/chakra/forms/input.pyi +104 -111
  52. reflex/components/chakra/forms/numberinput.pyi +87 -91
  53. reflex/components/chakra/forms/password.pyi +24 -24
  54. reflex/components/chakra/forms/pininput.pyi +39 -45
  55. reflex/components/chakra/forms/radio.pyi +38 -43
  56. reflex/components/chakra/forms/rangeslider.pyi +72 -76
  57. reflex/components/chakra/forms/select.pyi +39 -44
  58. reflex/components/chakra/forms/slider.pyi +88 -91
  59. reflex/components/chakra/forms/switch.pyi +22 -23
  60. reflex/components/chakra/forms/textarea.pyi +24 -27
  61. reflex/components/chakra/forms/time_picker.pyi +24 -24
  62. reflex/components/chakra/layout/aspect_ratio.pyi +21 -21
  63. reflex/components/chakra/layout/box.pyi +21 -22
  64. reflex/components/chakra/layout/card.pyi +69 -73
  65. reflex/components/chakra/layout/center.pyi +53 -52
  66. reflex/components/chakra/layout/container.pyi +21 -21
  67. reflex/components/chakra/layout/flex.pyi +23 -26
  68. reflex/components/chakra/layout/grid.pyi +53 -54
  69. reflex/components/chakra/layout/spacer.pyi +21 -20
  70. reflex/components/chakra/layout/stack.pyi +62 -60
  71. reflex/components/chakra/layout/wrap.pyi +37 -38
  72. reflex/components/chakra/media/avatar.pyi +54 -55
  73. reflex/components/chakra/media/icon.pyi +37 -38
  74. reflex/components/chakra/media/image.pyi +24 -26
  75. reflex/components/chakra/navigation/breadcrumb.pyi +69 -71
  76. reflex/components/chakra/navigation/link.pyi +20 -21
  77. reflex/components/chakra/navigation/linkoverlay.pyi +37 -37
  78. reflex/components/chakra/navigation/stepper.pyi +149 -151
  79. reflex/components/chakra/overlay/alertdialog.pyi +121 -124
  80. reflex/components/chakra/overlay/drawer.pyi +121 -126
  81. reflex/components/chakra/overlay/menu.pyi +135 -141
  82. reflex/components/chakra/overlay/modal.pyi +121 -124
  83. reflex/components/chakra/overlay/popover.pyi +151 -156
  84. reflex/components/chakra/overlay/tooltip.pyi +23 -24
  85. reflex/components/chakra/typography/heading.pyi +21 -21
  86. reflex/components/chakra/typography/highlight.pyi +21 -23
  87. reflex/components/chakra/typography/span.pyi +21 -21
  88. reflex/components/chakra/typography/text.pyi +21 -21
  89. reflex/components/component.py +6 -2
  90. reflex/components/core/__init__.py +2 -0
  91. reflex/components/core/__init__.pyi +9 -7
  92. reflex/components/core/banner.pyi +118 -146
  93. reflex/components/core/breakpoints.py +95 -0
  94. reflex/components/core/client_side_routing.pyi +37 -39
  95. reflex/components/core/clipboard.py +95 -0
  96. reflex/components/core/clipboard.pyi +102 -0
  97. reflex/components/core/debounce.pyi +23 -28
  98. reflex/components/core/foreach.py +3 -2
  99. reflex/components/core/html.pyi +38 -55
  100. reflex/components/core/upload.py +1 -1
  101. reflex/components/core/upload.pyi +74 -91
  102. reflex/components/datadisplay/__init__.pyi +2 -3
  103. reflex/components/datadisplay/code.py +3 -3
  104. reflex/components/datadisplay/code.pyi +22 -31
  105. reflex/components/datadisplay/dataeditor.pyi +41 -45
  106. reflex/components/el/__init__.pyi +131 -135
  107. reflex/components/el/element.pyi +21 -20
  108. reflex/components/el/elements/__init__.pyi +131 -132
  109. reflex/components/el/elements/base.pyi +38 -55
  110. reflex/components/el/elements/forms.pyi +558 -878
  111. reflex/components/el/elements/inline.pyi +941 -1403
  112. reflex/components/el/elements/media.pyi +645 -994
  113. reflex/components/el/elements/metadata.pyi +186 -268
  114. reflex/components/el/elements/other.pyi +239 -353
  115. reflex/components/el/elements/scripts.pyi +113 -171
  116. reflex/components/el/elements/sectioning.pyi +500 -739
  117. reflex/components/el/elements/tables.pyi +355 -551
  118. reflex/components/el/elements/typography.pyi +510 -760
  119. reflex/components/gridjs/datatable.pyi +38 -42
  120. reflex/components/lucide/icon.pyi +37 -38
  121. reflex/components/markdown/markdown.pyi +23 -36
  122. reflex/components/moment/moment.pyi +23 -25
  123. reflex/components/next/base.pyi +21 -20
  124. reflex/components/next/image.pyi +25 -27
  125. reflex/components/next/link.pyi +21 -21
  126. reflex/components/next/video.pyi +22 -22
  127. reflex/components/plotly/plotly.pyi +42 -45
  128. reflex/components/radix/__init__.pyi +26 -30
  129. reflex/components/radix/primitives/__init__.pyi +0 -2
  130. reflex/components/radix/primitives/accordion.pyi +119 -127
  131. reflex/components/radix/primitives/base.pyi +37 -40
  132. reflex/components/radix/primitives/drawer.pyi +175 -179
  133. reflex/components/radix/primitives/form.pyi +250 -336
  134. reflex/components/radix/primitives/progress.pyi +92 -96
  135. reflex/components/radix/primitives/slider.pyi +87 -89
  136. reflex/components/radix/themes/__init__.pyi +0 -2
  137. reflex/components/radix/themes/base.pyi +118 -121
  138. reflex/components/radix/themes/color_mode.pyi +103 -117
  139. reflex/components/radix/themes/components/__init__.pyi +12 -14
  140. reflex/components/radix/themes/components/alert_dialog.py +2 -1
  141. reflex/components/radix/themes/components/alert_dialog.pyi +150 -157
  142. reflex/components/radix/themes/components/aspect_ratio.pyi +22 -22
  143. reflex/components/radix/themes/components/avatar.py +2 -1
  144. reflex/components/radix/themes/components/avatar.pyi +32 -23
  145. reflex/components/radix/themes/components/badge.py +2 -1
  146. reflex/components/radix/themes/components/badge.pyi +50 -57
  147. reflex/components/radix/themes/components/button.py +2 -1
  148. reflex/components/radix/themes/components/button.pyi +60 -79
  149. reflex/components/radix/themes/components/callout.py +2 -1
  150. reflex/components/radix/themes/components/callout.pyi +201 -258
  151. reflex/components/radix/themes/components/card.py +2 -1
  152. reflex/components/radix/themes/components/card.pyi +48 -56
  153. reflex/components/radix/themes/components/checkbox.py +2 -1
  154. reflex/components/radix/themes/components/checkbox.pyi +68 -62
  155. reflex/components/radix/themes/components/checkbox_cards.py +8 -3
  156. reflex/components/radix/themes/components/checkbox_cards.pyi +87 -44
  157. reflex/components/radix/themes/components/checkbox_group.py +2 -1
  158. reflex/components/radix/themes/components/checkbox_group.pyi +49 -40
  159. reflex/components/radix/themes/components/context_menu.py +2 -1
  160. reflex/components/radix/themes/components/context_menu.pyi +153 -147
  161. reflex/components/radix/themes/components/data_list.py +8 -7
  162. reflex/components/radix/themes/components/data_list.pyi +116 -78
  163. reflex/components/radix/themes/components/dialog.py +2 -1
  164. reflex/components/radix/themes/components/dialog.pyi +154 -161
  165. reflex/components/radix/themes/components/dropdown_menu.py +2 -1
  166. reflex/components/radix/themes/components/dropdown_menu.pyi +169 -163
  167. reflex/components/radix/themes/components/hover_card.py +2 -1
  168. reflex/components/radix/themes/components/hover_card.pyi +97 -107
  169. reflex/components/radix/themes/components/icon_button.py +2 -1
  170. reflex/components/radix/themes/components/icon_button.pyi +59 -82
  171. reflex/components/radix/themes/components/inset.py +10 -9
  172. reflex/components/radix/themes/components/inset.pyi +109 -61
  173. reflex/components/radix/themes/components/popover.py +2 -1
  174. reflex/components/radix/themes/components/popover.pyi +105 -112
  175. reflex/components/radix/themes/components/progress.py +2 -1
  176. reflex/components/radix/themes/components/progress.pyi +32 -24
  177. reflex/components/radix/themes/components/radio.py +2 -1
  178. reflex/components/radix/themes/components/radio.pyi +32 -23
  179. reflex/components/radix/themes/components/radio_cards.py +51 -3
  180. reflex/components/radix/themes/components/radio_cards.pyi +120 -44
  181. reflex/components/radix/themes/components/radio_group.py +5 -2
  182. reflex/components/radix/themes/components/radio_group.pyi +82 -77
  183. reflex/components/radix/themes/components/scroll_area.pyi +21 -21
  184. reflex/components/radix/themes/components/segmented_control.py +2 -1
  185. reflex/components/radix/themes/components/segmented_control.pyi +52 -46
  186. reflex/components/radix/themes/components/select.py +2 -1
  187. reflex/components/radix/themes/components/select.pyi +188 -164
  188. reflex/components/radix/themes/components/separator.py +5 -2
  189. reflex/components/radix/themes/components/separator.pyi +40 -24
  190. reflex/components/radix/themes/components/skeleton.py +7 -6
  191. reflex/components/radix/themes/components/skeleton.pyi +40 -26
  192. reflex/components/radix/themes/components/slider.py +2 -1
  193. reflex/components/radix/themes/components/slider.pyi +40 -31
  194. reflex/components/radix/themes/components/spinner.py +2 -1
  195. reflex/components/radix/themes/components/spinner.pyi +31 -22
  196. reflex/components/radix/themes/components/switch.py +2 -1
  197. reflex/components/radix/themes/components/switch.pyi +33 -25
  198. reflex/components/radix/themes/components/table.py +2 -1
  199. reflex/components/radix/themes/components/table.pyi +265 -404
  200. reflex/components/radix/themes/components/tabs.py +14 -1
  201. reflex/components/radix/themes/components/tabs.pyi +113 -92
  202. reflex/components/radix/themes/components/text_area.py +3 -2
  203. reflex/components/radix/themes/components/text_area.pyi +64 -66
  204. reflex/components/radix/themes/components/text_field.py +2 -1
  205. reflex/components/radix/themes/components/text_field.pyi +116 -140
  206. reflex/components/radix/themes/components/tooltip.pyi +32 -37
  207. reflex/components/radix/themes/layout/__init__.pyi +4 -7
  208. reflex/components/radix/themes/layout/base.py +10 -9
  209. reflex/components/radix/themes/layout/base.pyi +121 -31
  210. reflex/components/radix/themes/layout/box.pyi +39 -53
  211. reflex/components/radix/themes/layout/center.pyi +89 -58
  212. reflex/components/radix/themes/layout/container.py +4 -1
  213. reflex/components/radix/themes/layout/container.pyi +51 -58
  214. reflex/components/radix/themes/layout/flex.py +6 -5
  215. reflex/components/radix/themes/layout/flex.pyi +91 -61
  216. reflex/components/radix/themes/layout/grid.py +9 -8
  217. reflex/components/radix/themes/layout/grid.pyi +116 -64
  218. reflex/components/radix/themes/layout/list.pyi +173 -233
  219. reflex/components/radix/themes/layout/section.py +4 -1
  220. reflex/components/radix/themes/layout/section.pyi +50 -57
  221. reflex/components/radix/themes/layout/spacer.pyi +89 -58
  222. reflex/components/radix/themes/layout/stack.pyi +160 -160
  223. reflex/components/radix/themes/typography/__init__.pyi +0 -2
  224. reflex/components/radix/themes/typography/blockquote.py +3 -2
  225. reflex/components/radix/themes/typography/blockquote.pyi +58 -59
  226. reflex/components/radix/themes/typography/code.py +3 -2
  227. reflex/components/radix/themes/typography/code.pyi +57 -58
  228. reflex/components/radix/themes/typography/heading.py +5 -4
  229. reflex/components/radix/themes/typography/heading.pyi +71 -60
  230. reflex/components/radix/themes/typography/link.py +4 -3
  231. reflex/components/radix/themes/typography/link.pyi +74 -82
  232. reflex/components/radix/themes/typography/text.py +5 -4
  233. reflex/components/radix/themes/typography/text.pyi +330 -364
  234. reflex/components/react_player/audio.pyi +37 -36
  235. reflex/components/react_player/react_player.pyi +37 -38
  236. reflex/components/react_player/video.pyi +37 -36
  237. reflex/components/recharts/__init__.pyi +41 -42
  238. reflex/components/recharts/cartesian.pyi +384 -400
  239. reflex/components/recharts/charts.pyi +224 -231
  240. reflex/components/recharts/general.pyi +89 -96
  241. reflex/components/recharts/polar.pyi +97 -104
  242. reflex/components/recharts/recharts.pyi +37 -37
  243. reflex/components/sonner/toast.pyi +22 -27
  244. reflex/components/suneditor/editor.pyi +53 -58
  245. reflex/config.py +6 -0
  246. reflex/constants/event.py +1 -0
  247. reflex/experimental/layout.pyi +140 -194
  248. reflex/model.py +14 -2
  249. reflex/state.py +55 -45
  250. reflex/style.py +24 -13
  251. reflex/utils/codespaces.py +94 -0
  252. reflex/utils/compat.py +21 -0
  253. reflex/utils/exceptions.py +4 -0
  254. reflex/utils/format.py +25 -4
  255. reflex/utils/prerequisites.py +0 -12
  256. reflex/utils/pyi_generator.py +88 -61
  257. reflex/utils/types.py +83 -5
  258. reflex/vars.py +62 -5
  259. reflex/vars.pyi +23 -11
  260. {reflex-0.5.5a1.dist-info → reflex-0.5.6.dist-info}/METADATA +5 -6
  261. {reflex-0.5.5a1.dist-info → reflex-0.5.6.dist-info}/RECORD +264 -255
  262. {reflex-0.5.5a1.dist-info → reflex-0.5.6.dist-info}/LICENSE +0 -0
  263. {reflex-0.5.5a1.dist-info → reflex-0.5.6.dist-info}/WHEEL +0 -0
  264. {reflex-0.5.5a1.dist-info → reflex-0.5.6.dist-info}/entry_points.txt +0 -0
reflex/app.py CHANGED
@@ -7,12 +7,12 @@ import concurrent.futures
7
7
  import contextlib
8
8
  import copy
9
9
  import functools
10
- import inspect
11
10
  import io
12
11
  import multiprocessing
13
12
  import os
14
13
  import platform
15
14
  import sys
15
+ from datetime import datetime
16
16
  from typing import (
17
17
  Any,
18
18
  AsyncIterator,
@@ -39,6 +39,7 @@ from starlette_admin.contrib.sqla.view import ModelView
39
39
 
40
40
  from reflex import constants
41
41
  from reflex.admin import AdminDash
42
+ from reflex.app_mixins import AppMixin, LifespanMixin, MiddlewareMixin
42
43
  from reflex.base import Base
43
44
  from reflex.compiler import compiler
44
45
  from reflex.compiler import utils as compiler_utils
@@ -51,6 +52,7 @@ from reflex.components.component import (
51
52
  evaluate_style_namespaces,
52
53
  )
53
54
  from reflex.components.core.banner import connection_pulser, connection_toaster
55
+ from reflex.components.core.breakpoints import set_breakpoints
54
56
  from reflex.components.core.client_side_routing import (
55
57
  Default404Page,
56
58
  wait_for_client_redirect,
@@ -59,7 +61,6 @@ from reflex.components.core.upload import Upload, get_upload_dir
59
61
  from reflex.components.radix import themes
60
62
  from reflex.config import get_config
61
63
  from reflex.event import Event, EventHandler, EventSpec
62
- from reflex.middleware import HydrateMiddleware, Middleware
63
64
  from reflex.model import Model
64
65
  from reflex.page import (
65
66
  DECORATED_PAGES,
@@ -78,8 +79,8 @@ from reflex.state import (
78
79
  _substate_key,
79
80
  code_uses_state_contexts,
80
81
  )
81
- from reflex.utils import console, exceptions, format, prerequisites, types
82
- from reflex.utils.exec import is_testing_env, should_skip_compile
82
+ from reflex.utils import codespaces, console, exceptions, format, prerequisites, types
83
+ from reflex.utils.exec import is_prod_mode, is_testing_env, should_skip_compile
83
84
  from reflex.utils.imports import ImportVar
84
85
 
85
86
  # Define custom types.
@@ -93,7 +94,11 @@ def default_overlay_component() -> Component:
93
94
  Returns:
94
95
  The default overlay_component, which is a connection_modal.
95
96
  """
96
- return Fragment.create(connection_pulser(), connection_toaster())
97
+ return Fragment.create(
98
+ connection_pulser(),
99
+ connection_toaster(),
100
+ *codespaces.codespaces_auto_redirect(),
101
+ )
97
102
 
98
103
 
99
104
  class OverlayFragment(Fragment):
@@ -102,50 +107,7 @@ class OverlayFragment(Fragment):
102
107
  pass
103
108
 
104
109
 
105
- class LifespanMixin(Base):
106
- """A Mixin that allow tasks to run during the whole app lifespan."""
107
-
108
- # Lifespan tasks that are planned to run.
109
- lifespan_tasks: Set[Union[asyncio.Task, Callable]] = set()
110
-
111
- @contextlib.asynccontextmanager
112
- async def _run_lifespan_tasks(self, app: FastAPI):
113
- running_tasks = []
114
- try:
115
- async with contextlib.AsyncExitStack() as stack:
116
- for task in self.lifespan_tasks:
117
- if isinstance(task, asyncio.Task):
118
- running_tasks.append(task)
119
- else:
120
- signature = inspect.signature(task)
121
- if "app" in signature.parameters:
122
- task = functools.partial(task, app=app)
123
- _t = task()
124
- if isinstance(_t, contextlib._AsyncGeneratorContextManager):
125
- await stack.enter_async_context(_t)
126
- elif isinstance(_t, Coroutine):
127
- running_tasks.append(asyncio.create_task(_t))
128
- yield
129
- finally:
130
- cancel_kwargs = (
131
- {"msg": "lifespan_cleanup"} if sys.version_info >= (3, 9) else {}
132
- )
133
- for task in running_tasks:
134
- task.cancel(**cancel_kwargs)
135
-
136
- def register_lifespan_task(self, task: Callable | asyncio.Task, **task_kwargs):
137
- """Register a task to run during the lifespan of the app.
138
-
139
- Args:
140
- task: The task to register.
141
- task_kwargs: The kwargs of the task.
142
- """
143
- if task_kwargs:
144
- task = functools.partial(task, **task_kwargs) # type: ignore
145
- self.lifespan_tasks.add(task) # type: ignore
146
-
147
-
148
- class App(LifespanMixin, Base):
110
+ class App(MiddlewareMixin, LifespanMixin, Base):
149
111
  """The main Reflex app that encapsulates the backend and frontend.
150
112
 
151
113
  Every Reflex app needs an app defined in its main module.
@@ -204,9 +166,6 @@ class App(LifespanMixin, Base):
204
166
  # Class to manage many client states.
205
167
  _state_manager: Optional[StateManager] = None
206
168
 
207
- # Middleware to add to the app. Users should use `add_middleware`. PRIVATE.
208
- middleware: List[Middleware] = []
209
-
210
169
  # Mapping from a route to event handlers to trigger when the page loads. PRIVATE.
211
170
  load_events: Dict[str, List[Union[EventHandler, EventSpec]]] = {}
212
171
 
@@ -244,19 +203,31 @@ class App(LifespanMixin, Base):
244
203
  "rx.BaseState cannot be subclassed multiple times. use rx.State instead"
245
204
  )
246
205
 
247
- # Add middleware.
248
- self.middleware.append(HydrateMiddleware())
206
+ if "breakpoints" in self.style:
207
+ set_breakpoints(self.style.pop("breakpoints"))
249
208
 
250
209
  # Set up the API.
251
210
  self.api = FastAPI(lifespan=self._run_lifespan_tasks)
252
211
  self._add_cors()
253
212
  self._add_default_endpoints()
254
213
 
214
+ for clz in App.__mro__:
215
+ if clz == App:
216
+ continue
217
+ if issubclass(clz, AppMixin):
218
+ clz._init_mixin(self)
219
+
255
220
  self._setup_state()
256
221
 
257
222
  # Set up the admin dash.
258
223
  self._setup_admin_dash()
259
224
 
225
+ if sys.platform == "win32" and not is_prod_mode():
226
+ # Hack to fix Windows hot reload issue.
227
+ from reflex.utils.compat import windows_hot_reload_lifespan_hack
228
+
229
+ self.register_lifespan_task(windows_hot_reload_lifespan_hack)
230
+
260
231
  def _enable_state(self) -> None:
261
232
  """Enable state for the app."""
262
233
  if not self.state:
@@ -341,6 +312,10 @@ class App(LifespanMixin, Base):
341
312
  StaticFiles(directory=get_upload_dir()),
342
313
  name="uploaded_files",
343
314
  )
315
+ if codespaces.is_running_in_codespaces():
316
+ self.api.get(str(constants.Endpoint.AUTH_CODESPACE))(
317
+ codespaces.auth_codespace
318
+ )
344
319
 
345
320
  def _add_cors(self):
346
321
  """Add CORS middleware to the app."""
@@ -366,77 +341,6 @@ class App(LifespanMixin, Base):
366
341
  raise ValueError("The state manager has not been initialized.")
367
342
  return self._state_manager
368
343
 
369
- async def _preprocess(self, state: BaseState, event: Event) -> StateUpdate | None:
370
- """Preprocess the event.
371
-
372
- This is where middleware can modify the event before it is processed.
373
- Each middleware is called in the order it was added to the app.
374
-
375
- If a middleware returns an update, the event is not processed and the
376
- update is returned.
377
-
378
- Args:
379
- state: The state to preprocess.
380
- event: The event to preprocess.
381
-
382
- Returns:
383
- An optional state to return.
384
- """
385
- for middleware in self.middleware:
386
- if asyncio.iscoroutinefunction(middleware.preprocess):
387
- out = await middleware.preprocess(app=self, state=state, event=event) # type: ignore
388
- else:
389
- out = middleware.preprocess(app=self, state=state, event=event) # type: ignore
390
- if out is not None:
391
- return out # type: ignore
392
-
393
- async def _postprocess(
394
- self, state: BaseState, event: Event, update: StateUpdate
395
- ) -> StateUpdate:
396
- """Postprocess the event.
397
-
398
- This is where middleware can modify the delta after it is processed.
399
- Each middleware is called in the order it was added to the app.
400
-
401
- Args:
402
- state: The state to postprocess.
403
- event: The event to postprocess.
404
- update: The current state update.
405
-
406
- Returns:
407
- The state update to return.
408
- """
409
- for middleware in self.middleware:
410
- if asyncio.iscoroutinefunction(middleware.postprocess):
411
- out = await middleware.postprocess(
412
- app=self, # type: ignore
413
- state=state,
414
- event=event,
415
- update=update,
416
- )
417
- else:
418
- out = middleware.postprocess(
419
- app=self, # type: ignore
420
- state=state,
421
- event=event,
422
- update=update,
423
- )
424
- if out is not None:
425
- return out # type: ignore
426
- return update
427
-
428
- def add_middleware(self, middleware: Middleware, index: int | None = None):
429
- """Add middleware to the app.
430
-
431
- Args:
432
- middleware: The middleware to add.
433
- index: The index to add the middleware at.
434
- """
435
- if index is None:
436
- self.middleware.append(middleware)
437
- else:
438
- self.middleware.insert(index, middleware)
439
-
440
344
  @staticmethod
441
345
  def _generate_component(component: Component | ComponentCallable) -> Component:
442
346
  """Generate a component from a callable.
@@ -797,6 +701,36 @@ class App(LifespanMixin, Base):
797
701
  for render, kwargs in DECORATED_PAGES[get_config().app_name]:
798
702
  self.add_page(render, **kwargs)
799
703
 
704
+ def _validate_var_dependencies(
705
+ self, state: Optional[Type[BaseState]] = None
706
+ ) -> None:
707
+ """Validate the dependencies of the vars in the app.
708
+
709
+ Args:
710
+ state: The state to validate the dependencies for.
711
+
712
+ Raises:
713
+ VarDependencyError: When a computed var has an invalid dependency.
714
+ """
715
+ if not self.state:
716
+ return
717
+
718
+ if not state:
719
+ state = self.state
720
+
721
+ for var in state.computed_vars.values():
722
+ if not var._cache:
723
+ continue
724
+ deps = var._deps(objclass=state)
725
+ for dep in deps:
726
+ if dep not in state.vars and dep not in state.backend_vars:
727
+ raise exceptions.VarDependencyError(
728
+ f"ComputedVar {var._var_name} on state {state.__name__} has an invalid dependency {dep}"
729
+ )
730
+
731
+ for substate in state.class_subclasses:
732
+ self._validate_var_dependencies(substate)
733
+
800
734
  def _compile(self, export: bool = False):
801
735
  """Compile the app and output it to the pages folder.
802
736
 
@@ -808,6 +742,9 @@ class App(LifespanMixin, Base):
808
742
  """
809
743
  from reflex.utils.exceptions import ReflexRuntimeError
810
744
 
745
+ def get_compilation_time() -> str:
746
+ return str(datetime.now().time()).split(".")[0]
747
+
811
748
  # Render a default 404 page if the user didn't supply one
812
749
  if constants.Page404.SLUG not in self.pages:
813
750
  self.add_custom_404_page()
@@ -818,6 +755,7 @@ class App(LifespanMixin, Base):
818
755
  if not self._should_compile():
819
756
  return
820
757
 
758
+ self._validate_var_dependencies()
821
759
  self._setup_overlay_component()
822
760
 
823
761
  # Create a progress bar.
@@ -832,7 +770,7 @@ class App(LifespanMixin, Base):
832
770
  fixed_pages_within_executor = 5
833
771
  progress.start()
834
772
  task = progress.add_task(
835
- "Compiling:",
773
+ f"[{get_compilation_time()}] Compiling:",
836
774
  total=len(self.pages)
837
775
  + fixed_pages_within_executor
838
776
  + adhoc_steps_without_executor,
@@ -0,0 +1,5 @@
1
+ """Reflex AppMixins package."""
2
+
3
+ from .lifespan import LifespanMixin
4
+ from .middleware import MiddlewareMixin
5
+ from .mixin import AppMixin
@@ -0,0 +1,57 @@
1
+ """Mixin that allow tasks to run during the whole app lifespan."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import asyncio
6
+ import contextlib
7
+ import functools
8
+ import inspect
9
+ import sys
10
+ from typing import Callable, Coroutine, Set, Union
11
+
12
+ from fastapi import FastAPI
13
+
14
+ from .mixin import AppMixin
15
+
16
+
17
+ class LifespanMixin(AppMixin):
18
+ """A Mixin that allow tasks to run during the whole app lifespan."""
19
+
20
+ # Lifespan tasks that are planned to run.
21
+ lifespan_tasks: Set[Union[asyncio.Task, Callable]] = set()
22
+
23
+ @contextlib.asynccontextmanager
24
+ async def _run_lifespan_tasks(self, app: FastAPI):
25
+ running_tasks = []
26
+ try:
27
+ async with contextlib.AsyncExitStack() as stack:
28
+ for task in self.lifespan_tasks:
29
+ if isinstance(task, asyncio.Task):
30
+ running_tasks.append(task)
31
+ else:
32
+ signature = inspect.signature(task)
33
+ if "app" in signature.parameters:
34
+ task = functools.partial(task, app=app)
35
+ _t = task()
36
+ if isinstance(_t, contextlib._AsyncGeneratorContextManager):
37
+ await stack.enter_async_context(_t)
38
+ elif isinstance(_t, Coroutine):
39
+ running_tasks.append(asyncio.create_task(_t))
40
+ yield
41
+ finally:
42
+ cancel_kwargs = (
43
+ {"msg": "lifespan_cleanup"} if sys.version_info >= (3, 9) else {}
44
+ )
45
+ for task in running_tasks:
46
+ task.cancel(**cancel_kwargs)
47
+
48
+ def register_lifespan_task(self, task: Callable | asyncio.Task, **task_kwargs):
49
+ """Register a task to run during the lifespan of the app.
50
+
51
+ Args:
52
+ task: The task to register.
53
+ task_kwargs: The kwargs of the task.
54
+ """
55
+ if task_kwargs:
56
+ task = functools.partial(task, **task_kwargs) # type: ignore
57
+ self.lifespan_tasks.add(task) # type: ignore
@@ -0,0 +1,93 @@
1
+ """Middleware Mixin that allow to add middleware to the app."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import asyncio
6
+ from typing import List
7
+
8
+ from reflex.event import Event
9
+ from reflex.middleware import HydrateMiddleware, Middleware
10
+ from reflex.state import BaseState, StateUpdate
11
+
12
+ from .mixin import AppMixin
13
+
14
+
15
+ class MiddlewareMixin(AppMixin):
16
+ """Middleware Mixin that allow to add middleware to the app."""
17
+
18
+ # Middleware to add to the app. Users should use `add_middleware`. PRIVATE.
19
+ middleware: List[Middleware] = []
20
+
21
+ def _init_mixin(self):
22
+ self.middleware.append(HydrateMiddleware())
23
+
24
+ def add_middleware(self, middleware: Middleware, index: int | None = None):
25
+ """Add middleware to the app.
26
+
27
+ Args:
28
+ middleware: The middleware to add.
29
+ index: The index to add the middleware at.
30
+ """
31
+ if index is None:
32
+ self.middleware.append(middleware)
33
+ else:
34
+ self.middleware.insert(index, middleware)
35
+
36
+ async def _preprocess(self, state: BaseState, event: Event) -> StateUpdate | None:
37
+ """Preprocess the event.
38
+
39
+ This is where middleware can modify the event before it is processed.
40
+ Each middleware is called in the order it was added to the app.
41
+
42
+ If a middleware returns an update, the event is not processed and the
43
+ update is returned.
44
+
45
+ Args:
46
+ state: The state to preprocess.
47
+ event: The event to preprocess.
48
+
49
+ Returns:
50
+ An optional state to return.
51
+ """
52
+ for middleware in self.middleware:
53
+ if asyncio.iscoroutinefunction(middleware.preprocess):
54
+ out = await middleware.preprocess(app=self, state=state, event=event) # type: ignore
55
+ else:
56
+ out = middleware.preprocess(app=self, state=state, event=event) # type: ignore
57
+ if out is not None:
58
+ return out # type: ignore
59
+
60
+ async def _postprocess(
61
+ self, state: BaseState, event: Event, update: StateUpdate
62
+ ) -> StateUpdate:
63
+ """Postprocess the event.
64
+
65
+ This is where middleware can modify the delta after it is processed.
66
+ Each middleware is called in the order it was added to the app.
67
+
68
+ Args:
69
+ state: The state to postprocess.
70
+ event: The event to postprocess.
71
+ update: The current state update.
72
+
73
+ Returns:
74
+ The state update to return.
75
+ """
76
+ for middleware in self.middleware:
77
+ if asyncio.iscoroutinefunction(middleware.postprocess):
78
+ out = await middleware.postprocess(
79
+ app=self, # type: ignore
80
+ state=state,
81
+ event=event,
82
+ update=update,
83
+ )
84
+ else:
85
+ out = middleware.postprocess(
86
+ app=self, # type: ignore
87
+ state=state,
88
+ event=event,
89
+ update=update,
90
+ )
91
+ if out is not None:
92
+ return out # type: ignore
93
+ return update
@@ -0,0 +1,14 @@
1
+ """Default mixin for all app mixins."""
2
+
3
+ from reflex.base import Base
4
+
5
+
6
+ class AppMixin(Base):
7
+ """Define the base class for all app mixins."""
8
+
9
+ def _init_mixin(self):
10
+ """Initialize the mixin.
11
+
12
+ Any App mixin can override this method to perform any initialization.
13
+ """
14
+ ...
@@ -3,6 +3,7 @@
3
3
  from __future__ import annotations
4
4
 
5
5
  import os
6
+ from datetime import datetime
6
7
  from pathlib import Path
7
8
  from typing import Dict, Iterable, Optional, Type, Union
8
9
 
@@ -79,20 +80,24 @@ def _compile_contexts(state: Optional[Type[BaseState]], theme: Component | None)
79
80
  The compiled context file.
80
81
  """
81
82
  appearance = getattr(theme, "appearance", None)
82
- if appearance is None:
83
+ if appearance is None or Var.create_safe(appearance)._var_name == "inherit":
83
84
  appearance = SYSTEM_COLOR_MODE
85
+
86
+ last_compiled_time = str(datetime.now())
84
87
  return (
85
88
  templates.CONTEXT.render(
86
89
  initial_state=utils.compile_state(state),
87
90
  state_name=state.get_name(),
88
91
  client_storage=utils.compile_client_storage(state),
89
92
  is_dev_mode=not is_prod_mode(),
93
+ last_compiled_time=last_compiled_time,
90
94
  default_color_mode=appearance,
91
95
  )
92
96
  if state
93
97
  else templates.CONTEXT.render(
94
98
  is_dev_mode=not is_prod_mode(),
95
99
  default_color_mode=appearance,
100
+ last_compiled_time=last_compiled_time,
96
101
  )
97
102
  )
98
103
 
@@ -18,9 +18,7 @@ from . import react_player as react_player
18
18
  from . import recharts as recharts
19
19
  from . import sonner as sonner
20
20
  from . import suneditor as suneditor
21
-
22
21
  from .component import Component as Component
23
22
  from .component import NoSSRComponent as NoSSRComponent
24
23
  from .next import NextLink as NextLink
25
24
  from .next import next_link as next_link
26
- from reflex.utils import lazy_loader
@@ -5,7 +5,6 @@
5
5
 
6
6
  from . import app_wrap as app_wrap
7
7
  from . import bare as bare
8
-
9
8
  from .body import Body as Body
10
9
  from .document import DocumentHead as DocumentHead
11
10
  from .document import Html as Html
@@ -13,8 +12,8 @@ from .document import Main as Main
13
12
  from .document import NextScript as NextScript
14
13
  from .fragment import Fragment as Fragment
15
14
  from .fragment import fragment as fragment
16
- from .head import head as head
17
15
  from .head import Head as Head
16
+ from .head import head as head
18
17
  from .link import RawLink as RawLink
19
18
  from .link import ScriptTag as ScriptTag
20
19
  from .meta import Description as Description
@@ -23,4 +22,3 @@ from .meta import Meta as Meta
23
22
  from .meta import Title as Title
24
23
  from .script import Script as Script
25
24
  from .script import script as script
26
- from reflex.utils import lazy_loader
@@ -1,15 +1,14 @@
1
1
  """Stub file for reflex/components/base/app_wrap.py"""
2
+
2
3
  # ------------------- DO NOT EDIT ----------------------
3
4
  # This file was generated by `reflex/utils/pyi_generator.py`!
4
5
  # ------------------------------------------------------
6
+ from typing import Any, Callable, Dict, Optional, Union, overload
5
7
 
6
- from typing import Any, Dict, Literal, Optional, Union, overload
7
- from reflex.vars import Var, BaseVar, ComputedVar
8
- from reflex.event import EventChain, EventHandler, EventSpec
9
- from reflex.style import Style
10
8
  from reflex.components.base.fragment import Fragment
11
- from reflex.components.component import Component
12
- from reflex.vars import Var
9
+ from reflex.event import EventHandler, EventSpec
10
+ from reflex.style import Style
11
+ from reflex.vars import BaseVar, Var
13
12
 
14
13
  class AppWrap(Fragment):
15
14
  @overload
@@ -24,51 +23,51 @@ class AppWrap(Fragment):
24
23
  autofocus: Optional[bool] = None,
25
24
  custom_attrs: Optional[Dict[str, Union[Var, str]]] = None,
26
25
  on_blur: Optional[
27
- Union[EventHandler, EventSpec, list, function, BaseVar]
26
+ Union[EventHandler, EventSpec, list, Callable, BaseVar]
28
27
  ] = None,
29
28
  on_click: Optional[
30
- Union[EventHandler, EventSpec, list, function, BaseVar]
29
+ Union[EventHandler, EventSpec, list, Callable, BaseVar]
31
30
  ] = None,
32
31
  on_context_menu: Optional[
33
- Union[EventHandler, EventSpec, list, function, BaseVar]
32
+ Union[EventHandler, EventSpec, list, Callable, BaseVar]
34
33
  ] = None,
35
34
  on_double_click: Optional[
36
- Union[EventHandler, EventSpec, list, function, BaseVar]
35
+ Union[EventHandler, EventSpec, list, Callable, BaseVar]
37
36
  ] = None,
38
37
  on_focus: Optional[
39
- Union[EventHandler, EventSpec, list, function, BaseVar]
38
+ Union[EventHandler, EventSpec, list, Callable, BaseVar]
40
39
  ] = None,
41
40
  on_mount: Optional[
42
- Union[EventHandler, EventSpec, list, function, BaseVar]
41
+ Union[EventHandler, EventSpec, list, Callable, BaseVar]
43
42
  ] = None,
44
43
  on_mouse_down: Optional[
45
- Union[EventHandler, EventSpec, list, function, BaseVar]
44
+ Union[EventHandler, EventSpec, list, Callable, BaseVar]
46
45
  ] = None,
47
46
  on_mouse_enter: Optional[
48
- Union[EventHandler, EventSpec, list, function, BaseVar]
47
+ Union[EventHandler, EventSpec, list, Callable, BaseVar]
49
48
  ] = None,
50
49
  on_mouse_leave: Optional[
51
- Union[EventHandler, EventSpec, list, function, BaseVar]
50
+ Union[EventHandler, EventSpec, list, Callable, BaseVar]
52
51
  ] = None,
53
52
  on_mouse_move: Optional[
54
- Union[EventHandler, EventSpec, list, function, BaseVar]
53
+ Union[EventHandler, EventSpec, list, Callable, BaseVar]
55
54
  ] = None,
56
55
  on_mouse_out: Optional[
57
- Union[EventHandler, EventSpec, list, function, BaseVar]
56
+ Union[EventHandler, EventSpec, list, Callable, BaseVar]
58
57
  ] = None,
59
58
  on_mouse_over: Optional[
60
- Union[EventHandler, EventSpec, list, function, BaseVar]
59
+ Union[EventHandler, EventSpec, list, Callable, BaseVar]
61
60
  ] = None,
62
61
  on_mouse_up: Optional[
63
- Union[EventHandler, EventSpec, list, function, BaseVar]
62
+ Union[EventHandler, EventSpec, list, Callable, BaseVar]
64
63
  ] = None,
65
64
  on_scroll: Optional[
66
- Union[EventHandler, EventSpec, list, function, BaseVar]
65
+ Union[EventHandler, EventSpec, list, Callable, BaseVar]
67
66
  ] = None,
68
67
  on_unmount: Optional[
69
- Union[EventHandler, EventSpec, list, function, BaseVar]
68
+ Union[EventHandler, EventSpec, list, Callable, BaseVar]
70
69
  ] = None,
71
- **props
70
+ **props,
72
71
  ) -> "AppWrap":
73
72
  """Create a new AppWrap component.
74
73