reflex 0.6.8a2__py3-none-any.whl → 0.7.0__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 (247) hide show
  1. reflex/.templates/jinja/custom_components/pyproject.toml.jinja2 +1 -1
  2. reflex/.templates/jinja/web/pages/_app.js.jinja2 +7 -7
  3. reflex/.templates/jinja/web/pages/utils.js.jinja2 +3 -3
  4. reflex/.templates/web/components/reflex/radix_themes_color_mode_provider.js +1 -4
  5. reflex/.templates/web/utils/state.js +65 -36
  6. reflex/__init__.py +4 -17
  7. reflex/__init__.pyi +1 -2
  8. reflex/app.py +286 -129
  9. reflex/app_mixins/lifespan.py +9 -9
  10. reflex/app_mixins/middleware.py +6 -6
  11. reflex/app_module_for_backend.py +3 -7
  12. reflex/base.py +7 -7
  13. reflex/compiler/compiler.py +8 -0
  14. reflex/compiler/utils.py +57 -18
  15. reflex/components/base/app_wrap.pyi +16 -16
  16. reflex/components/base/bare.py +1 -1
  17. reflex/components/base/body.pyi +16 -16
  18. reflex/components/base/document.pyi +76 -76
  19. reflex/components/base/error_boundary.py +2 -1
  20. reflex/components/base/error_boundary.pyi +19 -22
  21. reflex/components/base/fragment.pyi +16 -16
  22. reflex/components/base/head.pyi +31 -31
  23. reflex/components/base/link.pyi +31 -31
  24. reflex/components/base/meta.py +2 -2
  25. reflex/components/base/meta.pyi +61 -61
  26. reflex/components/base/script.pyi +19 -19
  27. reflex/components/base/strict_mode.py +10 -0
  28. reflex/components/base/strict_mode.pyi +57 -0
  29. reflex/components/component.py +38 -77
  30. reflex/components/core/banner.py +159 -4
  31. reflex/components/core/banner.pyi +162 -76
  32. reflex/components/core/breakpoints.py +3 -1
  33. reflex/components/core/client_side_routing.py +1 -1
  34. reflex/components/core/client_side_routing.pyi +32 -32
  35. reflex/components/core/clipboard.pyi +17 -20
  36. reflex/components/core/cond.py +9 -10
  37. reflex/components/core/debounce.py +1 -1
  38. reflex/components/core/debounce.pyi +17 -17
  39. reflex/components/core/foreach.py +28 -3
  40. reflex/components/core/html.py +1 -1
  41. reflex/components/core/html.pyi +16 -16
  42. reflex/components/core/match.py +5 -5
  43. reflex/components/core/sticky.py +134 -0
  44. reflex/components/core/sticky.pyi +449 -0
  45. reflex/components/core/upload.py +2 -2
  46. reflex/components/core/upload.pyi +80 -88
  47. reflex/components/datadisplay/code.py +5 -14
  48. reflex/components/datadisplay/code.pyi +31 -31
  49. reflex/components/datadisplay/dataeditor.py +7 -4
  50. reflex/components/datadisplay/dataeditor.pyi +40 -54
  51. reflex/components/datadisplay/logo.py +13 -8
  52. reflex/components/datadisplay/shiki_code_block.py +14 -9
  53. reflex/components/datadisplay/shiki_code_block.pyi +46 -46
  54. reflex/components/dynamic.py +22 -3
  55. reflex/components/el/constants/reflex.py +1 -1
  56. reflex/components/el/element.py +1 -1
  57. reflex/components/el/element.pyi +16 -16
  58. reflex/components/el/elements/base.pyi +16 -16
  59. reflex/components/el/elements/forms.py +4 -4
  60. reflex/components/el/elements/forms.pyi +224 -258
  61. reflex/components/el/elements/inline.pyi +421 -421
  62. reflex/components/el/elements/media.pyi +376 -376
  63. reflex/components/el/elements/metadata.pyi +91 -91
  64. reflex/components/el/elements/other.pyi +106 -106
  65. reflex/components/el/elements/scripts.pyi +46 -46
  66. reflex/components/el/elements/sectioning.pyi +226 -226
  67. reflex/components/el/elements/tables.pyi +151 -151
  68. reflex/components/el/elements/typography.pyi +226 -226
  69. reflex/components/gridjs/datatable.pyi +31 -31
  70. reflex/components/lucide/icon.py +46 -8
  71. reflex/components/lucide/icon.pyi +85 -31
  72. reflex/components/markdown/markdown.py +10 -8
  73. reflex/components/markdown/markdown.pyi +16 -16
  74. reflex/components/moment/moment.py +2 -2
  75. reflex/components/moment/moment.pyi +17 -19
  76. reflex/components/next/base.pyi +16 -16
  77. reflex/components/next/image.py +16 -4
  78. reflex/components/next/image.pyi +22 -20
  79. reflex/components/next/link.py +1 -1
  80. reflex/components/next/link.pyi +16 -16
  81. reflex/components/next/video.pyi +16 -16
  82. reflex/components/plotly/__init__.py +29 -2
  83. reflex/components/plotly/plotly.py +240 -5
  84. reflex/components/plotly/plotly.pyi +799 -44
  85. reflex/components/props.py +3 -3
  86. reflex/components/radix/__init__.pyi +1 -1
  87. reflex/components/radix/primitives/accordion.py +9 -5
  88. reflex/components/radix/primitives/accordion.pyi +110 -108
  89. reflex/components/radix/primitives/base.pyi +31 -31
  90. reflex/components/radix/primitives/drawer.py +5 -2
  91. reflex/components/radix/primitives/drawer.pyi +179 -187
  92. reflex/components/radix/primitives/form.pyi +160 -172
  93. reflex/components/radix/primitives/progress.py +1 -1
  94. reflex/components/radix/primitives/progress.pyi +76 -76
  95. reflex/components/radix/primitives/slider.py +1 -1
  96. reflex/components/radix/primitives/slider.pyi +78 -82
  97. reflex/components/radix/themes/base.pyi +121 -121
  98. reflex/components/radix/themes/color_mode.py +11 -9
  99. reflex/components/radix/themes/color_mode.pyi +47 -49
  100. reflex/components/radix/themes/components/alert_dialog.py +3 -0
  101. reflex/components/radix/themes/components/alert_dialog.pyi +110 -112
  102. reflex/components/radix/themes/components/aspect_ratio.pyi +16 -16
  103. reflex/components/radix/themes/components/avatar.pyi +16 -16
  104. reflex/components/radix/themes/components/badge.pyi +16 -16
  105. reflex/components/radix/themes/components/button.pyi +16 -16
  106. reflex/components/radix/themes/components/callout.pyi +76 -76
  107. reflex/components/radix/themes/components/card.py +1 -1
  108. reflex/components/radix/themes/components/card.pyi +17 -17
  109. reflex/components/radix/themes/components/checkbox.pyi +49 -55
  110. reflex/components/radix/themes/components/checkbox_cards.pyi +31 -31
  111. reflex/components/radix/themes/components/checkbox_group.pyi +31 -31
  112. reflex/components/radix/themes/components/context_menu.py +5 -0
  113. reflex/components/radix/themes/components/context_menu.pyi +149 -155
  114. reflex/components/radix/themes/components/data_list.pyi +61 -61
  115. reflex/components/radix/themes/components/dialog.py +3 -0
  116. reflex/components/radix/themes/components/dialog.pyi +113 -117
  117. reflex/components/radix/themes/components/dropdown_menu.py +5 -0
  118. reflex/components/radix/themes/components/dropdown_menu.pyi +133 -137
  119. reflex/components/radix/themes/components/hover_card.py +3 -0
  120. reflex/components/radix/themes/components/hover_card.pyi +63 -67
  121. reflex/components/radix/themes/components/icon_button.py +2 -2
  122. reflex/components/radix/themes/components/icon_button.pyi +17 -16
  123. reflex/components/radix/themes/components/inset.pyi +16 -16
  124. reflex/components/radix/themes/components/popover.py +3 -0
  125. reflex/components/radix/themes/components/popover.pyi +68 -70
  126. reflex/components/radix/themes/components/progress.pyi +16 -16
  127. reflex/components/radix/themes/components/radio.pyi +16 -16
  128. reflex/components/radix/themes/components/radio_cards.py +2 -0
  129. reflex/components/radix/themes/components/radio_cards.pyi +32 -34
  130. reflex/components/radix/themes/components/radio_group.py +1 -1
  131. reflex/components/radix/themes/components/radio_group.pyi +62 -64
  132. reflex/components/radix/themes/components/scroll_area.pyi +16 -16
  133. reflex/components/radix/themes/components/segmented_control.pyi +32 -35
  134. reflex/components/radix/themes/components/select.py +4 -0
  135. reflex/components/radix/themes/components/select.pyi +145 -157
  136. reflex/components/radix/themes/components/separator.pyi +16 -16
  137. reflex/components/radix/themes/components/skeleton.py +3 -0
  138. reflex/components/radix/themes/components/skeleton.pyi +16 -16
  139. reflex/components/radix/themes/components/slider.pyi +22 -28
  140. reflex/components/radix/themes/components/spinner.pyi +16 -16
  141. reflex/components/radix/themes/components/switch.pyi +17 -19
  142. reflex/components/radix/themes/components/table.pyi +106 -106
  143. reflex/components/radix/themes/components/tabs.py +3 -0
  144. reflex/components/radix/themes/components/tabs.pyi +78 -82
  145. reflex/components/radix/themes/components/text_area.py +12 -0
  146. reflex/components/radix/themes/components/text_area.pyi +21 -33
  147. reflex/components/radix/themes/components/text_field.py +1 -1
  148. reflex/components/radix/themes/components/text_field.pyi +52 -80
  149. reflex/components/radix/themes/components/tooltip.py +6 -1
  150. reflex/components/radix/themes/components/tooltip.pyi +20 -21
  151. reflex/components/radix/themes/layout/__init__.pyi +1 -1
  152. reflex/components/radix/themes/layout/base.pyi +16 -16
  153. reflex/components/radix/themes/layout/box.pyi +16 -16
  154. reflex/components/radix/themes/layout/center.pyi +16 -16
  155. reflex/components/radix/themes/layout/container.pyi +16 -16
  156. reflex/components/radix/themes/layout/flex.pyi +16 -16
  157. reflex/components/radix/themes/layout/grid.pyi +16 -16
  158. reflex/components/radix/themes/layout/list.py +2 -2
  159. reflex/components/radix/themes/layout/list.pyi +76 -76
  160. reflex/components/radix/themes/layout/section.pyi +16 -16
  161. reflex/components/radix/themes/layout/spacer.pyi +16 -16
  162. reflex/components/radix/themes/layout/stack.py +2 -2
  163. reflex/components/radix/themes/layout/stack.pyi +46 -46
  164. reflex/components/radix/themes/typography/blockquote.pyi +16 -16
  165. reflex/components/radix/themes/typography/code.pyi +16 -16
  166. reflex/components/radix/themes/typography/heading.pyi +16 -16
  167. reflex/components/radix/themes/typography/link.py +1 -1
  168. reflex/components/radix/themes/typography/link.pyi +16 -16
  169. reflex/components/radix/themes/typography/text.py +2 -2
  170. reflex/components/radix/themes/typography/text.pyi +106 -106
  171. reflex/components/react_player/audio.pyi +33 -39
  172. reflex/components/react_player/react_player.py +1 -1
  173. reflex/components/react_player/react_player.pyi +32 -38
  174. reflex/components/react_player/video.pyi +33 -39
  175. reflex/components/recharts/__init__.py +2 -0
  176. reflex/components/recharts/__init__.pyi +2 -0
  177. reflex/components/recharts/cartesian.pyi +282 -282
  178. reflex/components/recharts/charts.py +15 -15
  179. reflex/components/recharts/charts.pyi +164 -164
  180. reflex/components/recharts/general.py +19 -4
  181. reflex/components/recharts/general.pyi +132 -81
  182. reflex/components/recharts/polar.py +2 -2
  183. reflex/components/recharts/polar.pyi +55 -55
  184. reflex/components/recharts/recharts.py +4 -4
  185. reflex/components/recharts/recharts.pyi +31 -31
  186. reflex/components/sonner/toast.py +15 -13
  187. reflex/components/sonner/toast.pyi +22 -22
  188. reflex/components/suneditor/editor.py +6 -4
  189. reflex/components/suneditor/editor.pyi +26 -40
  190. reflex/components/tags/iter_tag.py +3 -3
  191. reflex/components/tags/tag.py +25 -3
  192. reflex/config.py +48 -15
  193. reflex/constants/__init__.py +1 -0
  194. reflex/constants/base.py +4 -1
  195. reflex/constants/compiler.py +5 -2
  196. reflex/constants/config.py +8 -1
  197. reflex/constants/installer.py +9 -9
  198. reflex/constants/style.py +1 -1
  199. reflex/custom_components/custom_components.py +18 -10
  200. reflex/event.py +221 -231
  201. reflex/experimental/__init__.py +19 -11
  202. reflex/experimental/client_state.py +53 -28
  203. reflex/experimental/hooks.py +5 -5
  204. reflex/experimental/layout.py +8 -5
  205. reflex/experimental/layout.pyi +79 -83
  206. reflex/experimental/misc.py +3 -3
  207. reflex/istate/wrappers.py +1 -1
  208. reflex/middleware/hydrate_middleware.py +2 -2
  209. reflex/model.py +11 -6
  210. reflex/page.py +5 -5
  211. reflex/reflex.py +104 -26
  212. reflex/route.py +1 -1
  213. reflex/state.py +358 -401
  214. reflex/style.py +27 -3
  215. reflex/testing.py +29 -23
  216. reflex/utils/build.py +6 -2
  217. reflex/utils/codespaces.py +1 -4
  218. reflex/utils/compat.py +6 -5
  219. reflex/utils/console.py +71 -16
  220. reflex/utils/exceptions.py +89 -26
  221. reflex/utils/exec.py +69 -74
  222. reflex/utils/export.py +6 -1
  223. reflex/utils/format.py +8 -40
  224. reflex/utils/imports.py +5 -2
  225. reflex/utils/lazy_loader.py +7 -1
  226. reflex/utils/path_ops.py +74 -14
  227. reflex/utils/prerequisites.py +345 -68
  228. reflex/utils/processes.py +45 -32
  229. reflex/utils/pyi_generator.py +39 -33
  230. reflex/utils/registry.py +4 -4
  231. reflex/utils/serializers.py +1 -1
  232. reflex/utils/telemetry.py +5 -4
  233. reflex/utils/types.py +42 -18
  234. reflex/vars/base.py +695 -330
  235. reflex/vars/datetime.py +6 -7
  236. reflex/vars/dep_tracking.py +344 -0
  237. reflex/vars/function.py +11 -5
  238. reflex/vars/number.py +31 -43
  239. reflex/vars/object.py +74 -64
  240. reflex/vars/sequence.py +79 -67
  241. {reflex-0.6.8a2.dist-info → reflex-0.7.0.dist-info}/METADATA +7 -8
  242. reflex-0.7.0.dist-info/RECORD +401 -0
  243. {reflex-0.6.8a2.dist-info → reflex-0.7.0.dist-info}/WHEEL +1 -1
  244. reflex/experimental/assets.py +0 -37
  245. reflex-0.6.8a2.dist-info/RECORD +0 -397
  246. {reflex-0.6.8a2.dist-info → reflex-0.7.0.dist-info}/LICENSE +0 -0
  247. {reflex-0.6.8a2.dist-info → reflex-0.7.0.dist-info}/entry_points.txt +0 -0
reflex/utils/processes.py CHANGED
@@ -15,12 +15,14 @@ from typing import Callable, Generator, List, Optional, Tuple, Union
15
15
  import psutil
16
16
  import typer
17
17
  from redis.exceptions import RedisError
18
+ from rich.progress import Progress
18
19
 
19
20
  from reflex import constants
21
+ from reflex.config import environment
20
22
  from reflex.utils import console, path_ops, prerequisites
21
23
 
22
24
 
23
- def kill(pid):
25
+ def kill(pid: int):
24
26
  """Kill a process.
25
27
 
26
28
  Args:
@@ -48,7 +50,7 @@ def get_num_workers() -> int:
48
50
  return (os.cpu_count() or 1) * 2 + 1
49
51
 
50
52
 
51
- def get_process_on_port(port) -> Optional[psutil.Process]:
53
+ def get_process_on_port(port: int) -> Optional[psutil.Process]:
52
54
  """Get the process on the given port.
53
55
 
54
56
  Args:
@@ -62,7 +64,7 @@ def get_process_on_port(port) -> Optional[psutil.Process]:
62
64
  psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess
63
65
  ):
64
66
  if importlib.metadata.version("psutil") >= "6.0.0":
65
- conns = proc.net_connections(kind="inet") # type: ignore
67
+ conns = proc.net_connections(kind="inet")
66
68
  else:
67
69
  conns = proc.connections(kind="inet")
68
70
  for conn in conns:
@@ -71,7 +73,7 @@ def get_process_on_port(port) -> Optional[psutil.Process]:
71
73
  return None
72
74
 
73
75
 
74
- def is_process_on_port(port) -> bool:
76
+ def is_process_on_port(port: int) -> bool:
75
77
  """Check if a process is running on the given port.
76
78
 
77
79
  Args:
@@ -83,7 +85,7 @@ def is_process_on_port(port) -> bool:
83
85
  return get_process_on_port(port) is not None
84
86
 
85
87
 
86
- def kill_process_on_port(port):
88
+ def kill_process_on_port(port: int):
87
89
  """Kill the process on the given port.
88
90
 
89
91
  Args:
@@ -91,10 +93,10 @@ def kill_process_on_port(port):
91
93
  """
92
94
  if get_process_on_port(port) is not None:
93
95
  with contextlib.suppress(psutil.AccessDenied):
94
- get_process_on_port(port).kill() # type: ignore
96
+ get_process_on_port(port).kill() # pyright: ignore [reportOptionalMemberAccess]
95
97
 
96
98
 
97
- def change_port(port: str, _type: str) -> str:
99
+ def change_port(port: int, _type: str) -> int:
98
100
  """Change the port.
99
101
 
100
102
  Args:
@@ -105,7 +107,7 @@ def change_port(port: str, _type: str) -> str:
105
107
  The new port.
106
108
 
107
109
  """
108
- new_port = str(int(port) + 1)
110
+ new_port = port + 1
109
111
  if is_process_on_port(new_port):
110
112
  return change_port(new_port, _type)
111
113
  console.info(
@@ -114,7 +116,7 @@ def change_port(port: str, _type: str) -> str:
114
116
  return new_port
115
117
 
116
118
 
117
- def handle_port(service_name: str, port: str, default_port: str) -> str:
119
+ def handle_port(service_name: str, port: int, default_port: int) -> int:
118
120
  """Change port if the specified port is in use and is not explicitly specified as a CLI arg or config arg.
119
121
  otherwise tell the user the port is in use and exit the app.
120
122
 
@@ -133,7 +135,7 @@ def handle_port(service_name: str, port: str, default_port: str) -> str:
133
135
  Exit:when the port is in use.
134
136
  """
135
137
  if is_process_on_port(port):
136
- if int(port) == int(default_port):
138
+ if port == int(default_port):
137
139
  return change_port(port, service_name)
138
140
  else:
139
141
  console.error(f"{service_name.capitalize()} port: {port} is already in use")
@@ -141,7 +143,12 @@ def handle_port(service_name: str, port: str, default_port: str) -> str:
141
143
  return port
142
144
 
143
145
 
144
- def new_process(args, run: bool = False, show_logs: bool = False, **kwargs):
146
+ def new_process(
147
+ args: str | list[str] | list[str | None] | list[str | Path | None],
148
+ run: bool = False,
149
+ show_logs: bool = False,
150
+ **kwargs,
151
+ ):
145
152
  """Wrapper over subprocess.Popen to unify the launch of child processes.
146
153
 
147
154
  Args:
@@ -156,24 +163,30 @@ def new_process(args, run: bool = False, show_logs: bool = False, **kwargs):
156
163
  Raises:
157
164
  Exit: When attempting to run a command with a None value.
158
165
  """
159
- node_bin_path = str(path_ops.get_node_bin_path())
160
- if not node_bin_path and not prerequisites.CURRENTLY_INSTALLING_NODE:
161
- console.warn(
162
- "The path to the Node binary could not be found. Please ensure that Node is properly "
163
- "installed and added to your system's PATH environment variable or try running "
164
- "`reflex init` again."
165
- )
166
- if None in args:
166
+ # Check for invalid command first.
167
+ if isinstance(args, list) and None in args:
167
168
  console.error(f"Invalid command: {args}")
168
169
  raise typer.Exit(1)
169
- # Add the node bin path to the PATH environment variable.
170
+
171
+ path_env: str = os.environ.get("PATH", "")
172
+
173
+ # Add node_bin_path to the PATH environment variable.
174
+ if not environment.REFLEX_BACKEND_ONLY.get():
175
+ node_bin_path = str(path_ops.get_node_bin_path())
176
+ if not node_bin_path and not prerequisites.CURRENTLY_INSTALLING_NODE:
177
+ console.warn(
178
+ "The path to the Node binary could not be found. Please ensure that Node is properly "
179
+ "installed and added to your system's PATH environment variable or try running "
180
+ "`reflex init` again."
181
+ )
182
+ path_env = os.pathsep.join([node_bin_path, path_env])
183
+
170
184
  env: dict[str, str] = {
171
185
  **os.environ,
172
- "PATH": os.pathsep.join(
173
- [node_bin_path if node_bin_path else "", os.environ["PATH"]]
174
- ), # type: ignore
186
+ "PATH": path_env,
175
187
  **kwargs.pop("env", {}),
176
188
  }
189
+
177
190
  kwargs = {
178
191
  "env": env,
179
192
  "stderr": None if show_logs else subprocess.STDOUT,
@@ -185,7 +198,7 @@ def new_process(args, run: bool = False, show_logs: bool = False, **kwargs):
185
198
  }
186
199
  console.debug(f"Running command: {args}")
187
200
  fn = subprocess.run if run else subprocess.Popen
188
- return fn(args, **kwargs)
201
+ return fn(args, **kwargs) # pyright: ignore [reportCallIssue, reportArgumentType]
189
202
 
190
203
 
191
204
  @contextlib.contextmanager
@@ -206,14 +219,14 @@ def run_concurrently_context(
206
219
  return
207
220
 
208
221
  # Convert the functions to tuples.
209
- fns = [fn if isinstance(fn, tuple) else (fn,) for fn in fns] # type: ignore
222
+ fns = [fn if isinstance(fn, tuple) else (fn,) for fn in fns] # pyright: ignore [reportAssignmentType]
210
223
 
211
224
  # Run the functions concurrently.
212
225
  executor = None
213
226
  try:
214
227
  executor = futures.ThreadPoolExecutor(max_workers=len(fns))
215
228
  # Submit the tasks.
216
- tasks = [executor.submit(*fn) for fn in fns] # type: ignore
229
+ tasks = [executor.submit(*fn) for fn in fns] # pyright: ignore [reportArgumentType]
217
230
 
218
231
  # Yield control back to the main thread while tasks are running.
219
232
  yield tasks
@@ -241,7 +254,7 @@ def run_concurrently(*fns: Union[Callable, Tuple]) -> None:
241
254
  def stream_logs(
242
255
  message: str,
243
256
  process: subprocess.Popen,
244
- progress=None,
257
+ progress: Progress | None = None,
245
258
  suppress_errors: bool = False,
246
259
  analytics_enabled: bool = False,
247
260
  ):
@@ -361,7 +374,7 @@ def get_command_with_loglevel(command: list[str]) -> list[str]:
361
374
  The updated command list
362
375
  """
363
376
  npm_path = path_ops.get_npm_path()
364
- npm_path = str(Path(npm_path).resolve()) if npm_path else npm_path
377
+ npm_path = str(npm_path) if npm_path else None
365
378
 
366
379
  if command[0] == npm_path:
367
380
  return [*command, "--loglevel", "silly"]
@@ -369,10 +382,10 @@ def get_command_with_loglevel(command: list[str]) -> list[str]:
369
382
 
370
383
 
371
384
  def run_process_with_fallback(
372
- args,
385
+ args: list[str],
373
386
  *,
374
- show_status_message,
375
- fallback=None,
387
+ show_status_message: str,
388
+ fallback: str | list | None = None,
376
389
  analytics_enabled: bool = False,
377
390
  **kwargs,
378
391
  ):
@@ -411,7 +424,7 @@ def run_process_with_fallback(
411
424
  )
412
425
 
413
426
 
414
- def execute_command_and_return_output(command) -> str | None:
427
+ def execute_command_and_return_output(command: str) -> str | None:
415
428
  """Execute a command and return the output.
416
429
 
417
430
  Args:
@@ -75,7 +75,6 @@ DEFAULT_IMPORTS = {
75
75
  "EventHandler",
76
76
  "EventSpec",
77
77
  "EventType",
78
- "BASE_STATE",
79
78
  "KeyInputInfo",
80
79
  ],
81
80
  "reflex.style": ["Style"],
@@ -83,7 +82,7 @@ DEFAULT_IMPORTS = {
83
82
  }
84
83
 
85
84
 
86
- def _walk_files(path):
85
+ def _walk_files(path: str | Path):
87
86
  """Walk all files in a path.
88
87
  This can be replaced with Path.walk() in python3.12.
89
88
 
@@ -114,7 +113,9 @@ def _relative_to_pwd(path: Path) -> Path:
114
113
  return path
115
114
 
116
115
 
117
- def _get_type_hint(value, type_hint_globals, is_optional=True) -> str:
116
+ def _get_type_hint(
117
+ value: Any, type_hint_globals: dict, is_optional: bool = True
118
+ ) -> str:
118
119
  """Resolve the type hint for value.
119
120
 
120
121
  Args:
@@ -229,7 +230,7 @@ def _generate_imports(
229
230
  """
230
231
  return [
231
232
  *[
232
- ast.ImportFrom(module=name, names=[ast.alias(name=val) for val in values])
233
+ ast.ImportFrom(module=name, names=[ast.alias(name=val) for val in values]) # pyright: ignore [reportCallIssue]
233
234
  for name, values in DEFAULT_IMPORTS.items()
234
235
  ],
235
236
  ast.Import([ast.alias("reflex")]),
@@ -367,7 +368,7 @@ def _extract_class_props_as_ast_nodes(
367
368
  # Try to get default from pydantic field definition.
368
369
  default = target_class.__fields__[name].default
369
370
  if isinstance(default, Var):
370
- default = default._decode() # type: ignore
371
+ default = default._decode()
371
372
 
372
373
  kwargs.append(
373
374
  (
@@ -383,7 +384,7 @@ def _extract_class_props_as_ast_nodes(
383
384
  return kwargs
384
385
 
385
386
 
386
- def type_to_ast(typ, cls: type) -> ast.AST:
387
+ def type_to_ast(typ: Any, cls: type) -> ast.AST:
387
388
  """Converts any type annotation into its AST representation.
388
389
  Handles nested generic types, unions, etc.
389
390
 
@@ -434,14 +435,16 @@ def type_to_ast(typ, cls: type) -> ast.AST:
434
435
  if len(arg_nodes) == 1:
435
436
  slice_value = arg_nodes[0]
436
437
  else:
437
- slice_value = ast.Tuple(elts=arg_nodes, ctx=ast.Load())
438
+ slice_value = ast.Tuple(elts=arg_nodes, ctx=ast.Load()) # pyright: ignore [reportArgumentType]
438
439
 
439
440
  return ast.Subscript(
440
- value=ast.Name(id=base_name), slice=ast.Index(value=slice_value), ctx=ast.Load()
441
+ value=ast.Name(id=base_name),
442
+ slice=ast.Index(value=slice_value), # pyright: ignore [reportArgumentType]
443
+ ctx=ast.Load(),
441
444
  )
442
445
 
443
446
 
444
- def _get_parent_imports(func):
447
+ def _get_parent_imports(func: Callable):
445
448
  _imports = {"reflex.vars": ["Var"]}
446
449
  for type_hint in inspect.get_annotations(func).values():
447
450
  try:
@@ -498,7 +501,7 @@ def _generate_component_create_functiondef(
498
501
 
499
502
  def figure_out_return_type(annotation: Any):
500
503
  if inspect.isclass(annotation) and issubclass(annotation, inspect._empty):
501
- return ast.Name(id="EventType[..., BASE_STATE]")
504
+ return ast.Name(id="EventType[Any]")
502
505
 
503
506
  if not isinstance(annotation, str) and get_origin(annotation) is tuple:
504
507
  arguments = get_args(annotation)
@@ -514,8 +517,10 @@ def _generate_component_create_functiondef(
514
517
  # Get all prefixes of the type arguments
515
518
  all_count_args_type = [
516
519
  ast.Name(
517
- f"EventType[[{', '.join([ast.unparse(arg) for arg in type_args[:i]])}], BASE_STATE]"
520
+ f"EventType[{', '.join([ast.unparse(arg) for arg in type_args[:i]])}]"
518
521
  )
522
+ if i > 0
523
+ else ast.Name("EventType[()]")
519
524
  for i in range(len(type_args) + 1)
520
525
  ]
521
526
 
@@ -528,7 +533,7 @@ def _generate_component_create_functiondef(
528
533
  inside_of_tuple = annotation.removeprefix("Tuple[").removesuffix("]")
529
534
 
530
535
  if inside_of_tuple == "()":
531
- return ast.Name(id="EventType[[], BASE_STATE]")
536
+ return ast.Name(id="EventType[()]")
532
537
 
533
538
  arguments = [""]
534
539
 
@@ -555,16 +560,16 @@ def _generate_component_create_functiondef(
555
560
  ]
556
561
 
557
562
  all_count_args_type = [
558
- ast.Name(
559
- f"EventType[[{', '.join(arguments_without_var[:i])}], BASE_STATE]"
560
- )
563
+ ast.Name(f"EventType[{', '.join(arguments_without_var[:i])}]")
564
+ if i > 0
565
+ else ast.Name("EventType[()]")
561
566
  for i in range(len(arguments) + 1)
562
567
  ]
563
568
 
564
569
  return ast.Name(
565
570
  id=f"Union[{', '.join(map(ast.unparse, all_count_args_type))}]"
566
571
  )
567
- return ast.Name(id="EventType[..., BASE_STATE]")
572
+ return ast.Name(id="EventType[Any]")
568
573
 
569
574
  event_triggers = clz().get_event_triggers()
570
575
 
@@ -575,7 +580,7 @@ def _generate_component_create_functiondef(
575
580
  arg=trigger,
576
581
  annotation=ast.Subscript(
577
582
  ast.Name("Optional"),
578
- ast.Index( # type: ignore
583
+ ast.Index( # pyright: ignore [reportArgumentType]
579
584
  value=ast.Name(
580
585
  id=ast.unparse(
581
586
  figure_out_return_type(
@@ -618,10 +623,10 @@ def _generate_component_create_functiondef(
618
623
  defaults=[],
619
624
  )
620
625
 
621
- definition = ast.FunctionDef(
626
+ definition = ast.FunctionDef( # pyright: ignore [reportCallIssue]
622
627
  name="create",
623
628
  args=create_args,
624
- body=[
629
+ body=[ # pyright: ignore [reportArgumentType]
625
630
  ast.Expr(
626
631
  value=ast.Constant(
627
632
  value=_generate_docstrings(
@@ -630,7 +635,7 @@ def _generate_component_create_functiondef(
630
635
  ),
631
636
  ),
632
637
  ast.Expr(
633
- value=ast.Ellipsis(),
638
+ value=ast.Constant(value=Ellipsis),
634
639
  ),
635
640
  ],
636
641
  decorator_list=[
@@ -641,7 +646,7 @@ def _generate_component_create_functiondef(
641
646
  else [ast.Name(id="classmethod")]
642
647
  ),
643
648
  ],
644
- lineno=node.lineno if node is not None else None,
649
+ lineno=node.lineno if node is not None else None, # pyright: ignore [reportArgumentType]
645
650
  returns=ast.Constant(value=clz.__name__),
646
651
  )
647
652
  return definition
@@ -680,7 +685,7 @@ def _generate_staticmethod_call_functiondef(
680
685
  else []
681
686
  ),
682
687
  )
683
- definition = ast.FunctionDef(
688
+ definition = ast.FunctionDef( # pyright: ignore [reportCallIssue]
684
689
  name="__call__",
685
690
  args=call_args,
686
691
  body=[
@@ -690,11 +695,12 @@ def _generate_staticmethod_call_functiondef(
690
695
  ),
691
696
  ],
692
697
  decorator_list=[ast.Name(id="staticmethod")],
693
- lineno=node.lineno if node is not None else None,
698
+ lineno=node.lineno if node is not None else None, # pyright: ignore [reportArgumentType]
694
699
  returns=ast.Constant(
695
700
  value=_get_type_hint(
696
701
  typing.get_type_hints(clz.__call__).get("return", None),
697
702
  type_hint_globals,
703
+ is_optional=False,
698
704
  )
699
705
  ),
700
706
  )
@@ -726,17 +732,17 @@ def _generate_namespace_call_functiondef(
726
732
  clz = classes[clz_name]
727
733
 
728
734
  if not hasattr(clz.__call__, "__self__"):
729
- return _generate_staticmethod_call_functiondef(node, clz, type_hint_globals) # type: ignore
735
+ return _generate_staticmethod_call_functiondef(node, clz, type_hint_globals) # pyright: ignore [reportArgumentType]
730
736
 
731
737
  # Determine which class is wrapped by the namespace __call__ method
732
738
  component_clz = clz.__call__.__self__
733
739
 
734
- if clz.__call__.__func__.__name__ != "create":
740
+ if clz.__call__.__func__.__name__ != "create": # pyright: ignore [reportFunctionMemberAccess]
735
741
  return None
736
742
 
737
743
  definition = _generate_component_create_functiondef(
738
744
  node=None,
739
- clz=component_clz, # type: ignore
745
+ clz=component_clz, # pyright: ignore [reportArgumentType]
740
746
  type_hint_globals=type_hint_globals,
741
747
  )
742
748
  definition.name = "__call__"
@@ -816,7 +822,7 @@ class StubGenerator(ast.NodeTransformer):
816
822
  The modified Module node.
817
823
  """
818
824
  self.generic_visit(node)
819
- return self._remove_docstring(node) # type: ignore
825
+ return self._remove_docstring(node) # pyright: ignore [reportReturnType]
820
826
 
821
827
  def visit_Import(
822
828
  self, node: ast.Import | ast.ImportFrom
@@ -914,7 +920,7 @@ class StubGenerator(ast.NodeTransformer):
914
920
  node.body.append(call_definition)
915
921
  if not node.body:
916
922
  # We should never return an empty body.
917
- node.body.append(ast.Expr(value=ast.Ellipsis()))
923
+ node.body.append(ast.Expr(value=ast.Constant(value=Ellipsis)))
918
924
  self.current_class = None
919
925
  return node
920
926
 
@@ -941,9 +947,9 @@ class StubGenerator(ast.NodeTransformer):
941
947
  if node.name.startswith("_") and node.name != "__call__":
942
948
  return None # remove private methods
943
949
 
944
- if node.body[-1] != ast.Expr(value=ast.Ellipsis()):
950
+ if node.body[-1] != ast.Expr(value=ast.Constant(value=Ellipsis)):
945
951
  # Blank out the function body for public functions.
946
- node.body = [ast.Expr(value=ast.Ellipsis())]
952
+ node.body = [ast.Expr(value=ast.Constant(value=Ellipsis))]
947
953
  return node
948
954
 
949
955
  def visit_Assign(self, node: ast.Assign) -> ast.Assign | None:
@@ -1050,7 +1056,7 @@ class PyiGenerator:
1050
1056
  pyi_path.write_text(pyi_content)
1051
1057
  logger.info(f"Wrote {relpath}")
1052
1058
 
1053
- def _get_init_lazy_imports(self, mod, new_tree):
1059
+ def _get_init_lazy_imports(self, mod: tuple | ModuleType, new_tree: ast.AST):
1054
1060
  # retrieve the _SUBMODULES and _SUBMOD_ATTRS from an init file if present.
1055
1061
  sub_mods = getattr(mod, "_SUBMODULES", None)
1056
1062
  sub_mod_attrs = getattr(mod, "_SUBMOD_ATTRS", None)
@@ -1077,7 +1083,7 @@ class PyiGenerator:
1077
1083
  + (
1078
1084
  " # type: ignore"
1079
1085
  if mod in pyright_ignore_imports
1080
- else " # noqa" # ignore ruff formatting here for cases like rx.list.
1086
+ else " # noqa: F401" # ignore ruff formatting here for cases like rx.list.
1081
1087
  if isinstance(mod, tuple)
1082
1088
  else ""
1083
1089
  )
@@ -1136,7 +1142,7 @@ class PyiGenerator:
1136
1142
  if pyi_path:
1137
1143
  self.written_files.append(pyi_path)
1138
1144
 
1139
- def scan_all(self, targets, changed_files: list[Path] | None = None):
1145
+ def scan_all(self, targets: list, changed_files: list[Path] | None = None):
1140
1146
  """Scan all targets for class inheriting Component and generate the .pyi files.
1141
1147
 
1142
1148
  Args:
reflex/utils/registry.py CHANGED
@@ -22,15 +22,15 @@ def latency(registry: str) -> int:
22
22
  return 10_000_000
23
23
 
24
24
 
25
- def average_latency(registry, attempts: int = 3) -> int:
25
+ def average_latency(registry: str, attempts: int = 3) -> int:
26
26
  """Get the average latency of a registry.
27
27
 
28
28
  Args:
29
- registry (str): The URL of the registry.
30
- attempts (int): The number of attempts to make. Defaults to 10.
29
+ registry: The URL of the registry.
30
+ attempts: The number of attempts to make. Defaults to 10.
31
31
 
32
32
  Returns:
33
- int: The average latency of the registry in microseconds.
33
+ The average latency of the registry in microseconds.
34
34
  """
35
35
  return sum(latency(registry) for _ in range(attempts)) // attempts
36
36
 
@@ -476,7 +476,7 @@ try:
476
476
  base64_image = base64.b64encode(image_bytes).decode("utf-8")
477
477
  try:
478
478
  # Newer method to get the mime type, but does not always work.
479
- mime_type = image.get_format_mimetype() # type: ignore
479
+ mime_type = image.get_format_mimetype() # pyright: ignore [reportAttributeAccessIssue]
480
480
  except AttributeError:
481
481
  try:
482
482
  # Fallback method
reflex/utils/telemetry.py CHANGED
@@ -122,7 +122,7 @@ def _prepare_event(event: str, **kwargs) -> dict:
122
122
  return {}
123
123
 
124
124
  if UTC is None:
125
- # for python 3.9 & 3.10
125
+ # for python 3.10
126
126
  stamp = datetime.utcnow().isoformat()
127
127
  else:
128
128
  # for python 3.11 & 3.12
@@ -156,12 +156,13 @@ def _prepare_event(event: str, **kwargs) -> dict:
156
156
  def _send_event(event_data: dict) -> bool:
157
157
  try:
158
158
  httpx.post(POSTHOG_API_URL, json=event_data)
159
- return True
160
159
  except Exception:
161
160
  return False
161
+ else:
162
+ return True
162
163
 
163
164
 
164
- def _send(event, telemetry_enabled, **kwargs):
165
+ def _send(event: str, telemetry_enabled: bool | None, **kwargs):
165
166
  from reflex.config import get_config
166
167
 
167
168
  # Get the telemetry_enabled from the config if it is not specified.
@@ -188,7 +189,7 @@ def send(event: str, telemetry_enabled: bool | None = None, **kwargs):
188
189
  kwargs: Additional data to send with the event.
189
190
  """
190
191
 
191
- async def async_send(event, telemetry_enabled, **kwargs):
192
+ async def async_send(event: str, telemetry_enabled: bool | None, **kwargs):
192
193
  return _send(event, telemetry_enabled, **kwargs)
193
194
 
194
195
  try: