reflex 0.6.4a3__py3-none-any.whl → 0.6.5__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 (228) hide show
  1. reflex/.templates/jinja/web/pages/custom_component.js.jinja2 +0 -14
  2. reflex/.templates/jinja/web/pages/utils.js.jinja2 +4 -8
  3. reflex/.templates/web/components/shiki/code.js +16 -11
  4. reflex/.templates/web/utils/state.js +29 -21
  5. reflex/__init__.py +4 -0
  6. reflex/__init__.pyi +4 -0
  7. reflex/app.py +148 -154
  8. reflex/app_mixins/lifespan.py +5 -1
  9. reflex/app_mixins/middleware.py +3 -1
  10. reflex/app_mixins/mixin.py +3 -2
  11. reflex/base.py +2 -4
  12. reflex/compiler/compiler.py +111 -37
  13. reflex/components/base/app_wrap.pyi +17 -17
  14. reflex/components/base/bare.py +72 -3
  15. reflex/components/base/body.pyi +17 -17
  16. reflex/components/base/document.pyi +81 -81
  17. reflex/components/base/error_boundary.pyi +25 -18
  18. reflex/components/base/fragment.pyi +17 -17
  19. reflex/components/base/head.pyi +33 -33
  20. reflex/components/base/link.pyi +33 -33
  21. reflex/components/base/meta.pyi +65 -65
  22. reflex/components/base/script.py +4 -4
  23. reflex/components/base/script.pyi +23 -20
  24. reflex/components/component.py +250 -31
  25. reflex/components/core/banner.py +1 -1
  26. reflex/components/core/banner.pyi +81 -81
  27. reflex/components/core/client_side_routing.pyi +33 -33
  28. reflex/components/core/clipboard.py +2 -2
  29. reflex/components/core/clipboard.pyi +24 -18
  30. reflex/components/core/debounce.py +2 -2
  31. reflex/components/core/debounce.pyi +18 -18
  32. reflex/components/core/html.pyi +17 -17
  33. reflex/components/core/upload.py +90 -28
  34. reflex/components/core/upload.pyi +128 -72
  35. reflex/components/datadisplay/code.py +55 -40
  36. reflex/components/datadisplay/code.pyi +46 -44
  37. reflex/components/datadisplay/dataeditor.py +21 -20
  38. reflex/components/datadisplay/dataeditor.pyi +103 -35
  39. reflex/components/datadisplay/shiki_code_block.py +60 -27
  40. reflex/components/datadisplay/shiki_code_block.pyi +86 -65
  41. reflex/components/dynamic.py +9 -5
  42. reflex/components/el/element.pyi +17 -17
  43. reflex/components/el/elements/base.pyi +17 -17
  44. reflex/components/el/elements/forms.py +12 -3
  45. reflex/components/el/elements/forms.pyi +293 -233
  46. reflex/components/el/elements/inline.pyi +449 -449
  47. reflex/components/el/elements/media.pyi +401 -401
  48. reflex/components/el/elements/metadata.pyi +97 -97
  49. reflex/components/el/elements/other.pyi +113 -113
  50. reflex/components/el/elements/scripts.pyi +49 -49
  51. reflex/components/el/elements/sectioning.pyi +241 -241
  52. reflex/components/el/elements/tables.pyi +161 -161
  53. reflex/components/el/elements/typography.pyi +241 -241
  54. reflex/components/gridjs/datatable.pyi +33 -33
  55. reflex/components/lucide/icon.py +1 -1
  56. reflex/components/lucide/icon.pyi +33 -33
  57. reflex/components/markdown/markdown.py +180 -49
  58. reflex/components/markdown/markdown.pyi +36 -19
  59. reflex/components/moment/moment.py +17 -21
  60. reflex/components/moment/moment.pyi +26 -21
  61. reflex/components/next/base.pyi +17 -17
  62. reflex/components/next/image.py +3 -3
  63. reflex/components/next/image.pyi +21 -19
  64. reflex/components/next/link.pyi +17 -17
  65. reflex/components/next/video.pyi +17 -17
  66. reflex/components/plotly/plotly.py +79 -78
  67. reflex/components/plotly/plotly.pyi +91 -41
  68. reflex/components/props.py +34 -0
  69. reflex/components/radix/primitives/accordion.py +15 -8
  70. reflex/components/radix/primitives/accordion.pyi +121 -118
  71. reflex/components/radix/primitives/base.pyi +33 -33
  72. reflex/components/radix/primitives/drawer.py +41 -20
  73. reflex/components/radix/primitives/drawer.pyi +279 -190
  74. reflex/components/radix/primitives/form.py +2 -2
  75. reflex/components/radix/primitives/form.pyi +200 -167
  76. reflex/components/radix/primitives/progress.pyi +81 -81
  77. reflex/components/radix/primitives/slider.pyi +89 -83
  78. reflex/components/radix/themes/base.py +30 -1
  79. reflex/components/radix/themes/base.pyi +286 -113
  80. reflex/components/radix/themes/color_mode.py +17 -9
  81. reflex/components/radix/themes/color_mode.pyi +68 -56
  82. reflex/components/radix/themes/components/alert_dialog.py +8 -5
  83. reflex/components/radix/themes/components/alert_dialog.pyi +125 -117
  84. reflex/components/radix/themes/components/aspect_ratio.pyi +17 -17
  85. reflex/components/radix/themes/components/avatar.py +1 -5
  86. reflex/components/radix/themes/components/avatar.pyi +17 -17
  87. reflex/components/radix/themes/components/badge.py +1 -5
  88. reflex/components/radix/themes/components/badge.pyi +17 -17
  89. reflex/components/radix/themes/components/button.pyi +18 -21
  90. reflex/components/radix/themes/components/callout.py +1 -4
  91. reflex/components/radix/themes/components/callout.pyi +81 -81
  92. reflex/components/radix/themes/components/card.py +1 -3
  93. reflex/components/radix/themes/components/card.pyi +17 -17
  94. reflex/components/radix/themes/components/checkbox.py +4 -8
  95. reflex/components/radix/themes/components/checkbox.pyi +61 -52
  96. reflex/components/radix/themes/components/checkbox_cards.pyi +33 -33
  97. reflex/components/radix/themes/components/checkbox_group.pyi +33 -33
  98. reflex/components/radix/themes/components/context_menu.py +121 -28
  99. reflex/components/radix/themes/components/context_menu.pyi +250 -147
  100. reflex/components/radix/themes/components/data_list.pyi +65 -65
  101. reflex/components/radix/themes/components/dialog.py +11 -11
  102. reflex/components/radix/themes/components/dialog.pyi +135 -120
  103. reflex/components/radix/themes/components/dropdown_menu.py +14 -25
  104. reflex/components/radix/themes/components/dropdown_menu.pyi +157 -145
  105. reflex/components/radix/themes/components/hover_card.py +19 -7
  106. reflex/components/radix/themes/components/hover_card.pyi +102 -67
  107. reflex/components/radix/themes/components/icon_button.pyi +18 -21
  108. reflex/components/radix/themes/components/inset.py +1 -3
  109. reflex/components/radix/themes/components/inset.pyi +17 -17
  110. reflex/components/radix/themes/components/popover.py +22 -13
  111. reflex/components/radix/themes/components/popover.pyi +98 -72
  112. reflex/components/radix/themes/components/progress.pyi +17 -17
  113. reflex/components/radix/themes/components/radio.pyi +17 -17
  114. reflex/components/radix/themes/components/radio_cards.py +2 -2
  115. reflex/components/radix/themes/components/radio_cards.pyi +37 -34
  116. reflex/components/radix/themes/components/radio_group.py +3 -7
  117. reflex/components/radix/themes/components/radio_group.pyi +69 -66
  118. reflex/components/radix/themes/components/scroll_area.py +1 -3
  119. reflex/components/radix/themes/components/scroll_area.pyi +17 -17
  120. reflex/components/radix/themes/components/segmented_control.pyi +37 -34
  121. reflex/components/radix/themes/components/select.py +7 -11
  122. reflex/components/radix/themes/components/select.pyi +175 -154
  123. reflex/components/radix/themes/components/separator.py +1 -4
  124. reflex/components/radix/themes/components/separator.pyi +17 -17
  125. reflex/components/radix/themes/components/skeleton.pyi +17 -17
  126. reflex/components/radix/themes/components/slider.py +12 -21
  127. reflex/components/radix/themes/components/slider.pyi +47 -25
  128. reflex/components/radix/themes/components/spinner.py +1 -4
  129. reflex/components/radix/themes/components/spinner.pyi +17 -17
  130. reflex/components/radix/themes/components/switch.py +3 -6
  131. reflex/components/radix/themes/components/switch.pyi +21 -18
  132. reflex/components/radix/themes/components/table.py +21 -5
  133. reflex/components/radix/themes/components/table.pyi +392 -116
  134. reflex/components/radix/themes/components/tabs.py +3 -6
  135. reflex/components/radix/themes/components/tabs.pyi +89 -83
  136. reflex/components/radix/themes/components/text_area.py +1 -5
  137. reflex/components/radix/themes/components/text_area.pyi +43 -20
  138. reflex/components/radix/themes/components/text_field.py +1 -5
  139. reflex/components/radix/themes/components/text_field.pyi +101 -55
  140. reflex/components/radix/themes/components/tooltip.py +5 -7
  141. reflex/components/radix/themes/components/tooltip.pyi +25 -22
  142. reflex/components/radix/themes/layout/base.py +2 -27
  143. reflex/components/radix/themes/layout/base.pyi +82 -82
  144. reflex/components/radix/themes/layout/box.pyi +17 -17
  145. reflex/components/radix/themes/layout/center.pyi +17 -17
  146. reflex/components/radix/themes/layout/container.pyi +17 -17
  147. reflex/components/radix/themes/layout/flex.py +1 -6
  148. reflex/components/radix/themes/layout/flex.pyi +17 -17
  149. reflex/components/radix/themes/layout/grid.py +1 -6
  150. reflex/components/radix/themes/layout/grid.pyi +17 -17
  151. reflex/components/radix/themes/layout/list.py +20 -15
  152. reflex/components/radix/themes/layout/list.pyi +175 -92
  153. reflex/components/radix/themes/layout/section.pyi +17 -17
  154. reflex/components/radix/themes/layout/spacer.pyi +17 -17
  155. reflex/components/radix/themes/layout/stack.py +6 -6
  156. reflex/components/radix/themes/layout/stack.pyi +91 -62
  157. reflex/components/radix/themes/typography/blockquote.py +2 -8
  158. reflex/components/radix/themes/typography/blockquote.pyi +17 -17
  159. reflex/components/radix/themes/typography/code.py +4 -10
  160. reflex/components/radix/themes/typography/code.pyi +19 -18
  161. reflex/components/radix/themes/typography/heading.py +4 -11
  162. reflex/components/radix/themes/typography/heading.pyi +19 -18
  163. reflex/components/radix/themes/typography/link.py +4 -10
  164. reflex/components/radix/themes/typography/link.pyi +19 -18
  165. reflex/components/radix/themes/typography/text.py +4 -11
  166. reflex/components/radix/themes/typography/text.pyi +115 -114
  167. reflex/components/react_player/audio.pyi +58 -33
  168. reflex/components/react_player/react_player.py +17 -17
  169. reflex/components/react_player/react_player.pyi +55 -33
  170. reflex/components/react_player/video.pyi +58 -33
  171. reflex/components/recharts/cartesian.py +45 -45
  172. reflex/components/recharts/cartesian.pyi +389 -304
  173. reflex/components/recharts/charts.py +22 -22
  174. reflex/components/recharts/charts.pyi +226 -179
  175. reflex/components/recharts/general.py +26 -27
  176. reflex/components/recharts/general.pyi +106 -99
  177. reflex/components/recharts/polar.py +33 -33
  178. reflex/components/recharts/polar.pyi +70 -64
  179. reflex/components/recharts/recharts.pyi +33 -33
  180. reflex/components/sonner/toast.py +9 -36
  181. reflex/components/sonner/toast.pyi +20 -24
  182. reflex/components/suneditor/editor.py +8 -8
  183. reflex/components/suneditor/editor.pyi +50 -25
  184. reflex/components/tags/iter_tag.py +1 -10
  185. reflex/components/tags/tag.py +1 -4
  186. reflex/config.py +198 -35
  187. reflex/constants/__init__.py +4 -16
  188. reflex/constants/base.py +7 -14
  189. reflex/constants/colors.py +0 -1
  190. reflex/constants/installer.py +12 -7
  191. reflex/constants/state.py +4 -0
  192. reflex/custom_components/custom_components.py +6 -6
  193. reflex/event.py +486 -241
  194. reflex/experimental/client_state.py +9 -9
  195. reflex/experimental/layout.py +2 -2
  196. reflex/experimental/layout.pyi +95 -87
  197. reflex/experimental/misc.py +1 -1
  198. reflex/istate/__init__.py +1 -0
  199. reflex/istate/proxy.py +33 -0
  200. reflex/istate/wrappers.py +27 -0
  201. reflex/model.py +7 -7
  202. reflex/page.py +2 -1
  203. reflex/reflex.py +142 -8
  204. reflex/state.py +133 -46
  205. reflex/testing.py +9 -7
  206. reflex/utils/console.py +0 -1
  207. reflex/utils/exceptions.py +31 -3
  208. reflex/utils/exec.py +33 -14
  209. reflex/utils/format.py +15 -12
  210. reflex/utils/net.py +1 -1
  211. reflex/utils/path_ops.py +2 -2
  212. reflex/utils/prerequisites.py +82 -46
  213. reflex/utils/pyi_generator.py +63 -20
  214. reflex/utils/registry.py +1 -1
  215. reflex/utils/serializers.py +75 -36
  216. reflex/utils/telemetry.py +3 -2
  217. reflex/utils/types.py +125 -10
  218. reflex/vars/base.py +131 -119
  219. reflex/vars/function.py +59 -12
  220. reflex/vars/number.py +3 -1
  221. reflex/vars/object.py +30 -24
  222. reflex/vars/sequence.py +7 -7
  223. {reflex-0.6.4a3.dist-info → reflex-0.6.5.dist-info}/METADATA +3 -3
  224. reflex-0.6.5.dist-info/RECORD +394 -0
  225. reflex-0.6.4a3.dist-info/RECORD +0 -391
  226. {reflex-0.6.4a3.dist-info → reflex-0.6.5.dist-info}/LICENSE +0 -0
  227. {reflex-0.6.4a3.dist-info → reflex-0.6.5.dist-info}/WHEEL +0 -0
  228. {reflex-0.6.4a3.dist-info → reflex-0.6.5.dist-info}/entry_points.txt +0 -0
reflex/config.py CHANGED
@@ -10,7 +10,17 @@ import os
10
10
  import sys
11
11
  import urllib.parse
12
12
  from pathlib import Path
13
- from typing import Any, Dict, List, Optional, Set
13
+ from typing import (
14
+ TYPE_CHECKING,
15
+ Any,
16
+ Dict,
17
+ Generic,
18
+ List,
19
+ Optional,
20
+ Set,
21
+ TypeVar,
22
+ get_args,
23
+ )
14
24
 
15
25
  from typing_extensions import Annotated, get_type_hints
16
26
 
@@ -300,6 +310,141 @@ def interpret_env_var_value(
300
310
  )
301
311
 
302
312
 
313
+ T = TypeVar("T")
314
+
315
+
316
+ class EnvVar(Generic[T]):
317
+ """Environment variable."""
318
+
319
+ name: str
320
+ default: Any
321
+ type_: T
322
+
323
+ def __init__(self, name: str, default: Any, type_: T) -> None:
324
+ """Initialize the environment variable.
325
+
326
+ Args:
327
+ name: The environment variable name.
328
+ default: The default value.
329
+ type_: The type of the value.
330
+ """
331
+ self.name = name
332
+ self.default = default
333
+ self.type_ = type_
334
+
335
+ def interpret(self, value: str) -> T:
336
+ """Interpret the environment variable value.
337
+
338
+ Args:
339
+ value: The environment variable value.
340
+
341
+ Returns:
342
+ The interpreted value.
343
+ """
344
+ return interpret_env_var_value(value, self.type_, self.name)
345
+
346
+ def getenv(self) -> Optional[T]:
347
+ """Get the interpreted environment variable value.
348
+
349
+ Returns:
350
+ The environment variable value.
351
+ """
352
+ env_value = os.getenv(self.name, None)
353
+ if env_value is not None:
354
+ return self.interpret(env_value)
355
+ return None
356
+
357
+ def is_set(self) -> bool:
358
+ """Check if the environment variable is set.
359
+
360
+ Returns:
361
+ True if the environment variable is set.
362
+ """
363
+ return self.name in os.environ
364
+
365
+ def get(self) -> T:
366
+ """Get the interpreted environment variable value or the default value if not set.
367
+
368
+ Returns:
369
+ The interpreted value.
370
+ """
371
+ env_value = self.getenv()
372
+ if env_value is not None:
373
+ return env_value
374
+ return self.default
375
+
376
+ def set(self, value: T | None) -> None:
377
+ """Set the environment variable. None unsets the variable.
378
+
379
+ Args:
380
+ value: The value to set.
381
+ """
382
+ if value is None:
383
+ _ = os.environ.pop(self.name, None)
384
+ else:
385
+ if isinstance(value, enum.Enum):
386
+ value = value.value
387
+ os.environ[self.name] = str(value)
388
+
389
+
390
+ class env_var: # type: ignore
391
+ """Descriptor for environment variables."""
392
+
393
+ name: str
394
+ default: Any
395
+ internal: bool = False
396
+
397
+ def __init__(self, default: Any, internal: bool = False) -> None:
398
+ """Initialize the descriptor.
399
+
400
+ Args:
401
+ default: The default value.
402
+ internal: Whether the environment variable is reflex internal.
403
+ """
404
+ self.default = default
405
+ self.internal = internal
406
+
407
+ def __set_name__(self, owner, name):
408
+ """Set the name of the descriptor.
409
+
410
+ Args:
411
+ owner: The owner class.
412
+ name: The name of the descriptor.
413
+ """
414
+ self.name = name
415
+
416
+ def __get__(self, instance, owner):
417
+ """Get the EnvVar instance.
418
+
419
+ Args:
420
+ instance: The instance.
421
+ owner: The owner class.
422
+
423
+ Returns:
424
+ The EnvVar instance.
425
+ """
426
+ type_ = get_args(get_type_hints(owner)[self.name])[0]
427
+ env_name = self.name
428
+ if self.internal:
429
+ env_name = f"__{env_name}"
430
+ return EnvVar(name=env_name, default=self.default, type_=type_)
431
+
432
+
433
+ if TYPE_CHECKING:
434
+
435
+ def env_var(default, internal=False) -> EnvVar:
436
+ """Typing helper for the env_var descriptor.
437
+
438
+ Args:
439
+ default: The default value.
440
+ internal: Whether the environment variable is reflex internal.
441
+
442
+ Returns:
443
+ The EnvVar instance.
444
+ """
445
+ return default
446
+
447
+
303
448
  class PathExistsFlag:
304
449
  """Flag to indicate that a path must exist."""
305
450
 
@@ -307,83 +452,98 @@ class PathExistsFlag:
307
452
  ExistingPath = Annotated[Path, PathExistsFlag]
308
453
 
309
454
 
310
- @dataclasses.dataclass(init=False)
311
455
  class EnvironmentVariables:
312
456
  """Environment variables class to instantiate environment variables."""
313
457
 
314
458
  # Whether to use npm over bun to install frontend packages.
315
- REFLEX_USE_NPM: bool = False
459
+ REFLEX_USE_NPM: EnvVar[bool] = env_var(False)
316
460
 
317
461
  # The npm registry to use.
318
- NPM_CONFIG_REGISTRY: Optional[str] = None
462
+ NPM_CONFIG_REGISTRY: EnvVar[Optional[str]] = env_var(None)
319
463
 
320
464
  # Whether to use Granian for the backend. Otherwise, use Uvicorn.
321
- REFLEX_USE_GRANIAN: bool = False
465
+ REFLEX_USE_GRANIAN: EnvVar[bool] = env_var(False)
322
466
 
323
467
  # The username to use for authentication on python package repository. Username and password must both be provided.
324
- TWINE_USERNAME: Optional[str] = None
468
+ TWINE_USERNAME: EnvVar[Optional[str]] = env_var(None)
325
469
 
326
470
  # The password to use for authentication on python package repository. Username and password must both be provided.
327
- TWINE_PASSWORD: Optional[str] = None
471
+ TWINE_PASSWORD: EnvVar[Optional[str]] = env_var(None)
328
472
 
329
473
  # Whether to use the system installed bun. If set to false, bun will be bundled with the app.
330
- REFLEX_USE_SYSTEM_BUN: bool = False
474
+ REFLEX_USE_SYSTEM_BUN: EnvVar[bool] = env_var(False)
331
475
 
332
476
  # Whether to use the system installed node and npm. If set to false, node and npm will be bundled with the app.
333
- REFLEX_USE_SYSTEM_NODE: bool = False
477
+ REFLEX_USE_SYSTEM_NODE: EnvVar[bool] = env_var(False)
334
478
 
335
479
  # The working directory for the next.js commands.
336
- REFLEX_WEB_WORKDIR: Path = Path(constants.Dirs.WEB)
480
+ REFLEX_WEB_WORKDIR: EnvVar[Path] = env_var(Path(constants.Dirs.WEB))
337
481
 
338
482
  # Path to the alembic config file
339
- ALEMBIC_CONFIG: ExistingPath = Path(constants.ALEMBIC_CONFIG)
483
+ ALEMBIC_CONFIG: EnvVar[ExistingPath] = env_var(Path(constants.ALEMBIC_CONFIG))
340
484
 
341
485
  # Disable SSL verification for HTTPX requests.
342
- SSL_NO_VERIFY: bool = False
486
+ SSL_NO_VERIFY: EnvVar[bool] = env_var(False)
343
487
 
344
488
  # The directory to store uploaded files.
345
- REFLEX_UPLOADED_FILES_DIR: Path = Path(constants.Dirs.UPLOADED_FILES)
489
+ REFLEX_UPLOADED_FILES_DIR: EnvVar[Path] = env_var(
490
+ Path(constants.Dirs.UPLOADED_FILES)
491
+ )
346
492
 
347
- # Whether to use seperate processes to compile the frontend and how many. If not set, defaults to thread executor.
348
- REFLEX_COMPILE_PROCESSES: Optional[int] = None
493
+ # Whether to use separate processes to compile the frontend and how many. If not set, defaults to thread executor.
494
+ REFLEX_COMPILE_PROCESSES: EnvVar[Optional[int]] = env_var(None)
349
495
 
350
- # Whether to use seperate threads to compile the frontend and how many. Defaults to `min(32, os.cpu_count() + 4)`.
351
- REFLEX_COMPILE_THREADS: Optional[int] = None
496
+ # Whether to use separate threads to compile the frontend and how many. Defaults to `min(32, os.cpu_count() + 4)`.
497
+ REFLEX_COMPILE_THREADS: EnvVar[Optional[int]] = env_var(None)
352
498
 
353
499
  # The directory to store reflex dependencies.
354
- REFLEX_DIR: Path = Path(constants.Reflex.DIR)
500
+ REFLEX_DIR: EnvVar[Path] = env_var(Path(constants.Reflex.DIR))
355
501
 
356
502
  # Whether to print the SQL queries if the log level is INFO or lower.
357
- SQLALCHEMY_ECHO: bool = False
503
+ SQLALCHEMY_ECHO: EnvVar[bool] = env_var(False)
358
504
 
359
505
  # Whether to ignore the redis config error. Some redis servers only allow out-of-band configuration.
360
- REFLEX_IGNORE_REDIS_CONFIG_ERROR: bool = False
506
+ REFLEX_IGNORE_REDIS_CONFIG_ERROR: EnvVar[bool] = env_var(False)
361
507
 
362
508
  # Whether to skip purging the web directory in dev mode.
363
- REFLEX_PERSIST_WEB_DIR: bool = False
509
+ REFLEX_PERSIST_WEB_DIR: EnvVar[bool] = env_var(False)
364
510
 
365
511
  # The reflex.build frontend host.
366
- REFLEX_BUILD_FRONTEND: str = constants.Templates.REFLEX_BUILD_FRONTEND
512
+ REFLEX_BUILD_FRONTEND: EnvVar[str] = env_var(
513
+ constants.Templates.REFLEX_BUILD_FRONTEND
514
+ )
367
515
 
368
516
  # The reflex.build backend host.
369
- REFLEX_BUILD_BACKEND: str = constants.Templates.REFLEX_BUILD_BACKEND
517
+ REFLEX_BUILD_BACKEND: EnvVar[str] = env_var(
518
+ constants.Templates.REFLEX_BUILD_BACKEND
519
+ )
370
520
 
371
- def __init__(self):
372
- """Initialize the environment variables."""
373
- type_hints = get_type_hints(type(self))
521
+ # This env var stores the execution mode of the app
522
+ REFLEX_ENV_MODE: EnvVar[constants.Env] = env_var(constants.Env.DEV)
374
523
 
375
- for field in dataclasses.fields(self):
376
- raw_value = os.getenv(field.name, None)
524
+ # Whether to run the backend only. Exclusive with REFLEX_FRONTEND_ONLY.
525
+ REFLEX_BACKEND_ONLY: EnvVar[bool] = env_var(False)
377
526
 
378
- field.type = type_hints.get(field.name) or field.type
527
+ # Whether to run the frontend only. Exclusive with REFLEX_BACKEND_ONLY.
528
+ REFLEX_FRONTEND_ONLY: EnvVar[bool] = env_var(False)
379
529
 
380
- value = (
381
- interpret_env_var_value(raw_value, field.type, field.name)
382
- if raw_value is not None
383
- else get_default_value_for_field(field)
384
- )
530
+ # Reflex internal env to reload the config.
531
+ RELOAD_CONFIG: EnvVar[bool] = env_var(False, internal=True)
532
+
533
+ # If this env var is set to "yes", App.compile will be a no-op
534
+ REFLEX_SKIP_COMPILE: EnvVar[bool] = env_var(False, internal=True)
385
535
 
386
- setattr(self, field.name, value)
536
+ # Whether to run app harness tests in headless mode.
537
+ APP_HARNESS_HEADLESS: EnvVar[bool] = env_var(False)
538
+
539
+ # Which app harness driver to use.
540
+ APP_HARNESS_DRIVER: EnvVar[str] = env_var("Chrome")
541
+
542
+ # Arguments to pass to the app harness driver.
543
+ APP_HARNESS_DRIVER_ARGS: EnvVar[str] = env_var("")
544
+
545
+ # Where to save screenshots when tests fail.
546
+ SCREENSHOT_DIR: EnvVar[Optional[Path]] = env_var(None)
387
547
 
388
548
 
389
549
  environment = EnvironmentVariables()
@@ -451,6 +611,9 @@ class Config(Base):
451
611
  # The bun path
452
612
  bun_path: ExistingPath = constants.Bun.DEFAULT_PATH
453
613
 
614
+ # Timeout to do a production build of a frontend page.
615
+ static_page_generation_timeout: int = 60
616
+
454
617
  # List of origins that are allowed to connect to the backend API.
455
618
  cors_allowed_origins: List[str] = ["*"]
456
619
 
@@ -2,18 +2,15 @@
2
2
 
3
3
  from .base import (
4
4
  COOKIES,
5
- ENV_BACKEND_ONLY_ENV_VAR,
6
- ENV_FRONTEND_ONLY_ENV_VAR,
7
- ENV_MODE_ENV_VAR,
5
+ IS_LINUX,
6
+ IS_MACOS,
8
7
  IS_WINDOWS,
9
8
  LOCAL_STORAGE,
10
9
  POLLING_MAX_HTTP_BUFFER_SIZE,
11
10
  PYTEST_CURRENT_TEST,
12
11
  REFLEX_VAR_CLOSING_TAG,
13
12
  REFLEX_VAR_OPENING_TAG,
14
- RELOAD_CONFIG,
15
13
  SESSION_STORAGE,
16
- SKIP_COMPILE_ENV_VAR,
17
14
  ColorMode,
18
15
  Dirs,
19
16
  Env,
@@ -44,16 +41,9 @@ from .config import (
44
41
  GitIgnore,
45
42
  RequirementsTxt,
46
43
  )
47
- from .custom_components import (
48
- CustomComponents,
49
- )
44
+ from .custom_components import CustomComponents
50
45
  from .event import Endpoint, EventTriggers, SocketEvent
51
- from .installer import (
52
- Bun,
53
- Fnm,
54
- Node,
55
- PackageJson,
56
- )
46
+ from .installer import Bun, Fnm, Node, PackageJson
57
47
  from .route import (
58
48
  ROUTE_NOT_FOUND,
59
49
  ROUTER,
@@ -106,7 +96,6 @@ __ALL__ = [
106
96
  POLLING_MAX_HTTP_BUFFER_SIZE,
107
97
  PYTEST_CURRENT_TEST,
108
98
  Reflex,
109
- RELOAD_CONFIG,
110
99
  RequirementsTxt,
111
100
  RouteArgType,
112
101
  RouteRegex,
@@ -116,7 +105,6 @@ __ALL__ = [
116
105
  ROUTER_DATA_INCLUDE,
117
106
  ROUTE_NOT_FOUND,
118
107
  SETTER_PREFIX,
119
- SKIP_COMPILE_ENV_VAR,
120
108
  SocketEvent,
121
109
  StateManagerMode,
122
110
  Tailwind,
reflex/constants/base.py CHANGED
@@ -13,6 +13,8 @@ from platformdirs import PlatformDirs
13
13
  from .utils import classproperty
14
14
 
15
15
  IS_WINDOWS = platform.system() == "Windows"
16
+ IS_MACOS = platform.system() == "Darwin"
17
+ IS_LINUX = platform.system() == "Linux"
16
18
 
17
19
 
18
20
  class Dirs(SimpleNamespace):
@@ -76,7 +78,7 @@ class Reflex(SimpleNamespace):
76
78
  # The root directory of the reflex library.
77
79
  ROOT_DIR = Path(__file__).parents[2]
78
80
 
79
- RELEASES_URL = f"https://api.github.com/repos/reflex-dev/templates/releases"
81
+ RELEASES_URL = "https://api.github.com/repos/reflex-dev/templates/releases"
80
82
 
81
83
 
82
84
  class ReflexHostingCLI(SimpleNamespace):
@@ -112,7 +114,7 @@ class Templates(SimpleNamespace):
112
114
  from reflex.config import environment
113
115
 
114
116
  return (
115
- environment.REFLEX_BUILD_FRONTEND
117
+ environment.REFLEX_BUILD_FRONTEND.get()
116
118
  + "/gen?reflex_init_token={reflex_init_token}"
117
119
  )
118
120
 
@@ -126,7 +128,7 @@ class Templates(SimpleNamespace):
126
128
  """
127
129
  from reflex.config import environment
128
130
 
129
- return environment.REFLEX_BUILD_BACKEND + "/api/init/{reflex_init_token}"
131
+ return environment.REFLEX_BUILD_BACKEND.get() + "/api/init/{reflex_init_token}"
130
132
 
131
133
  @classproperty
132
134
  @classmethod
@@ -139,7 +141,8 @@ class Templates(SimpleNamespace):
139
141
  from reflex.config import environment
140
142
 
141
143
  return (
142
- environment.REFLEX_BUILD_BACKEND + "/api/gen/{generation_hash}/refactored"
144
+ environment.REFLEX_BUILD_BACKEND.get()
145
+ + "/api/gen/{generation_hash}/refactored"
143
146
  )
144
147
 
145
148
  class Dirs(SimpleNamespace):
@@ -239,19 +242,9 @@ COOKIES = "cookies"
239
242
  LOCAL_STORAGE = "local_storage"
240
243
  SESSION_STORAGE = "session_storage"
241
244
 
242
- # If this env var is set to "yes", App.compile will be a no-op
243
- SKIP_COMPILE_ENV_VAR = "__REFLEX_SKIP_COMPILE"
244
-
245
- # This env var stores the execution mode of the app
246
- ENV_MODE_ENV_VAR = "REFLEX_ENV_MODE"
247
-
248
- ENV_BACKEND_ONLY_ENV_VAR = "REFLEX_BACKEND_ONLY"
249
- ENV_FRONTEND_ONLY_ENV_VAR = "REFLEX_FRONTEND_ONLY"
250
-
251
245
  # Testing variables.
252
246
  # Testing os env set by pytest when running a test case.
253
247
  PYTEST_CURRENT_TEST = "PYTEST_CURRENT_TEST"
254
- RELOAD_CONFIG = "__REFLEX_RELOAD_CONFIG"
255
248
 
256
249
  REFLEX_VAR_OPENING_TAG = "<reflex.Var>"
257
250
  REFLEX_VAR_CLOSING_TAG = "</reflex.Var>"
@@ -35,7 +35,6 @@ ColorType = Literal[
35
35
  "amber",
36
36
  "gold",
37
37
  "bronze",
38
- "gray",
39
38
  "accent",
40
39
  "black",
41
40
  "white",
@@ -63,7 +63,7 @@ class Bun(SimpleNamespace):
63
63
  """
64
64
  from reflex.config import environment
65
65
 
66
- return environment.REFLEX_DIR / "bun"
66
+ return environment.REFLEX_DIR.get() / "bun"
67
67
 
68
68
  @classproperty
69
69
  @classmethod
@@ -75,6 +75,11 @@ class Bun(SimpleNamespace):
75
75
  """
76
76
  return cls.ROOT_PATH / "bin" / ("bun" if not IS_WINDOWS else "bun.exe")
77
77
 
78
+ DEFAULT_CONFIG = """
79
+ [install]
80
+ registry = "{registry}"
81
+ """
82
+
78
83
 
79
84
  # FNM config.
80
85
  class Fnm(SimpleNamespace):
@@ -100,7 +105,7 @@ class Fnm(SimpleNamespace):
100
105
  """
101
106
  from reflex.config import environment
102
107
 
103
- return environment.REFLEX_DIR / "fnm"
108
+ return environment.REFLEX_DIR.get() / "fnm"
104
109
 
105
110
  @classproperty
106
111
  @classmethod
@@ -118,9 +123,9 @@ class Node(SimpleNamespace):
118
123
  """Node/ NPM constants."""
119
124
 
120
125
  # The Node version.
121
- VERSION = "22.10.0"
126
+ VERSION = "22.11.0"
122
127
  # The minimum required node version.
123
- MIN_VERSION = "18.17.0"
128
+ MIN_VERSION = "18.18.0"
124
129
 
125
130
  @classproperty
126
131
  @classmethod
@@ -173,17 +178,17 @@ class PackageJson(SimpleNamespace):
173
178
  PATH = "package.json"
174
179
 
175
180
  DEPENDENCIES = {
176
- "@babel/standalone": "7.25.8",
181
+ "@babel/standalone": "7.26.0",
177
182
  "@emotion/react": "11.13.3",
178
183
  "axios": "1.7.7",
179
184
  "json5": "2.2.3",
180
- "next": "14.2.15",
185
+ "next": "14.2.16",
181
186
  "next-sitemap": "4.2.3",
182
187
  "next-themes": "0.3.0",
183
188
  "react": "18.3.1",
184
189
  "react-dom": "18.3.1",
185
190
  "react-focus-lock": "2.13.2",
186
- "socket.io-client": "4.8.0",
191
+ "socket.io-client": "4.8.1",
187
192
  "universal-cookie": "7.2.1",
188
193
  }
189
194
  DEV_DEPENDENCIES = {
reflex/constants/state.py CHANGED
@@ -9,3 +9,7 @@ class StateManagerMode(str, Enum):
9
9
  DISK = "disk"
10
10
  MEMORY = "memory"
11
11
  REDIS = "redis"
12
+
13
+
14
+ # Used for things like console_log, etc.
15
+ FRONTEND_EVENT_STATE = "__reflex_internal_frontend_event_state"
@@ -609,14 +609,14 @@ def publish(
609
609
  help="The API token to use for authentication on python package repository. If token is provided, no username/password should be provided at the same time",
610
610
  ),
611
611
  username: Optional[str] = typer.Option(
612
- environment.TWINE_USERNAME,
612
+ environment.TWINE_USERNAME.get(),
613
613
  "-u",
614
614
  "--username",
615
615
  show_default="TWINE_USERNAME environment variable value if set",
616
616
  help="The username to use for authentication on python package repository. Username and password must both be provided.",
617
617
  ),
618
618
  password: Optional[str] = typer.Option(
619
- environment.TWINE_PASSWORD,
619
+ environment.TWINE_PASSWORD.get(),
620
620
  "-p",
621
621
  "--password",
622
622
  show_default="TWINE_PASSWORD environment variable value if set",
@@ -779,8 +779,8 @@ def _validate_project_info():
779
779
  )
780
780
  # PyPI only shows the first author.
781
781
  author = project.get("authors", [{}])[0]
782
- author["name"] = console.ask(f"Author Name", default=author.get("name", ""))
783
- author["email"] = console.ask(f"Author Email", default=author.get("email", ""))
782
+ author["name"] = console.ask("Author Name", default=author.get("name", ""))
783
+ author["email"] = console.ask("Author Email", default=author.get("email", ""))
784
784
 
785
785
  console.print(f'Current keywords are: {project.get("keywords") or []}')
786
786
  keyword_action = console.ask(
@@ -923,7 +923,7 @@ def _get_file_from_prompt_in_loop() -> Tuple[bytes, str] | None:
923
923
  image_file = file_extension = None
924
924
  while image_file is None:
925
925
  image_filepath = console.ask(
926
- f"Upload a preview image of your demo app (enter to skip)"
926
+ "Upload a preview image of your demo app (enter to skip)"
927
927
  )
928
928
  if not image_filepath:
929
929
  break
@@ -973,6 +973,6 @@ def install(
973
973
  console.set_log_level(loglevel)
974
974
 
975
975
  if _pip_install_on_demand(package_name=".", install_args=["-e"]):
976
- console.info(f"Package installed successfully!")
976
+ console.info("Package installed successfully!")
977
977
  else:
978
978
  raise typer.Exit(code=1)