reflex 0.7.1a4__py3-none-any.whl → 0.7.2a1__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.
- reflex/.templates/jinja/web/utils/context.js.jinja2 +8 -8
- reflex/.templates/web/components/reflex/radix_themes_color_mode_provider.js +3 -3
- reflex/admin.py +1 -2
- reflex/app.py +46 -49
- reflex/app_mixins/lifespan.py +2 -2
- reflex/app_mixins/middleware.py +1 -2
- reflex/assets.py +1 -2
- reflex/base.py +2 -2
- reflex/compiler/compiler.py +51 -16
- reflex/compiler/utils.py +4 -13
- reflex/components/base/app_wrap.pyi +7 -7
- reflex/components/base/bare.py +3 -3
- reflex/components/base/body.pyi +7 -7
- reflex/components/base/document.py +1 -3
- reflex/components/base/document.pyi +32 -32
- reflex/components/base/error_boundary.py +2 -4
- reflex/components/base/error_boundary.pyi +11 -13
- reflex/components/base/fragment.pyi +7 -7
- reflex/components/base/head.pyi +13 -13
- reflex/components/base/link.pyi +22 -22
- reflex/components/base/meta.py +5 -7
- reflex/components/base/meta.pyi +40 -40
- reflex/components/base/script.pyi +11 -14
- reflex/components/base/strict_mode.pyi +7 -7
- reflex/components/component.py +188 -113
- reflex/components/core/auto_scroll.py +8 -1
- reflex/components/core/auto_scroll.pyi +183 -210
- reflex/components/core/banner.py +2 -4
- reflex/components/core/banner.pyi +390 -444
- reflex/components/core/breakpoints.py +5 -5
- reflex/components/core/client_side_routing.pyi +14 -14
- reflex/components/core/clipboard.py +4 -4
- reflex/components/core/clipboard.pyi +12 -14
- reflex/components/core/cond.py +17 -25
- reflex/components/core/debounce.py +3 -3
- reflex/components/core/debounce.pyi +14 -14
- reflex/components/core/foreach.py +7 -2
- reflex/components/core/html.py +1 -3
- reflex/components/core/html.pyi +184 -213
- reflex/components/core/match.py +15 -19
- reflex/components/core/sticky.pyi +930 -1078
- reflex/components/core/upload.py +4 -4
- reflex/components/core/upload.pyi +62 -62
- reflex/components/datadisplay/code.py +6 -6
- reflex/components/datadisplay/code.pyi +1159 -1165
- reflex/components/datadisplay/dataeditor.py +49 -49
- reflex/components/datadisplay/dataeditor.pyi +95 -123
- reflex/components/datadisplay/logo.py +1 -3
- reflex/components/datadisplay/shiki_code_block.py +8 -10
- reflex/components/datadisplay/shiki_code_block.pyi +1678 -1720
- reflex/components/el/element.pyi +7 -7
- reflex/components/el/elements/base.pyi +183 -210
- reflex/components/el/elements/forms.py +23 -23
- reflex/components/el/elements/forms.pyi +2571 -2933
- reflex/components/el/elements/inline.py +4 -4
- reflex/components/el/elements/inline.pyi +5191 -5953
- reflex/components/el/elements/media.py +47 -47
- reflex/components/el/elements/media.pyi +4802 -5500
- reflex/components/el/elements/metadata.py +1 -3
- reflex/components/el/elements/metadata.pyi +782 -896
- reflex/components/el/elements/other.pyi +1278 -1467
- reflex/components/el/elements/scripts.pyi +580 -667
- reflex/components/el/elements/sectioning.pyi +2761 -3166
- reflex/components/el/elements/tables.pyi +1840 -2119
- reflex/components/el/elements/typography.pyi +2772 -3179
- reflex/components/gridjs/datatable.py +7 -7
- reflex/components/gridjs/datatable.pyi +19 -19
- reflex/components/lucide/icon.pyi +21 -21
- reflex/components/markdown/markdown.py +2 -2
- reflex/components/markdown/markdown.pyi +9 -9
- reflex/components/moment/moment.py +11 -12
- reflex/components/moment/moment.pyi +44 -47
- reflex/components/next/base.pyi +7 -7
- reflex/components/next/image.py +3 -3
- reflex/components/next/image.pyi +19 -21
- reflex/components/next/link.pyi +9 -9
- reflex/components/next/video.py +1 -3
- reflex/components/next/video.pyi +9 -9
- reflex/components/plotly/plotly.py +22 -45
- reflex/components/plotly/plotly.pyi +164 -164
- reflex/components/radix/primitives/accordion.py +14 -14
- reflex/components/radix/primitives/accordion.pyi +439 -487
- reflex/components/radix/primitives/base.py +1 -3
- reflex/components/radix/primitives/base.pyi +15 -15
- reflex/components/radix/primitives/drawer.py +3 -3
- reflex/components/radix/primitives/drawer.pyi +110 -116
- reflex/components/radix/primitives/form.py +1 -1
- reflex/components/radix/primitives/form.pyi +668 -752
- reflex/components/radix/primitives/progress.py +6 -6
- reflex/components/radix/primitives/progress.pyi +225 -243
- reflex/components/radix/primitives/slider.py +6 -6
- reflex/components/radix/primitives/slider.pyi +52 -55
- reflex/components/radix/themes/base.py +3 -6
- reflex/components/radix/themes/base.pyi +197 -303
- reflex/components/radix/themes/color_mode.py +5 -5
- reflex/components/radix/themes/color_mode.pyi +366 -436
- reflex/components/radix/themes/components/alert_dialog.pyi +229 -262
- reflex/components/radix/themes/components/aspect_ratio.py +1 -3
- reflex/components/radix/themes/components/aspect_ratio.pyi +8 -8
- reflex/components/radix/themes/components/avatar.pyi +79 -94
- reflex/components/radix/themes/components/badge.pyi +252 -295
- reflex/components/radix/themes/components/button.pyi +269 -314
- reflex/components/radix/themes/components/callout.py +2 -2
- reflex/components/radix/themes/components/callout.pyi +1116 -1290
- reflex/components/radix/themes/components/card.pyi +194 -229
- reflex/components/radix/themes/components/checkbox.pyi +243 -278
- reflex/components/radix/themes/components/checkbox_cards.py +3 -7
- reflex/components/radix/themes/components/checkbox_cards.pyi +101 -135
- reflex/components/radix/themes/components/checkbox_group.py +2 -2
- reflex/components/radix/themes/components/checkbox_group.pyi +83 -96
- reflex/components/radix/themes/components/context_menu.py +18 -15
- reflex/components/radix/themes/components/context_menu.pyi +408 -458
- reflex/components/radix/themes/components/data_list.pyi +122 -147
- reflex/components/radix/themes/components/dialog.pyi +231 -264
- reflex/components/radix/themes/components/dropdown_menu.py +16 -13
- reflex/components/radix/themes/components/dropdown_menu.pyi +223 -246
- reflex/components/radix/themes/components/hover_card.py +2 -2
- reflex/components/radix/themes/components/hover_card.pyi +237 -282
- reflex/components/radix/themes/components/icon_button.pyi +269 -314
- reflex/components/radix/themes/components/inset.py +8 -8
- reflex/components/radix/themes/components/inset.pyi +232 -292
- reflex/components/radix/themes/components/popover.py +2 -2
- reflex/components/radix/themes/components/popover.pyi +229 -271
- reflex/components/radix/themes/components/progress.pyi +80 -96
- reflex/components/radix/themes/components/radio.pyi +73 -86
- reflex/components/radix/themes/components/radio_cards.py +4 -8
- reflex/components/radix/themes/components/radio_cards.pyi +117 -154
- reflex/components/radix/themes/components/radio_group.py +3 -3
- reflex/components/radix/themes/components/radio_group.pyi +250 -291
- reflex/components/radix/themes/components/scroll_area.pyi +14 -20
- reflex/components/radix/themes/components/segmented_control.py +6 -6
- reflex/components/radix/themes/components/segmented_control.pyi +89 -108
- reflex/components/radix/themes/components/select.py +7 -7
- reflex/components/radix/themes/components/select.pyi +376 -444
- reflex/components/radix/themes/components/separator.pyi +79 -93
- reflex/components/radix/themes/components/skeleton.pyi +32 -26
- reflex/components/radix/themes/components/slider.py +8 -8
- reflex/components/radix/themes/components/slider.pyi +99 -122
- reflex/components/radix/themes/components/spinner.pyi +12 -19
- reflex/components/radix/themes/components/switch.pyi +84 -99
- reflex/components/radix/themes/components/table.py +9 -9
- reflex/components/radix/themes/components/table.pyi +1440 -1794
- reflex/components/radix/themes/components/tabs.py +4 -4
- reflex/components/radix/themes/components/tabs.pyi +120 -132
- reflex/components/radix/themes/components/text_area.pyi +281 -331
- reflex/components/radix/themes/components/text_field.py +2 -2
- reflex/components/radix/themes/components/text_field.pyi +639 -734
- reflex/components/radix/themes/components/tooltip.py +6 -6
- reflex/components/radix/themes/components/tooltip.pyi +34 -43
- reflex/components/radix/themes/layout/base.pyi +85 -182
- reflex/components/radix/themes/layout/box.pyi +183 -210
- reflex/components/radix/themes/layout/center.pyi +225 -286
- reflex/components/radix/themes/layout/container.pyi +191 -224
- reflex/components/radix/themes/layout/flex.py +2 -2
- reflex/components/radix/themes/layout/flex.pyi +225 -286
- reflex/components/radix/themes/layout/grid.py +2 -2
- reflex/components/radix/themes/layout/grid.pyi +245 -315
- reflex/components/radix/themes/layout/list.py +2 -2
- reflex/components/radix/themes/layout/list.pyi +712 -815
- reflex/components/radix/themes/layout/section.pyi +187 -221
- reflex/components/radix/themes/layout/spacer.pyi +225 -286
- reflex/components/radix/themes/layout/stack.pyi +625 -768
- reflex/components/radix/themes/typography/blockquote.pyi +257 -299
- reflex/components/radix/themes/typography/code.pyi +259 -304
- reflex/components/radix/themes/typography/heading.pyi +272 -324
- reflex/components/radix/themes/typography/link.pyi +302 -358
- reflex/components/radix/themes/typography/text.pyi +1669 -1945
- reflex/components/react_player/audio.pyi +20 -22
- reflex/components/react_player/react_player.pyi +19 -19
- reflex/components/react_player/video.pyi +20 -22
- reflex/components/recharts/cartesian.py +100 -97
- reflex/components/recharts/cartesian.pyi +891 -1007
- reflex/components/recharts/charts.py +42 -42
- reflex/components/recharts/charts.pyi +212 -249
- reflex/components/recharts/general.py +22 -21
- reflex/components/recharts/general.pyi +198 -223
- reflex/components/recharts/polar.py +42 -45
- reflex/components/recharts/polar.pyi +254 -288
- reflex/components/recharts/recharts.pyi +13 -13
- reflex/components/sonner/toast.py +20 -20
- reflex/components/sonner/toast.pyi +58 -61
- reflex/components/suneditor/editor.py +9 -9
- reflex/components/suneditor/editor.pyi +78 -83
- reflex/components/tags/cond_tag.py +2 -2
- reflex/components/tags/iter_tag.py +10 -14
- reflex/components/tags/match_tag.py +2 -2
- reflex/components/tags/tag.py +10 -10
- reflex/config.py +36 -35
- reflex/constants/__init__.py +56 -53
- reflex/custom_components/custom_components.py +6 -7
- reflex/event.py +38 -42
- reflex/experimental/client_state.py +2 -4
- reflex/experimental/layout.py +2 -2
- reflex/experimental/layout.pyi +579 -663
- reflex/istate/data.py +4 -5
- reflex/middleware/hydrate_middleware.py +2 -2
- reflex/middleware/middleware.py +2 -2
- reflex/model.py +3 -5
- reflex/page.py +2 -2
- reflex/reflex.py +9 -10
- reflex/state.py +77 -49
- reflex/style.py +9 -3
- reflex/testing.py +21 -24
- reflex/utils/console.py +1 -1
- reflex/utils/decorator.py +26 -1
- reflex/utils/exec.py +6 -11
- reflex/utils/export.py +2 -3
- reflex/utils/format.py +4 -4
- reflex/utils/imports.py +12 -12
- reflex/utils/prerequisites.py +35 -84
- reflex/utils/processes.py +5 -5
- reflex/utils/pyi_generator.py +33 -22
- reflex/utils/serializers.py +60 -15
- reflex/utils/types.py +237 -56
- reflex/vars/base.py +122 -72
- reflex/vars/datetime.py +2 -2
- reflex/vars/function.py +52 -55
- reflex/vars/number.py +59 -5
- reflex/vars/object.py +57 -26
- reflex/vars/sequence.py +983 -958
- {reflex-0.7.1a4.dist-info → reflex-0.7.2a1.dist-info}/METADATA +3 -6
- reflex-0.7.2a1.dist-info/RECORD +405 -0
- {reflex-0.7.1a4.dist-info → reflex-0.7.2a1.dist-info}/WHEEL +1 -1
- reflex-0.7.1a4.dist-info/RECORD +0 -405
- {reflex-0.7.1a4.dist-info → reflex-0.7.2a1.dist-info}/LICENSE +0 -0
- {reflex-0.7.1a4.dist-info → reflex-0.7.2a1.dist-info}/entry_points.txt +0 -0
reflex/testing.py
CHANGED
|
@@ -26,11 +26,9 @@ from typing import (
|
|
|
26
26
|
AsyncIterator,
|
|
27
27
|
Callable,
|
|
28
28
|
Coroutine,
|
|
29
|
-
List,
|
|
30
29
|
Optional,
|
|
31
30
|
Type,
|
|
32
31
|
TypeVar,
|
|
33
|
-
Union,
|
|
34
32
|
)
|
|
35
33
|
|
|
36
34
|
import psutil
|
|
@@ -78,8 +76,7 @@ DEFAULT_TIMEOUT = 15
|
|
|
78
76
|
POLL_INTERVAL = 0.25
|
|
79
77
|
FRONTEND_POPEN_ARGS = {}
|
|
80
78
|
T = TypeVar("T")
|
|
81
|
-
TimeoutType =
|
|
82
|
-
|
|
79
|
+
TimeoutType = int | float | None
|
|
83
80
|
if platform.system() == "Windows":
|
|
84
81
|
FRONTEND_POPEN_ARGS["creationflags"] = subprocess.CREATE_NEW_PROCESS_GROUP # pyright: ignore [reportAttributeAccessIssue]
|
|
85
82
|
FRONTEND_POPEN_ARGS["shell"] = True
|
|
@@ -119,19 +116,19 @@ class AppHarness:
|
|
|
119
116
|
"""AppHarness executes a reflex app in-process for testing."""
|
|
120
117
|
|
|
121
118
|
app_name: str
|
|
122
|
-
app_source:
|
|
123
|
-
Callable[[], None] | types.ModuleType | str | functools.partial[Any]
|
|
124
|
-
|
|
119
|
+
app_source: (
|
|
120
|
+
Callable[[], None] | types.ModuleType | str | functools.partial[Any] | None
|
|
121
|
+
)
|
|
125
122
|
app_path: Path
|
|
126
123
|
app_module_path: Path
|
|
127
|
-
app_module:
|
|
128
|
-
app_instance:
|
|
129
|
-
frontend_process:
|
|
130
|
-
frontend_url:
|
|
131
|
-
frontend_output_thread:
|
|
132
|
-
backend_thread:
|
|
133
|
-
backend:
|
|
134
|
-
state_manager:
|
|
124
|
+
app_module: types.ModuleType | None = None
|
|
125
|
+
app_instance: reflex.App | None = None
|
|
126
|
+
frontend_process: subprocess.Popen | None = None
|
|
127
|
+
frontend_url: str | None = None
|
|
128
|
+
frontend_output_thread: threading.Thread | None = None
|
|
129
|
+
backend_thread: threading.Thread | None = None
|
|
130
|
+
backend: uvicorn.Server | None = None
|
|
131
|
+
state_manager: StateManager | None = None
|
|
135
132
|
_frontends: list["WebDriver"] = dataclasses.field(default_factory=list)
|
|
136
133
|
_decorated_pages: list = dataclasses.field(default_factory=list)
|
|
137
134
|
|
|
@@ -139,10 +136,10 @@ class AppHarness:
|
|
|
139
136
|
def create(
|
|
140
137
|
cls,
|
|
141
138
|
root: Path,
|
|
142
|
-
app_source:
|
|
143
|
-
Callable[[], None] | types.ModuleType | str | functools.partial[Any]
|
|
144
|
-
|
|
145
|
-
app_name:
|
|
139
|
+
app_source: (
|
|
140
|
+
Callable[[], None] | types.ModuleType | str | functools.partial[Any] | None
|
|
141
|
+
) = None,
|
|
142
|
+
app_name: str | None = None,
|
|
146
143
|
) -> "AppHarness":
|
|
147
144
|
"""Create an AppHarness instance at root.
|
|
148
145
|
|
|
@@ -198,7 +195,7 @@ class AppHarness:
|
|
|
198
195
|
f"{self.app_name}___{self.app_name}___" + state_cls_name
|
|
199
196
|
)
|
|
200
197
|
|
|
201
|
-
def get_full_state_name(self, path:
|
|
198
|
+
def get_full_state_name(self, path: list[str]) -> str:
|
|
202
199
|
"""Get the full state name for the given state class name.
|
|
203
200
|
|
|
204
201
|
Args:
|
|
@@ -596,7 +593,7 @@ class AppHarness:
|
|
|
596
593
|
driver_clz: Optional[Type["WebDriver"]] = None,
|
|
597
594
|
driver_kwargs: dict[str, Any] | None = None,
|
|
598
595
|
driver_options: ArgOptions | None = None,
|
|
599
|
-
driver_option_args:
|
|
596
|
+
driver_option_args: list[str] | None = None,
|
|
600
597
|
driver_option_capabilities: dict[str, Any] | None = None,
|
|
601
598
|
) -> "WebDriver":
|
|
602
599
|
"""Get a selenium webdriver instance pointed at the app.
|
|
@@ -768,7 +765,7 @@ class AppHarness:
|
|
|
768
765
|
element: "WebElement",
|
|
769
766
|
timeout: TimeoutType = None,
|
|
770
767
|
exp_not_equal: str = "",
|
|
771
|
-
) ->
|
|
768
|
+
) -> str | None:
|
|
772
769
|
"""Poll element.get_attribute("value") for change.
|
|
773
770
|
|
|
774
771
|
Args:
|
|
@@ -904,8 +901,8 @@ class AppHarnessProd(AppHarness):
|
|
|
904
901
|
handling. Additionally, the backend runs in multi-worker mode.
|
|
905
902
|
"""
|
|
906
903
|
|
|
907
|
-
frontend_thread:
|
|
908
|
-
frontend_server:
|
|
904
|
+
frontend_thread: threading.Thread | None = None
|
|
905
|
+
frontend_server: Subdir404TCPServer | None = None
|
|
909
906
|
|
|
910
907
|
def _run_frontend(self):
|
|
911
908
|
web_root = (
|
reflex/utils/console.py
CHANGED
|
@@ -250,7 +250,7 @@ def deprecate(
|
|
|
250
250
|
|
|
251
251
|
if dedupe_key not in _EMITTED_DEPRECATION_WARNINGS:
|
|
252
252
|
msg = (
|
|
253
|
-
f"{feature_name} has been deprecated in version {deprecation_version} {reason.rstrip('.')}. It will be completely "
|
|
253
|
+
f"{feature_name} has been deprecated in version {deprecation_version}. {reason.rstrip('.').lstrip('. ')}. It will be completely "
|
|
254
254
|
f"removed in {removal_version}. ({loc})"
|
|
255
255
|
)
|
|
256
256
|
if _LOG_LEVEL <= LogLevel.WARNING:
|
reflex/utils/decorator.py
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"""Decorator utilities."""
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
import functools
|
|
4
|
+
from typing import Callable, ParamSpec, TypeVar
|
|
4
5
|
|
|
5
6
|
T = TypeVar("T")
|
|
6
7
|
|
|
@@ -23,3 +24,27 @@ def once(f: Callable[[], T]) -> Callable[[], T]:
|
|
|
23
24
|
return value # pyright: ignore[reportReturnType]
|
|
24
25
|
|
|
25
26
|
return wrapper
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
P = ParamSpec("P")
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def debug(f: Callable[P, T]) -> Callable[P, T]:
|
|
33
|
+
"""A decorator that prints the function name, arguments, and result.
|
|
34
|
+
|
|
35
|
+
Args:
|
|
36
|
+
f: The function to call.
|
|
37
|
+
|
|
38
|
+
Returns:
|
|
39
|
+
A function that prints the function name, arguments, and result.
|
|
40
|
+
"""
|
|
41
|
+
|
|
42
|
+
@functools.wraps(f)
|
|
43
|
+
def wrapper(*args: P.args, **kwargs: P.kwargs) -> T:
|
|
44
|
+
result = f(*args, **kwargs)
|
|
45
|
+
print( # noqa: T201
|
|
46
|
+
f"Calling {f.__name__} with args: {args} and kwargs: {kwargs}, result: {result}"
|
|
47
|
+
)
|
|
48
|
+
return result
|
|
49
|
+
|
|
50
|
+
return wrapper
|
reflex/utils/exec.py
CHANGED
|
@@ -524,17 +524,12 @@ def output_system_info():
|
|
|
524
524
|
|
|
525
525
|
fnm_info = f"[FNM {prerequisites.get_fnm_version()} (Expected: {constants.Fnm.VERSION}) (PATH: {constants.Fnm.EXE})]"
|
|
526
526
|
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
f"[Bun {prerequisites.get_bun_version()} (Expected: {constants.Bun.VERSION}) (PATH: {path_ops.get_bun_path()})]",
|
|
534
|
-
],
|
|
535
|
-
)
|
|
536
|
-
else:
|
|
537
|
-
dependencies.append(fnm_info)
|
|
527
|
+
dependencies.extend(
|
|
528
|
+
[
|
|
529
|
+
fnm_info,
|
|
530
|
+
f"[Bun {prerequisites.get_bun_version()} (Expected: {constants.Bun.VERSION}) (PATH: {path_ops.get_bun_path()})]",
|
|
531
|
+
],
|
|
532
|
+
)
|
|
538
533
|
|
|
539
534
|
if system == "Linux":
|
|
540
535
|
import distro # pyright: ignore[reportMissingImports]
|
reflex/utils/export.py
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
"""Export utilities."""
|
|
2
2
|
|
|
3
3
|
from pathlib import Path
|
|
4
|
-
from typing import Optional
|
|
5
4
|
|
|
6
5
|
from reflex import constants
|
|
7
6
|
from reflex.config import environment, get_config
|
|
@@ -16,8 +15,8 @@ def export(
|
|
|
16
15
|
backend: bool = True,
|
|
17
16
|
zip_dest_dir: str = str(Path.cwd()),
|
|
18
17
|
upload_db_file: bool = False,
|
|
19
|
-
api_url:
|
|
20
|
-
deploy_url:
|
|
18
|
+
api_url: str | None = None,
|
|
19
|
+
deploy_url: str | None = None,
|
|
21
20
|
env: constants.Env = constants.Env.PROD,
|
|
22
21
|
loglevel: constants.LogLevel = console._LOG_LEVEL,
|
|
23
22
|
):
|
reflex/utils/format.py
CHANGED
|
@@ -6,7 +6,7 @@ import inspect
|
|
|
6
6
|
import json
|
|
7
7
|
import os
|
|
8
8
|
import re
|
|
9
|
-
from typing import TYPE_CHECKING, Any,
|
|
9
|
+
from typing import TYPE_CHECKING, Any, Union
|
|
10
10
|
|
|
11
11
|
from reflex import constants
|
|
12
12
|
from reflex.constants.state import FRONTEND_EVENT_STATE
|
|
@@ -336,7 +336,7 @@ def format_route(route: str, format_case: bool = True) -> str:
|
|
|
336
336
|
|
|
337
337
|
def format_match(
|
|
338
338
|
cond: str | Var,
|
|
339
|
-
match_cases:
|
|
339
|
+
match_cases: list[list[Var]],
|
|
340
340
|
default: Var,
|
|
341
341
|
) -> str:
|
|
342
342
|
"""Format a match expression whose return type is a Var.
|
|
@@ -370,7 +370,7 @@ def format_match(
|
|
|
370
370
|
|
|
371
371
|
def format_prop(
|
|
372
372
|
prop: Union[Var, EventChain, ComponentStyle, str],
|
|
373
|
-
) ->
|
|
373
|
+
) -> int | float | str:
|
|
374
374
|
"""Format a prop.
|
|
375
375
|
|
|
376
376
|
Args:
|
|
@@ -532,7 +532,7 @@ if TYPE_CHECKING:
|
|
|
532
532
|
|
|
533
533
|
def format_queue_events(
|
|
534
534
|
events: EventType[Any] | None = None,
|
|
535
|
-
args_spec:
|
|
535
|
+
args_spec: ArgsSpec | None = None,
|
|
536
536
|
) -> Var[EventChain]:
|
|
537
537
|
"""Format a list of event handler / event spec as a javascript callback.
|
|
538
538
|
|
reflex/utils/imports.py
CHANGED
|
@@ -4,7 +4,7 @@ from __future__ import annotations
|
|
|
4
4
|
|
|
5
5
|
import dataclasses
|
|
6
6
|
from collections import defaultdict
|
|
7
|
-
from typing import DefaultDict,
|
|
7
|
+
from typing import DefaultDict, Union
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
def merge_imports(
|
|
@@ -18,7 +18,7 @@ def merge_imports(
|
|
|
18
18
|
Returns:
|
|
19
19
|
The merged import dicts.
|
|
20
20
|
"""
|
|
21
|
-
all_imports: DefaultDict[str,
|
|
21
|
+
all_imports: DefaultDict[str, list[ImportVar]] = defaultdict(list)
|
|
22
22
|
for import_dict in imports:
|
|
23
23
|
for lib, fields in (
|
|
24
24
|
import_dict if isinstance(import_dict, tuple) else import_dict.items()
|
|
@@ -95,26 +95,26 @@ class ImportVar:
|
|
|
95
95
|
"""An import var."""
|
|
96
96
|
|
|
97
97
|
# The name of the import tag.
|
|
98
|
-
tag:
|
|
98
|
+
tag: str | None
|
|
99
99
|
|
|
100
100
|
# whether the import is default or named.
|
|
101
|
-
is_default:
|
|
101
|
+
is_default: bool | None = False
|
|
102
102
|
|
|
103
103
|
# The tag alias.
|
|
104
|
-
alias:
|
|
104
|
+
alias: str | None = None
|
|
105
105
|
|
|
106
106
|
# Whether this import need to install the associated lib
|
|
107
|
-
install:
|
|
107
|
+
install: bool | None = True
|
|
108
108
|
|
|
109
109
|
# whether this import should be rendered or not
|
|
110
|
-
render:
|
|
110
|
+
render: bool | None = True
|
|
111
111
|
|
|
112
112
|
# The path of the package to import from.
|
|
113
113
|
package_path: str = "/"
|
|
114
114
|
|
|
115
115
|
# whether this import package should be added to transpilePackages in next.config.js
|
|
116
116
|
# https://nextjs.org/docs/app/api-reference/next-config-js/transpilePackages
|
|
117
|
-
transpile:
|
|
117
|
+
transpile: bool | None = False
|
|
118
118
|
|
|
119
119
|
@property
|
|
120
120
|
def name(self) -> str:
|
|
@@ -131,7 +131,7 @@ class ImportVar:
|
|
|
131
131
|
return self.tag or ""
|
|
132
132
|
|
|
133
133
|
|
|
134
|
-
ImportTypes = Union[str, ImportVar,
|
|
135
|
-
ImportDict =
|
|
136
|
-
ParsedImportDict =
|
|
137
|
-
ImmutableParsedImportDict =
|
|
134
|
+
ImportTypes = Union[str, ImportVar, list[str | ImportVar], list[ImportVar]]
|
|
135
|
+
ImportDict = dict[str, ImportTypes]
|
|
136
|
+
ParsedImportDict = dict[str, list[ImportVar]]
|
|
137
|
+
ImmutableParsedImportDict = tuple[tuple[str, tuple[ImportVar, ...]], ...]
|
reflex/utils/prerequisites.py
CHANGED
|
@@ -23,7 +23,7 @@ import zipfile
|
|
|
23
23
|
from datetime import datetime
|
|
24
24
|
from pathlib import Path
|
|
25
25
|
from types import ModuleType
|
|
26
|
-
from typing import
|
|
26
|
+
from typing import Callable, NamedTuple
|
|
27
27
|
from urllib.parse import urlparse
|
|
28
28
|
|
|
29
29
|
import httpx
|
|
@@ -72,9 +72,9 @@ class Template:
|
|
|
72
72
|
class CpuInfo:
|
|
73
73
|
"""Model to save cpu info."""
|
|
74
74
|
|
|
75
|
-
manufacturer_id:
|
|
76
|
-
model_name:
|
|
77
|
-
address_width:
|
|
75
|
+
manufacturer_id: str | None
|
|
76
|
+
model_name: str | None
|
|
77
|
+
address_width: int | None
|
|
78
78
|
|
|
79
79
|
|
|
80
80
|
def get_web_dir() -> Path:
|
|
@@ -242,9 +242,7 @@ def get_install_package_manager(on_failure_return_none: bool = False) -> str | N
|
|
|
242
242
|
The path to the package manager.
|
|
243
243
|
"""
|
|
244
244
|
if constants.IS_WINDOWS and (
|
|
245
|
-
|
|
246
|
-
or windows_check_onedrive_in_path()
|
|
247
|
-
or windows_npm_escape_hatch()
|
|
245
|
+
windows_check_onedrive_in_path() or windows_npm_escape_hatch()
|
|
248
246
|
):
|
|
249
247
|
return get_package_manager(on_failure_return_none)
|
|
250
248
|
return str(get_config().bun_path)
|
|
@@ -896,7 +894,7 @@ def init_reflex_json(project_hash: int | None):
|
|
|
896
894
|
|
|
897
895
|
|
|
898
896
|
def update_next_config(
|
|
899
|
-
export: bool = False, transpile_packages:
|
|
897
|
+
export: bool = False, transpile_packages: list[str] | None = None
|
|
900
898
|
):
|
|
901
899
|
"""Update Next.js config from Reflex config.
|
|
902
900
|
|
|
@@ -918,7 +916,7 @@ def update_next_config(
|
|
|
918
916
|
|
|
919
917
|
|
|
920
918
|
def _update_next_config(
|
|
921
|
-
config: Config, export: bool = False, transpile_packages:
|
|
919
|
+
config: Config, export: bool = False, transpile_packages: list[str] | None = None
|
|
922
920
|
):
|
|
923
921
|
next_config = {
|
|
924
922
|
"basePath": config.frontend_path or "",
|
|
@@ -1064,17 +1062,11 @@ def install_bun():
|
|
|
1064
1062
|
Raises:
|
|
1065
1063
|
SystemPackageMissingError: If "unzip" is missing.
|
|
1066
1064
|
"""
|
|
1067
|
-
win_supported = is_windows_bun_supported()
|
|
1068
1065
|
one_drive_in_path = windows_check_onedrive_in_path()
|
|
1069
|
-
if constants.IS_WINDOWS and
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
)
|
|
1074
|
-
if one_drive_in_path:
|
|
1075
|
-
console.warn(
|
|
1076
|
-
"Creating project directories in OneDrive is not recommended for bun usage on windows. This will fallback to npm."
|
|
1077
|
-
)
|
|
1066
|
+
if constants.IS_WINDOWS and one_drive_in_path:
|
|
1067
|
+
console.warn(
|
|
1068
|
+
"Creating project directories in OneDrive is not recommended for bun usage on windows. This will fallback to npm."
|
|
1069
|
+
)
|
|
1078
1070
|
|
|
1079
1071
|
# Skip if bun is already installed.
|
|
1080
1072
|
if get_bun_version() == version.parse(constants.Bun.VERSION):
|
|
@@ -1176,12 +1168,7 @@ def install_frontend_packages(packages: set[str], config: Config):
|
|
|
1176
1168
|
get_package_manager(on_failure_return_none=True)
|
|
1177
1169
|
if (
|
|
1178
1170
|
not constants.IS_WINDOWS
|
|
1179
|
-
or (
|
|
1180
|
-
constants.IS_WINDOWS
|
|
1181
|
-
and (
|
|
1182
|
-
is_windows_bun_supported() and not windows_check_onedrive_in_path()
|
|
1183
|
-
)
|
|
1184
|
-
)
|
|
1171
|
+
or (constants.IS_WINDOWS and not windows_check_onedrive_in_path())
|
|
1185
1172
|
)
|
|
1186
1173
|
else None
|
|
1187
1174
|
)
|
|
@@ -1200,7 +1187,7 @@ def install_frontend_packages(packages: set[str], config: Config):
|
|
|
1200
1187
|
)
|
|
1201
1188
|
|
|
1202
1189
|
processes.run_process_with_fallback(
|
|
1203
|
-
[install_package_manager, "install"],
|
|
1190
|
+
[install_package_manager, "install", "--legacy-peer-deps"],
|
|
1204
1191
|
fallback=fallback_command,
|
|
1205
1192
|
analytics_enabled=True,
|
|
1206
1193
|
show_status_message="Installing base frontend packages",
|
|
@@ -1213,6 +1200,7 @@ def install_frontend_packages(packages: set[str], config: Config):
|
|
|
1213
1200
|
[
|
|
1214
1201
|
install_package_manager,
|
|
1215
1202
|
"add",
|
|
1203
|
+
"--legacy-peer-deps",
|
|
1216
1204
|
"-d",
|
|
1217
1205
|
constants.Tailwind.VERSION,
|
|
1218
1206
|
*((config.tailwind or {}).get("plugins", [])),
|
|
@@ -1227,7 +1215,7 @@ def install_frontend_packages(packages: set[str], config: Config):
|
|
|
1227
1215
|
# Install custom packages defined in frontend_packages
|
|
1228
1216
|
if len(packages) > 0:
|
|
1229
1217
|
processes.run_process_with_fallback(
|
|
1230
|
-
[install_package_manager, "add", *packages],
|
|
1218
|
+
[install_package_manager, "add", "--legacy-peer-deps", *packages],
|
|
1231
1219
|
fallback=fallback_command,
|
|
1232
1220
|
analytics_enabled=True,
|
|
1233
1221
|
show_status_message="Installing frontend packages from config and components",
|
|
@@ -1371,7 +1359,7 @@ def validate_frontend_dependencies(init: bool = True):
|
|
|
1371
1359
|
validate_bun()
|
|
1372
1360
|
|
|
1373
1361
|
|
|
1374
|
-
def ensure_reflex_installation_id() ->
|
|
1362
|
+
def ensure_reflex_installation_id() -> int | None:
|
|
1375
1363
|
"""Ensures that a reflex distinct id has been generated and stored in the reflex directory.
|
|
1376
1364
|
|
|
1377
1365
|
Returns:
|
|
@@ -1925,24 +1913,23 @@ def format_address_width(address_width: str | None) -> int | None:
|
|
|
1925
1913
|
return None
|
|
1926
1914
|
|
|
1927
1915
|
|
|
1928
|
-
|
|
1929
|
-
|
|
1930
|
-
"""Get the CPU info of the underlining host.
|
|
1916
|
+
def _retrieve_cpu_info() -> CpuInfo | None:
|
|
1917
|
+
"""Retrieve the CPU info of the host.
|
|
1931
1918
|
|
|
1932
1919
|
Returns:
|
|
1933
|
-
|
|
1920
|
+
The CPU info.
|
|
1934
1921
|
"""
|
|
1935
1922
|
platform_os = platform.system()
|
|
1936
1923
|
cpuinfo = {}
|
|
1937
1924
|
try:
|
|
1938
1925
|
if platform_os == "Windows":
|
|
1939
|
-
cmd = "
|
|
1926
|
+
cmd = 'powershell -Command "Get-CimInstance Win32_Processor | Select-Object -First 1 | Select-Object AddressWidth,Manufacturer,Name | ConvertTo-Json"'
|
|
1940
1927
|
output = processes.execute_command_and_return_output(cmd)
|
|
1941
1928
|
if output:
|
|
1942
|
-
|
|
1943
|
-
cpuinfo["
|
|
1944
|
-
cpuinfo["
|
|
1945
|
-
cpuinfo["
|
|
1929
|
+
cpu_data = json.loads(output)
|
|
1930
|
+
cpuinfo["address_width"] = cpu_data["AddressWidth"]
|
|
1931
|
+
cpuinfo["manufacturer_id"] = cpu_data["Manufacturer"]
|
|
1932
|
+
cpuinfo["model_name"] = cpu_data["Name"]
|
|
1946
1933
|
elif platform_os == "Linux":
|
|
1947
1934
|
output = processes.execute_command_and_return_output("lscpu")
|
|
1948
1935
|
if output:
|
|
@@ -1982,21 +1969,20 @@ def get_cpu_info() -> CpuInfo | None:
|
|
|
1982
1969
|
|
|
1983
1970
|
|
|
1984
1971
|
@functools.lru_cache(maxsize=None)
|
|
1985
|
-
def
|
|
1986
|
-
"""
|
|
1987
|
-
We typically do not run bun on ARM or 32 bit devices that use windows.
|
|
1972
|
+
def get_cpu_info() -> CpuInfo | None:
|
|
1973
|
+
"""Get the CPU info of the underlining host.
|
|
1988
1974
|
|
|
1989
1975
|
Returns:
|
|
1990
|
-
|
|
1976
|
+
The CPU info.
|
|
1991
1977
|
"""
|
|
1992
|
-
|
|
1993
|
-
|
|
1994
|
-
|
|
1995
|
-
|
|
1996
|
-
|
|
1997
|
-
|
|
1998
|
-
|
|
1999
|
-
|
|
1978
|
+
cpu_info_file = environment.REFLEX_DIR.get() / "cpu_info.json"
|
|
1979
|
+
if cpu_info_file.exists() and (cpu_info := json.loads(cpu_info_file.read_text())):
|
|
1980
|
+
return CpuInfo(**cpu_info)
|
|
1981
|
+
cpu_info = _retrieve_cpu_info()
|
|
1982
|
+
if cpu_info:
|
|
1983
|
+
cpu_info_file.parent.mkdir(parents=True, exist_ok=True)
|
|
1984
|
+
cpu_info_file.write_text(json.dumps(dataclasses.asdict(cpu_info)))
|
|
1985
|
+
return cpu_info
|
|
2000
1986
|
|
|
2001
1987
|
|
|
2002
1988
|
def is_generation_hash(template: str) -> bool:
|
|
@@ -2025,38 +2011,3 @@ def get_user_tier():
|
|
|
2025
2011
|
if authenticated_token[0]
|
|
2026
2012
|
else "anonymous"
|
|
2027
2013
|
)
|
|
2028
|
-
|
|
2029
|
-
|
|
2030
|
-
def check_config_option_in_tier(
|
|
2031
|
-
option_name: str,
|
|
2032
|
-
allowed_tiers: list[str],
|
|
2033
|
-
fallback_value: Any,
|
|
2034
|
-
help_link: str | None = None,
|
|
2035
|
-
):
|
|
2036
|
-
"""Check if a config option is allowed for the authenticated user's current tier.
|
|
2037
|
-
|
|
2038
|
-
Args:
|
|
2039
|
-
option_name: The name of the option to check.
|
|
2040
|
-
allowed_tiers: The tiers that are allowed to use the option.
|
|
2041
|
-
fallback_value: The fallback value if the option is not allowed.
|
|
2042
|
-
help_link: The help link to show to a user that is authenticated.
|
|
2043
|
-
"""
|
|
2044
|
-
config = get_config()
|
|
2045
|
-
current_tier = get_user_tier()
|
|
2046
|
-
|
|
2047
|
-
if current_tier == "anonymous":
|
|
2048
|
-
the_remedy = (
|
|
2049
|
-
"You are currently logged out. Run `reflex login` to access this option."
|
|
2050
|
-
)
|
|
2051
|
-
else:
|
|
2052
|
-
the_remedy = (
|
|
2053
|
-
f"Your current subscription tier is `{current_tier}`. "
|
|
2054
|
-
f"Please upgrade to {allowed_tiers} to access this option. "
|
|
2055
|
-
)
|
|
2056
|
-
if help_link:
|
|
2057
|
-
the_remedy += f"See {help_link} for more information."
|
|
2058
|
-
|
|
2059
|
-
if current_tier not in allowed_tiers:
|
|
2060
|
-
console.warn(f"Config option `{option_name}` is restricted. {the_remedy}")
|
|
2061
|
-
setattr(config, option_name, fallback_value)
|
|
2062
|
-
config._set_persistent(**{option_name: fallback_value})
|
reflex/utils/processes.py
CHANGED
|
@@ -10,7 +10,7 @@ import signal
|
|
|
10
10
|
import subprocess
|
|
11
11
|
from concurrent import futures
|
|
12
12
|
from pathlib import Path
|
|
13
|
-
from typing import Callable, Generator,
|
|
13
|
+
from typing import Callable, Generator, Tuple
|
|
14
14
|
|
|
15
15
|
import psutil
|
|
16
16
|
import typer
|
|
@@ -50,7 +50,7 @@ def get_num_workers() -> int:
|
|
|
50
50
|
return (os.cpu_count() or 1) * 2 + 1
|
|
51
51
|
|
|
52
52
|
|
|
53
|
-
def get_process_on_port(port: int) ->
|
|
53
|
+
def get_process_on_port(port: int) -> psutil.Process | None:
|
|
54
54
|
"""Get the process on the given port.
|
|
55
55
|
|
|
56
56
|
Args:
|
|
@@ -202,7 +202,7 @@ def new_process(
|
|
|
202
202
|
|
|
203
203
|
@contextlib.contextmanager
|
|
204
204
|
def run_concurrently_context(
|
|
205
|
-
*fns:
|
|
205
|
+
*fns: Callable | Tuple,
|
|
206
206
|
) -> Generator[list[futures.Future], None, None]:
|
|
207
207
|
"""Run functions concurrently in a thread pool.
|
|
208
208
|
|
|
@@ -240,7 +240,7 @@ def run_concurrently_context(
|
|
|
240
240
|
executor.shutdown(wait=False)
|
|
241
241
|
|
|
242
242
|
|
|
243
|
-
def run_concurrently(*fns:
|
|
243
|
+
def run_concurrently(*fns: Callable | Tuple) -> None:
|
|
244
244
|
"""Run functions concurrently in a thread pool.
|
|
245
245
|
|
|
246
246
|
Args:
|
|
@@ -335,7 +335,7 @@ def show_status(
|
|
|
335
335
|
status.update(f"{message} {line}")
|
|
336
336
|
|
|
337
337
|
|
|
338
|
-
def show_progress(message: str, process: subprocess.Popen, checkpoints:
|
|
338
|
+
def show_progress(message: str, process: subprocess.Popen, checkpoints: list[str]):
|
|
339
339
|
"""Show a progress bar for a process.
|
|
340
340
|
|
|
341
341
|
Args:
|