reflex 0.7.13a2__py3-none-any.whl → 0.7.14a2__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/apps/blank/code/blank.py +0 -2
- reflex/app.py +64 -69
- reflex/app_mixins/lifespan.py +2 -3
- reflex/app_mixins/middleware.py +1 -0
- reflex/app_mixins/mixin.py +0 -1
- reflex/assets.py +6 -3
- reflex/base.py +3 -2
- reflex/compiler/compiler.py +77 -64
- reflex/compiler/utils.py +8 -6
- reflex/components/base/app_wrap.pyi +0 -1
- reflex/components/base/bare.py +5 -7
- reflex/components/base/body.pyi +0 -1
- reflex/components/base/document.pyi +0 -5
- reflex/components/base/error_boundary.pyi +0 -1
- reflex/components/base/fragment.pyi +0 -1
- reflex/components/base/head.pyi +0 -2
- reflex/components/base/link.pyi +0 -2
- reflex/components/base/meta.py +2 -1
- reflex/components/base/meta.pyi +0 -4
- reflex/components/base/script.py +2 -1
- reflex/components/base/script.pyi +0 -1
- reflex/components/base/strict_mode.pyi +0 -1
- reflex/components/component.py +49 -41
- reflex/components/core/auto_scroll.pyi +0 -1
- reflex/components/core/banner.pyi +0 -6
- reflex/components/core/breakpoints.py +9 -11
- reflex/components/core/client_side_routing.pyi +0 -2
- reflex/components/core/clipboard.pyi +0 -1
- reflex/components/core/colors.py +10 -7
- reflex/components/core/cond.py +4 -2
- reflex/components/core/debounce.py +5 -3
- reflex/components/core/debounce.pyi +0 -1
- reflex/components/core/foreach.py +8 -6
- reflex/components/core/html.py +3 -3
- reflex/components/core/html.pyi +0 -1
- reflex/components/core/match.py +19 -17
- reflex/components/core/sticky.pyi +0 -4
- reflex/components/core/upload.pyi +0 -5
- reflex/components/datadisplay/code.py +1 -2
- reflex/components/datadisplay/code.pyi +0 -2
- reflex/components/datadisplay/dataeditor.py +7 -10
- reflex/components/datadisplay/dataeditor.pyi +0 -1
- reflex/components/datadisplay/logo.py +3 -4
- reflex/components/datadisplay/shiki_code_block.py +8 -11
- reflex/components/datadisplay/shiki_code_block.pyi +0 -3
- reflex/components/dynamic.py +2 -3
- reflex/components/el/__init__.pyi +2 -0
- reflex/components/el/element.pyi +0 -1
- reflex/components/el/elements/__init__.py +1 -0
- reflex/components/el/elements/__init__.pyi +3 -0
- reflex/components/el/elements/base.pyi +0 -1
- reflex/components/el/elements/forms.py +14 -15
- reflex/components/el/elements/forms.pyi +15 -32
- reflex/components/el/elements/inline.pyi +0 -28
- reflex/components/el/elements/media.py +26 -0
- reflex/components/el/elements/media.pyi +259 -25
- reflex/components/el/elements/metadata.py +0 -1
- reflex/components/el/elements/metadata.pyi +0 -6
- reflex/components/el/elements/other.pyi +0 -7
- reflex/components/el/elements/scripts.pyi +0 -3
- reflex/components/el/elements/sectioning.pyi +0 -15
- reflex/components/el/elements/tables.pyi +0 -10
- reflex/components/el/elements/typography.pyi +0 -15
- reflex/components/gridjs/datatable.py +10 -13
- reflex/components/gridjs/datatable.pyi +0 -2
- reflex/components/lucide/icon.py +10 -9
- reflex/components/lucide/icon.pyi +0 -3
- reflex/components/markdown/markdown.py +6 -8
- reflex/components/markdown/markdown.pyi +0 -1
- reflex/components/moment/moment.pyi +0 -1
- reflex/components/next/base.py +0 -2
- reflex/components/next/base.pyi +0 -3
- reflex/components/next/image.pyi +0 -1
- reflex/components/next/link.pyi +0 -1
- reflex/components/next/video.pyi +0 -1
- reflex/components/plotly/plotly.pyi +0 -9
- reflex/components/props.py +4 -3
- reflex/components/radix/primitives/accordion.pyi +0 -7
- reflex/components/radix/primitives/base.py +1 -3
- reflex/components/radix/primitives/base.pyi +0 -2
- reflex/components/radix/primitives/drawer.pyi +0 -11
- reflex/components/radix/primitives/form.py +4 -8
- reflex/components/radix/primitives/form.pyi +0 -12
- reflex/components/radix/primitives/progress.py +1 -1
- reflex/components/radix/primitives/progress.pyi +0 -5
- reflex/components/radix/primitives/slider.py +1 -1
- reflex/components/radix/primitives/slider.pyi +0 -5
- reflex/components/radix/themes/base.pyi +0 -8
- reflex/components/radix/themes/color_mode.pyi +0 -3
- reflex/components/radix/themes/components/alert_dialog.py +4 -2
- reflex/components/radix/themes/components/alert_dialog.pyi +4 -9
- reflex/components/radix/themes/components/aspect_ratio.py +1 -2
- reflex/components/radix/themes/components/aspect_ratio.pyi +1 -3
- reflex/components/radix/themes/components/avatar.py +5 -2
- reflex/components/radix/themes/components/avatar.pyi +1 -3
- reflex/components/radix/themes/components/badge.py +5 -2
- reflex/components/radix/themes/components/badge.pyi +1 -3
- reflex/components/radix/themes/components/button.py +2 -3
- reflex/components/radix/themes/components/button.pyi +1 -3
- reflex/components/radix/themes/components/callout.py +1 -2
- reflex/components/radix/themes/components/callout.pyi +1 -7
- reflex/components/radix/themes/components/card.py +1 -2
- reflex/components/radix/themes/components/card.pyi +1 -3
- reflex/components/radix/themes/components/checkbox.py +7 -4
- reflex/components/radix/themes/components/checkbox.pyi +1 -5
- reflex/components/radix/themes/components/checkbox_cards.py +1 -2
- reflex/components/radix/themes/components/checkbox_cards.pyi +1 -4
- reflex/components/radix/themes/components/checkbox_group.py +1 -2
- reflex/components/radix/themes/components/checkbox_group.pyi +1 -4
- reflex/components/radix/themes/components/context_menu.py +1 -1
- reflex/components/radix/themes/components/context_menu.pyi +1 -14
- reflex/components/radix/themes/components/data_list.py +1 -2
- reflex/components/radix/themes/components/data_list.pyi +1 -6
- reflex/components/radix/themes/components/dialog.py +4 -2
- reflex/components/radix/themes/components/dialog.pyi +4 -9
- reflex/components/radix/themes/components/dropdown_menu.py +5 -2
- reflex/components/radix/themes/components/dropdown_menu.pyi +4 -10
- reflex/components/radix/themes/components/hover_card.py +4 -2
- reflex/components/radix/themes/components/hover_card.pyi +4 -6
- reflex/components/radix/themes/components/icon_button.py +7 -8
- reflex/components/radix/themes/components/icon_button.pyi +1 -3
- reflex/components/radix/themes/components/inset.py +1 -2
- reflex/components/radix/themes/components/inset.pyi +1 -3
- reflex/components/radix/themes/components/popover.py +4 -2
- reflex/components/radix/themes/components/popover.pyi +4 -6
- reflex/components/radix/themes/components/progress.py +1 -2
- reflex/components/radix/themes/components/progress.pyi +1 -3
- reflex/components/radix/themes/components/radio.py +1 -2
- reflex/components/radix/themes/components/radio.pyi +1 -3
- reflex/components/radix/themes/components/radio_cards.py +1 -2
- reflex/components/radix/themes/components/radio_cards.pyi +1 -4
- reflex/components/radix/themes/components/radio_group.py +7 -5
- reflex/components/radix/themes/components/radio_group.pyi +1 -6
- reflex/components/radix/themes/components/scroll_area.py +1 -2
- reflex/components/radix/themes/components/scroll_area.pyi +1 -3
- reflex/components/radix/themes/components/segmented_control.py +1 -2
- reflex/components/radix/themes/components/segmented_control.pyi +1 -4
- reflex/components/radix/themes/components/select.py +5 -2
- reflex/components/radix/themes/components/select.pyi +1 -11
- reflex/components/radix/themes/components/separator.py +1 -2
- reflex/components/radix/themes/components/separator.pyi +1 -3
- reflex/components/radix/themes/components/skeleton.py +1 -2
- reflex/components/radix/themes/components/skeleton.pyi +1 -3
- reflex/components/radix/themes/components/slider.py +1 -2
- reflex/components/radix/themes/components/slider.pyi +1 -3
- reflex/components/radix/themes/components/spinner.py +1 -2
- reflex/components/radix/themes/components/spinner.pyi +1 -3
- reflex/components/radix/themes/components/switch.py +1 -2
- reflex/components/radix/themes/components/switch.pyi +1 -3
- reflex/components/radix/themes/components/table.py +1 -2
- reflex/components/radix/themes/components/table.pyi +1 -9
- reflex/components/radix/themes/components/tabs.py +1 -2
- reflex/components/radix/themes/components/tabs.pyi +1 -7
- reflex/components/radix/themes/components/text_area.py +5 -2
- reflex/components/radix/themes/components/text_area.pyi +2 -4
- reflex/components/radix/themes/components/text_field.py +5 -2
- reflex/components/radix/themes/components/text_field.pyi +1 -5
- reflex/components/radix/themes/components/tooltip.py +1 -2
- reflex/components/radix/themes/components/tooltip.pyi +1 -3
- reflex/components/radix/themes/layout/base.py +5 -2
- reflex/components/radix/themes/layout/base.pyi +5 -3
- reflex/components/radix/themes/layout/box.py +1 -2
- reflex/components/radix/themes/layout/box.pyi +1 -3
- reflex/components/radix/themes/layout/center.pyi +0 -1
- reflex/components/radix/themes/layout/container.py +1 -2
- reflex/components/radix/themes/layout/container.pyi +1 -3
- reflex/components/radix/themes/layout/flex.py +6 -2
- reflex/components/radix/themes/layout/flex.pyi +1 -3
- reflex/components/radix/themes/layout/grid.py +6 -2
- reflex/components/radix/themes/layout/grid.pyi +1 -3
- reflex/components/radix/themes/layout/list.py +2 -1
- reflex/components/radix/themes/layout/list.pyi +0 -5
- reflex/components/radix/themes/layout/section.py +1 -2
- reflex/components/radix/themes/layout/section.pyi +1 -3
- reflex/components/radix/themes/layout/spacer.pyi +0 -1
- reflex/components/radix/themes/layout/stack.py +1 -1
- reflex/components/radix/themes/layout/stack.pyi +0 -3
- reflex/components/radix/themes/typography/blockquote.py +1 -1
- reflex/components/radix/themes/typography/blockquote.pyi +1 -3
- reflex/components/radix/themes/typography/code.py +5 -1
- reflex/components/radix/themes/typography/code.pyi +1 -3
- reflex/components/radix/themes/typography/heading.py +1 -1
- reflex/components/radix/themes/typography/heading.pyi +1 -3
- reflex/components/radix/themes/typography/link.py +3 -2
- reflex/components/radix/themes/typography/link.pyi +1 -3
- reflex/components/radix/themes/typography/text.py +1 -1
- reflex/components/radix/themes/typography/text.pyi +1 -9
- reflex/components/react_player/audio.py +0 -2
- reflex/components/react_player/audio.pyi +0 -3
- reflex/components/react_player/react_player.pyi +0 -1
- reflex/components/react_player/video.py +0 -2
- reflex/components/react_player/video.pyi +0 -3
- reflex/components/recharts/__init__.py +1 -1
- reflex/components/recharts/__init__.pyi +1 -1
- reflex/components/recharts/cartesian.py +20 -25
- reflex/components/recharts/cartesian.pyi +20 -37
- reflex/components/recharts/charts.py +2 -1
- reflex/components/recharts/charts.pyi +0 -12
- reflex/components/recharts/general.pyi +0 -6
- reflex/components/recharts/polar.py +5 -4
- reflex/components/recharts/polar.pyi +4 -10
- reflex/components/recharts/recharts.py +12 -10
- reflex/components/recharts/recharts.pyi +10 -11
- reflex/components/sonner/toast.py +2 -2
- reflex/components/sonner/toast.pyi +0 -2
- reflex/components/suneditor/editor.py +2 -1
- reflex/components/suneditor/editor.pyi +0 -1
- reflex/components/tags/iter_tag.py +4 -2
- reflex/config.py +47 -35
- reflex/constants/base.py +3 -3
- reflex/constants/compiler.py +8 -6
- reflex/constants/installer.py +24 -15
- reflex/custom_components/custom_components.py +1 -2
- reflex/event.py +58 -60
- reflex/experimental/__init__.py +2 -2
- reflex/experimental/client_state.py +9 -4
- reflex/experimental/layout.pyi +0 -5
- reflex/istate/manager.py +15 -19
- reflex/istate/proxy.py +19 -12
- reflex/model.py +6 -4
- reflex/plugins/base.py +8 -0
- reflex/plugins/tailwind_v3.py +8 -0
- reflex/plugins/tailwind_v4.py +8 -0
- reflex/reflex.py +9 -11
- reflex/route.py +7 -9
- reflex/state.py +66 -70
- reflex/style.py +3 -1
- reflex/testing.py +46 -29
- reflex/utils/build.py +2 -1
- reflex/utils/console.py +9 -17
- reflex/utils/exec.py +9 -11
- reflex/utils/format.py +21 -24
- reflex/utils/imports.py +4 -3
- reflex/utils/lazy_loader.py +3 -3
- reflex/utils/misc.py +2 -1
- reflex/utils/net.py +2 -2
- reflex/utils/path_ops.py +2 -1
- reflex/utils/prerequisites.py +67 -38
- reflex/utils/processes.py +4 -6
- reflex/utils/pyi_generator.py +46 -41
- reflex/utils/redir.py +1 -1
- reflex/utils/serializers.py +4 -4
- reflex/utils/telemetry.py +20 -2
- reflex/utils/types.py +16 -13
- reflex/vars/base.py +96 -109
- reflex/vars/datetime.py +2 -1
- reflex/vars/dep_tracking.py +19 -28
- reflex/vars/number.py +6 -7
- reflex/vars/object.py +5 -6
- reflex/vars/sequence.py +11 -11
- {reflex-0.7.13a2.dist-info → reflex-0.7.14a2.dist-info}/METADATA +1 -1
- reflex-0.7.14a2.dist-info/RECORD +407 -0
- reflex-0.7.13a2.dist-info/RECORD +0 -407
- {reflex-0.7.13a2.dist-info → reflex-0.7.14a2.dist-info}/WHEEL +0 -0
- {reflex-0.7.13a2.dist-info → reflex-0.7.14a2.dist-info}/entry_points.txt +0 -0
- {reflex-0.7.13a2.dist-info → reflex-0.7.14a2.dist-info}/licenses/LICENSE +0 -0
reflex/constants/installer.py
CHANGED
|
@@ -14,7 +14,7 @@ class Bun(SimpleNamespace):
|
|
|
14
14
|
"""Bun constants."""
|
|
15
15
|
|
|
16
16
|
# The Bun version.
|
|
17
|
-
VERSION = "1.2.
|
|
17
|
+
VERSION = "1.2.15"
|
|
18
18
|
|
|
19
19
|
# Min Bun Version
|
|
20
20
|
MIN_VERSION = "1.2.8"
|
|
@@ -113,22 +113,31 @@ class PackageJson(SimpleNamespace):
|
|
|
113
113
|
|
|
114
114
|
_react_version = _determine_react_version()
|
|
115
115
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
"
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
"
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
116
|
+
@classproperty
|
|
117
|
+
@classmethod
|
|
118
|
+
def DEPENDENCIES(cls) -> dict[str, str]:
|
|
119
|
+
"""The dependencies to include in package.json.
|
|
120
|
+
|
|
121
|
+
Returns:
|
|
122
|
+
A dictionary of dependencies with their versions.
|
|
123
|
+
"""
|
|
124
|
+
return {
|
|
125
|
+
"@emotion/react": "11.14.0",
|
|
126
|
+
"axios": "1.9.0",
|
|
127
|
+
"json5": "2.2.3",
|
|
128
|
+
"next": _determine_nextjs_version(),
|
|
129
|
+
"next-sitemap": "4.2.3",
|
|
130
|
+
"next-themes": "0.4.6",
|
|
131
|
+
"react": cls._react_version,
|
|
132
|
+
"react-dom": cls._react_version,
|
|
133
|
+
"react-focus-lock": "2.13.6",
|
|
134
|
+
"socket.io-client": "4.8.1",
|
|
135
|
+
"universal-cookie": "7.2.2",
|
|
136
|
+
}
|
|
137
|
+
|
|
129
138
|
DEV_DEPENDENCIES = {
|
|
130
139
|
"autoprefixer": "10.4.21",
|
|
131
|
-
"postcss": "8.5.
|
|
140
|
+
"postcss": "8.5.4",
|
|
132
141
|
"postcss-import": "16.1.0",
|
|
133
142
|
}
|
|
134
143
|
OVERRIDES = {
|
|
@@ -35,7 +35,6 @@ def set_loglevel(ctx: Any, self: Any, value: str | None):
|
|
|
35
35
|
@click.group
|
|
36
36
|
def custom_components_cli():
|
|
37
37
|
"""CLI for creating custom components."""
|
|
38
|
-
pass
|
|
39
38
|
|
|
40
39
|
|
|
41
40
|
loglevel_option = click.option(
|
|
@@ -575,7 +574,7 @@ def _validate_url_with_protocol_prefix(url: str | None) -> bool:
|
|
|
575
574
|
Returns:
|
|
576
575
|
Whether the entered URL is acceptable.
|
|
577
576
|
"""
|
|
578
|
-
return not url or (url.startswith("http://"
|
|
577
|
+
return not url or (url.startswith(("http://", "https://")))
|
|
579
578
|
|
|
580
579
|
|
|
581
580
|
def _get_file_from_prompt_in_loop() -> tuple[bytes, str] | None:
|
reflex/event.py
CHANGED
|
@@ -228,9 +228,8 @@ class EventHandler(EventActionsMixin):
|
|
|
228
228
|
),
|
|
229
229
|
Unset,
|
|
230
230
|
):
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
)
|
|
231
|
+
msg = f"Event handler {self.fn.__name__} received repeated argument {repeated_arg}."
|
|
232
|
+
raise EventHandlerTypeError(msg)
|
|
234
233
|
|
|
235
234
|
if not isinstance(
|
|
236
235
|
extra_arg := next(
|
|
@@ -238,9 +237,10 @@ class EventHandler(EventActionsMixin):
|
|
|
238
237
|
),
|
|
239
238
|
Unset,
|
|
240
239
|
):
|
|
241
|
-
|
|
240
|
+
msg = (
|
|
242
241
|
f"Event handler {self.fn.__name__} received extra argument {extra_arg}."
|
|
243
242
|
)
|
|
243
|
+
raise EventHandlerTypeError(msg)
|
|
244
244
|
|
|
245
245
|
fn_args = fn_args[: len(args)] + list(kwargs)
|
|
246
246
|
|
|
@@ -257,9 +257,8 @@ class EventHandler(EventActionsMixin):
|
|
|
257
257
|
try:
|
|
258
258
|
values.append(LiteralVar.create(arg))
|
|
259
259
|
except TypeError as e:
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
) from e
|
|
260
|
+
msg = f"Arguments to event handlers must be Vars or JSON-serializable. Got {arg} of type {type(arg)}."
|
|
261
|
+
raise EventHandlerTypeError(msg) from e
|
|
263
262
|
payload = tuple(zip(fn_args, values, strict=False))
|
|
264
263
|
|
|
265
264
|
# Return the event spec.
|
|
@@ -353,9 +352,8 @@ class EventSpec(EventActionsMixin):
|
|
|
353
352
|
for arg in args:
|
|
354
353
|
values.append(LiteralVar.create(value=arg)) # noqa: PERF401, RUF100
|
|
355
354
|
except TypeError as e:
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
) from e
|
|
355
|
+
msg = f"Arguments to event handlers must be Vars or JSON-serializable. Got {arg} of type {type(arg)}."
|
|
356
|
+
raise EventHandlerTypeError(msg) from e
|
|
359
357
|
new_payload = tuple(zip(fn_args, values, strict=False))
|
|
360
358
|
return self.with_args(self.args + new_payload)
|
|
361
359
|
|
|
@@ -408,7 +406,8 @@ class CallableEventSpec(EventSpec):
|
|
|
408
406
|
from reflex.utils.exceptions import EventHandlerTypeError
|
|
409
407
|
|
|
410
408
|
if self.fn is None:
|
|
411
|
-
|
|
409
|
+
msg = "CallableEventSpec has no associated function."
|
|
410
|
+
raise EventHandlerTypeError(msg)
|
|
412
411
|
return self.fn(*args, **kwargs)
|
|
413
412
|
|
|
414
413
|
|
|
@@ -453,7 +452,7 @@ class EventChain(EventActionsMixin):
|
|
|
453
452
|
if isinstance(value, Var):
|
|
454
453
|
if isinstance(value, EventChainVar):
|
|
455
454
|
return value
|
|
456
|
-
|
|
455
|
+
if isinstance(value, EventVar):
|
|
457
456
|
value = [value]
|
|
458
457
|
elif safe_issubclass(value._var_type, (EventChain, EventSpec)):
|
|
459
458
|
return cls.create(
|
|
@@ -463,9 +462,8 @@ class EventChain(EventActionsMixin):
|
|
|
463
462
|
**event_chain_kwargs,
|
|
464
463
|
)
|
|
465
464
|
else:
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
)
|
|
465
|
+
msg = f"Invalid event chain: {value!s} of type {value._var_type}"
|
|
466
|
+
raise ValueError(msg)
|
|
469
467
|
elif isinstance(value, EventChain):
|
|
470
468
|
# Trust that the caller knows what they're doing passing an EventChain directly
|
|
471
469
|
return value
|
|
@@ -485,15 +483,17 @@ class EventChain(EventActionsMixin):
|
|
|
485
483
|
# Call the lambda to get the event chain.
|
|
486
484
|
result = call_event_fn(v, args_spec, key=key)
|
|
487
485
|
if isinstance(result, Var):
|
|
488
|
-
|
|
486
|
+
msg = (
|
|
489
487
|
f"Invalid event chain: {v}. Cannot use a Var-returning "
|
|
490
488
|
"lambda inside an EventChain list."
|
|
491
489
|
)
|
|
490
|
+
raise ValueError(msg)
|
|
492
491
|
events.extend(result)
|
|
493
492
|
elif isinstance(v, EventVar):
|
|
494
493
|
events.append(v)
|
|
495
494
|
else:
|
|
496
|
-
|
|
495
|
+
msg = f"Invalid event: {v}"
|
|
496
|
+
raise ValueError(msg)
|
|
497
497
|
|
|
498
498
|
# If the input is a callable, create an event chain.
|
|
499
499
|
elif isinstance(value, Callable):
|
|
@@ -507,7 +507,8 @@ class EventChain(EventActionsMixin):
|
|
|
507
507
|
|
|
508
508
|
# Otherwise, raise an error.
|
|
509
509
|
else:
|
|
510
|
-
|
|
510
|
+
msg = f"Invalid event chain: {value}"
|
|
511
|
+
raise ValueError(msg)
|
|
511
512
|
|
|
512
513
|
# Add args to the event specs if necessary.
|
|
513
514
|
events = [
|
|
@@ -783,9 +784,11 @@ class FileUpload:
|
|
|
783
784
|
on_upload_progress, self.on_upload_progress_args_spec
|
|
784
785
|
)
|
|
785
786
|
else:
|
|
786
|
-
|
|
787
|
+
msg = f"{on_upload_progress} is not a valid event handler."
|
|
788
|
+
raise ValueError(msg)
|
|
787
789
|
if isinstance(events, Var):
|
|
788
|
-
|
|
790
|
+
msg = f"{on_upload_progress} cannot return a var {events}."
|
|
791
|
+
raise ValueError(msg)
|
|
789
792
|
on_upload_progress_chain = EventChain(
|
|
790
793
|
events=[*events],
|
|
791
794
|
args_spec=self.on_upload_progress_args_spec,
|
|
@@ -1081,7 +1084,8 @@ def download(
|
|
|
1081
1084
|
|
|
1082
1085
|
if isinstance(url, str):
|
|
1083
1086
|
if not url.startswith("/"):
|
|
1084
|
-
|
|
1087
|
+
msg = "The URL argument should start with a /"
|
|
1088
|
+
raise ValueError(msg)
|
|
1085
1089
|
|
|
1086
1090
|
# if filename is not provided, infer it from url
|
|
1087
1091
|
if filename is None:
|
|
@@ -1092,7 +1096,8 @@ def download(
|
|
|
1092
1096
|
|
|
1093
1097
|
if data is not None:
|
|
1094
1098
|
if url is not None:
|
|
1095
|
-
|
|
1099
|
+
msg = "Cannot provide both URL and data to download."
|
|
1100
|
+
raise ValueError(msg)
|
|
1096
1101
|
|
|
1097
1102
|
if isinstance(data, str):
|
|
1098
1103
|
# Caller provided a plain text string to download.
|
|
@@ -1115,9 +1120,8 @@ def download(
|
|
|
1115
1120
|
b64_data = b64encode(data).decode("utf-8")
|
|
1116
1121
|
url = "data:application/octet-stream;base64," + b64_data
|
|
1117
1122
|
else:
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
)
|
|
1123
|
+
msg = f"Invalid data type {type(data)} for download. Use `str` or `bytes`."
|
|
1124
|
+
raise ValueError(msg)
|
|
1121
1125
|
|
|
1122
1126
|
return server_side(
|
|
1123
1127
|
"_download",
|
|
@@ -1323,23 +1327,21 @@ def _check_event_args_subclass_of_callback(
|
|
|
1323
1327
|
except TypeError as te:
|
|
1324
1328
|
callback_name_context = f" of {callback_name}" if callback_name else ""
|
|
1325
1329
|
key_context = f" for {key}" if key else ""
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
) from te
|
|
1330
|
+
msg = f"Could not compare types {args_types_without_vars[i]} and {callback_param_name_to_type[arg]} for argument {arg}{callback_name_context}{key_context}."
|
|
1331
|
+
raise TypeError(msg) from te
|
|
1329
1332
|
|
|
1330
1333
|
if compare_result:
|
|
1331
1334
|
type_match_found[arg] = True
|
|
1332
1335
|
continue
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
f"Event handler {key} expects {args_types_without_vars[i]} for argument {arg} but got {callback_param_name_to_type[arg]}{as_annotated_in} instead."
|
|
1341
|
-
)
|
|
1336
|
+
type_match_found[arg] = False
|
|
1337
|
+
as_annotated_in = (
|
|
1338
|
+
f" as annotated in {callback_name}" if callback_name else ""
|
|
1339
|
+
)
|
|
1340
|
+
delayed_exceptions.append(
|
|
1341
|
+
EventHandlerArgTypeMismatchError(
|
|
1342
|
+
f"Event handler {key} expects {args_types_without_vars[i]} for argument {arg} but got {callback_param_name_to_type[arg]}{as_annotated_in} instead."
|
|
1342
1343
|
)
|
|
1344
|
+
)
|
|
1343
1345
|
|
|
1344
1346
|
if all(type_match_found.values()):
|
|
1345
1347
|
delayed_exceptions.clear()
|
|
@@ -1495,8 +1497,7 @@ def resolve_annotation(annotations: dict[str, Any], arg_name: str, spec: ArgsSpe
|
|
|
1495
1497
|
if annotation is None:
|
|
1496
1498
|
if not isinstance(spec, types.LambdaType):
|
|
1497
1499
|
raise MissingAnnotationError(var_name=arg_name)
|
|
1498
|
-
|
|
1499
|
-
return dict[str, dict]
|
|
1500
|
+
return dict[str, dict]
|
|
1500
1501
|
return annotation
|
|
1501
1502
|
|
|
1502
1503
|
|
|
@@ -1570,12 +1571,13 @@ def check_fn_match_arg_spec(
|
|
|
1570
1571
|
number_of_event_args = len(parsed_event_args)
|
|
1571
1572
|
|
|
1572
1573
|
if number_of_user_args - number_of_user_default_args > number_of_event_args:
|
|
1573
|
-
|
|
1574
|
+
msg = (
|
|
1574
1575
|
f"Event {key} only provides {number_of_event_args} arguments, but "
|
|
1575
1576
|
f"{func_name or user_func} requires at least {number_of_user_args - number_of_user_default_args} "
|
|
1576
1577
|
"arguments to be passed to the event handler.\n"
|
|
1577
1578
|
"See https://reflex.dev/docs/events/event-arguments/"
|
|
1578
1579
|
)
|
|
1580
|
+
raise EventFnArgMismatchError(msg)
|
|
1579
1581
|
|
|
1580
1582
|
|
|
1581
1583
|
def call_event_fn(
|
|
@@ -1630,9 +1632,8 @@ def call_event_fn(
|
|
|
1630
1632
|
|
|
1631
1633
|
# Make sure the event spec is valid.
|
|
1632
1634
|
if not isinstance(e, EventSpec):
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
)
|
|
1635
|
+
msg = f"Lambda {fn} returned an invalid event spec: {e}."
|
|
1636
|
+
raise EventHandlerValueError(msg)
|
|
1636
1637
|
|
|
1637
1638
|
# Add the event spec to the chain.
|
|
1638
1639
|
events.append(e)
|
|
@@ -1696,7 +1697,8 @@ def fix_events(
|
|
|
1696
1697
|
if isinstance(e, EventHandler):
|
|
1697
1698
|
e = e()
|
|
1698
1699
|
if not isinstance(e, EventSpec):
|
|
1699
|
-
|
|
1700
|
+
msg = f"Unexpected event type, {type(e)}."
|
|
1701
|
+
raise ValueError(msg)
|
|
1700
1702
|
name = format.format_event_handler(e.handler)
|
|
1701
1703
|
payload = {k._js_expr: v._decode() for k, v in e.args}
|
|
1702
1704
|
|
|
@@ -1749,9 +1751,8 @@ class EventVar(ObjectVar, python_types=(EventSpec, EventHandler)):
|
|
|
1749
1751
|
Raises:
|
|
1750
1752
|
TypeError: EventVar cannot be converted to a boolean.
|
|
1751
1753
|
"""
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
)
|
|
1754
|
+
msg = f"Cannot convert {self._js_expr} of type {type(self).__name__} to bool."
|
|
1755
|
+
raise TypeError(msg)
|
|
1755
1756
|
|
|
1756
1757
|
|
|
1757
1758
|
@dataclasses.dataclass(
|
|
@@ -1798,9 +1799,8 @@ class LiteralEventVar(VarOperationCall, LiteralVar, EventVar):
|
|
|
1798
1799
|
try:
|
|
1799
1800
|
value = call_event_handler(value, no_args)
|
|
1800
1801
|
except EventFnArgMismatchError:
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
) from None
|
|
1802
|
+
msg = f"Event handler {value.fn.__qualname__} used inside of a rx.cond() must not take any arguments."
|
|
1803
|
+
raise EventFnArgMismatchError(msg) from None
|
|
1804
1804
|
|
|
1805
1805
|
return cls(
|
|
1806
1806
|
_js_expr="",
|
|
@@ -1835,9 +1835,8 @@ class EventChainVar(BuilderFunctionVar, python_types=EventChain):
|
|
|
1835
1835
|
Raises:
|
|
1836
1836
|
TypeError: EventChainVar cannot be converted to a boolean.
|
|
1837
1837
|
"""
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
)
|
|
1838
|
+
msg = f"Cannot convert {self._js_expr} of type {type(self).__name__} to bool."
|
|
1839
|
+
raise TypeError(msg)
|
|
1841
1840
|
|
|
1842
1841
|
|
|
1843
1842
|
@dataclasses.dataclass(
|
|
@@ -1906,9 +1905,8 @@ class LiteralEventChainVar(ArgsFunctionOperationBuilder, LiteralVar, EventChainV
|
|
|
1906
1905
|
invocation = value.invocation
|
|
1907
1906
|
|
|
1908
1907
|
if invocation is not None and not isinstance(invocation, FunctionVar):
|
|
1909
|
-
|
|
1910
|
-
|
|
1911
|
-
)
|
|
1908
|
+
msg = f"EventChain invocation must be a FunctionVar, got {invocation!s} of type {invocation._var_type!s}."
|
|
1909
|
+
raise ValueError(msg)
|
|
1912
1910
|
|
|
1913
1911
|
return cls(
|
|
1914
1912
|
_js_expr="",
|
|
@@ -2142,12 +2140,12 @@ class EventNamespace:
|
|
|
2142
2140
|
if not inspect.iscoroutinefunction(
|
|
2143
2141
|
func
|
|
2144
2142
|
) and not inspect.isasyncgenfunction(func):
|
|
2145
|
-
|
|
2146
|
-
|
|
2147
|
-
)
|
|
2143
|
+
msg = "Background task must be async function or generator."
|
|
2144
|
+
raise TypeError(msg)
|
|
2148
2145
|
setattr(func, BACKGROUND_TASK_MARKER, True)
|
|
2149
2146
|
if getattr(func, "__name__", "").startswith("_"):
|
|
2150
|
-
|
|
2147
|
+
msg = "Event handlers cannot be private."
|
|
2148
|
+
raise ValueError(msg)
|
|
2151
2149
|
|
|
2152
2150
|
qualname: str | None = getattr(func, "__qualname__", None)
|
|
2153
2151
|
|
reflex/experimental/__init__.py
CHANGED
|
@@ -6,9 +6,9 @@ from reflex.components.datadisplay.shiki_code_block import code_block as code_bl
|
|
|
6
6
|
from reflex.components.props import PropsBase
|
|
7
7
|
from reflex.components.radix.themes.components.progress import progress as progress
|
|
8
8
|
from reflex.components.sonner.toast import toast as toast
|
|
9
|
+
from reflex.utils.console import warn
|
|
10
|
+
from reflex.utils.misc import run_in_thread
|
|
9
11
|
|
|
10
|
-
from ..utils.console import warn
|
|
11
|
-
from ..utils.misc import run_in_thread
|
|
12
12
|
from . import hooks as hooks
|
|
13
13
|
from .client_state import ClientStateVar as ClientStateVar
|
|
14
14
|
from .layout import layout as layout
|
|
@@ -111,7 +111,8 @@ class ClientStateVar(Var):
|
|
|
111
111
|
var_name = get_unique_variable_name()
|
|
112
112
|
id_name = "id_" + get_unique_variable_name()
|
|
113
113
|
if not isinstance(var_name, str):
|
|
114
|
-
|
|
114
|
+
msg = "var_name must be a string."
|
|
115
|
+
raise ValueError(msg)
|
|
115
116
|
if default is NoValue:
|
|
116
117
|
default_var = Var(_js_expr="")
|
|
117
118
|
elif not isinstance(default, Var):
|
|
@@ -158,7 +159,9 @@ class ClientStateVar(Var):
|
|
|
158
159
|
hooks[f"{_client_state_ref(var_name)} ??= {var_name!s}"] = None
|
|
159
160
|
hooks[f"{_client_state_ref_dict(var_name)} ??= {{}}"] = None
|
|
160
161
|
hooks[f"{_client_state_ref_dict(setter_name)} ??= {{}}"] = None
|
|
161
|
-
hooks[
|
|
162
|
+
hooks[
|
|
163
|
+
f"{_client_state_ref_dict(var_name)}[{id_name}] = {_client_state_ref(var_name)}"
|
|
164
|
+
] = None
|
|
162
165
|
hooks[
|
|
163
166
|
f"{_client_state_ref_dict(setter_name)}[{id_name}] = {setter_name}"
|
|
164
167
|
] = None
|
|
@@ -269,7 +272,8 @@ class ClientStateVar(Var):
|
|
|
269
272
|
ValueError: If the ClientStateVar is not global.
|
|
270
273
|
"""
|
|
271
274
|
if not self._global_ref:
|
|
272
|
-
|
|
275
|
+
msg = "ClientStateVar must be global to retrieve the value."
|
|
276
|
+
raise ValueError(msg)
|
|
273
277
|
return run_script(_client_state_ref(self._getter_name), callback=callback)
|
|
274
278
|
|
|
275
279
|
def push(self, value: Any) -> EventSpec:
|
|
@@ -287,6 +291,7 @@ class ClientStateVar(Var):
|
|
|
287
291
|
ValueError: If the ClientStateVar is not global.
|
|
288
292
|
"""
|
|
289
293
|
if not self._global_ref:
|
|
290
|
-
|
|
294
|
+
msg = "ClientStateVar must be global to push the value."
|
|
295
|
+
raise ValueError(msg)
|
|
291
296
|
value = Var.create(value)
|
|
292
297
|
return run_script(f"{_client_state_ref(self._setter_name)}({value})")
|
reflex/experimental/layout.pyi
CHANGED
|
@@ -237,7 +237,6 @@ class Sidebar(Box, MemoizationLeaf):
|
|
|
237
237
|
Returns:
|
|
238
238
|
The sidebar component.
|
|
239
239
|
"""
|
|
240
|
-
...
|
|
241
240
|
|
|
242
241
|
def add_style(self) -> dict[str, Any] | None: ...
|
|
243
242
|
def add_hooks(self) -> list[Var]: ...
|
|
@@ -309,7 +308,6 @@ class DrawerSidebar(DrawerRoot):
|
|
|
309
308
|
Returns:
|
|
310
309
|
The drawer sidebar component.
|
|
311
310
|
"""
|
|
312
|
-
...
|
|
313
311
|
|
|
314
312
|
sidebar_trigger_style = {
|
|
315
313
|
"position": "fixed",
|
|
@@ -362,7 +360,6 @@ class SidebarTrigger(Fragment):
|
|
|
362
360
|
Returns:
|
|
363
361
|
The sidebar trigger component.
|
|
364
362
|
"""
|
|
365
|
-
...
|
|
366
363
|
|
|
367
364
|
class Layout(Box):
|
|
368
365
|
@overload
|
|
@@ -587,7 +584,6 @@ class Layout(Box):
|
|
|
587
584
|
Returns:
|
|
588
585
|
The layout component.
|
|
589
586
|
"""
|
|
590
|
-
...
|
|
591
587
|
|
|
592
588
|
class LayoutNamespace(ComponentNamespace):
|
|
593
589
|
drawer_sidebar = staticmethod(DrawerSidebar.create)
|
|
@@ -814,6 +810,5 @@ class LayoutNamespace(ComponentNamespace):
|
|
|
814
810
|
Returns:
|
|
815
811
|
The layout component.
|
|
816
812
|
"""
|
|
817
|
-
...
|
|
818
813
|
|
|
819
814
|
layout = LayoutNamespace()
|
reflex/istate/manager.py
CHANGED
|
@@ -66,9 +66,8 @@ class StateManager(ABC):
|
|
|
66
66
|
lock_expiration=config.redis_lock_expiration,
|
|
67
67
|
lock_warning_threshold=config.redis_lock_warning_threshold,
|
|
68
68
|
)
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
)
|
|
69
|
+
msg = f"Expected one of: DISK, MEMORY, REDIS, got {config.state_manager_mode}"
|
|
70
|
+
raise InvalidStateManagerModeError(msg)
|
|
72
71
|
|
|
73
72
|
@abstractmethod
|
|
74
73
|
async def get_state(self, token: str) -> BaseState:
|
|
@@ -80,7 +79,6 @@ class StateManager(ABC):
|
|
|
80
79
|
Returns:
|
|
81
80
|
The state for the token.
|
|
82
81
|
"""
|
|
83
|
-
pass
|
|
84
82
|
|
|
85
83
|
@abstractmethod
|
|
86
84
|
async def set_state(self, token: str, state: BaseState):
|
|
@@ -90,7 +88,6 @@ class StateManager(ABC):
|
|
|
90
88
|
token: The token to set the state for.
|
|
91
89
|
state: The state to set.
|
|
92
90
|
"""
|
|
93
|
-
pass
|
|
94
91
|
|
|
95
92
|
@abstractmethod
|
|
96
93
|
@contextlib.asynccontextmanager
|
|
@@ -145,7 +142,6 @@ class StateManagerMemory(StateManager):
|
|
|
145
142
|
token: The token to set the state for.
|
|
146
143
|
state: The state to set.
|
|
147
144
|
"""
|
|
148
|
-
pass
|
|
149
145
|
|
|
150
146
|
@override
|
|
151
147
|
@contextlib.asynccontextmanager
|
|
@@ -269,6 +265,7 @@ class StateManagerDisk(StateManager):
|
|
|
269
265
|
return BaseState._deserialize(fp=file)
|
|
270
266
|
except Exception:
|
|
271
267
|
pass
|
|
268
|
+
return None
|
|
272
269
|
|
|
273
270
|
async def populate_substates(
|
|
274
271
|
self, client_token: str, state: BaseState, root_state: BaseState
|
|
@@ -449,9 +446,8 @@ class StateManagerRedis(StateManager):
|
|
|
449
446
|
InvalidLockWarningThresholdError: If the lock warning threshold is invalid.
|
|
450
447
|
"""
|
|
451
448
|
if self.lock_warning_threshold >= (lock_expiration := self.lock_expiration):
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
)
|
|
449
|
+
msg = f"The lock warning threshold({self.lock_warning_threshold}) must be less than the lock expiration time({lock_expiration})."
|
|
450
|
+
raise InvalidLockWarningThresholdError(msg)
|
|
455
451
|
|
|
456
452
|
def _get_required_state_classes(
|
|
457
453
|
self,
|
|
@@ -557,9 +553,8 @@ class StateManagerRedis(StateManager):
|
|
|
557
553
|
# Get the State class associated with the given path.
|
|
558
554
|
state_cls = self.state.get_class_substate(state_path)
|
|
559
555
|
else:
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
)
|
|
556
|
+
msg = f"StateManagerRedis requires token to be specified in the form of {{token}}_{{state_full_name}}, but got {token}"
|
|
557
|
+
raise RuntimeError(msg)
|
|
563
558
|
|
|
564
559
|
# Determine which states we already have.
|
|
565
560
|
flat_state_tree: dict[str, BaseState] = (
|
|
@@ -601,11 +596,12 @@ class StateManagerRedis(StateManager):
|
|
|
601
596
|
)
|
|
602
597
|
parent_state = flat_state_tree.get(parent_state_name)
|
|
603
598
|
if parent_state is None:
|
|
604
|
-
|
|
599
|
+
msg = (
|
|
605
600
|
f"Parent state for {state.get_full_name()} was not found "
|
|
606
601
|
"in the state tree, but should have already been fetched. "
|
|
607
|
-
"This is a bug"
|
|
602
|
+
"This is a bug"
|
|
608
603
|
)
|
|
604
|
+
raise RuntimeError(msg)
|
|
609
605
|
parent_state.substates[state_name] = state
|
|
610
606
|
state.parent_state = parent_state
|
|
611
607
|
|
|
@@ -638,12 +634,13 @@ class StateManagerRedis(StateManager):
|
|
|
638
634
|
lock_id is not None
|
|
639
635
|
and await self.redis.get(self._lock_key(token)) != lock_id
|
|
640
636
|
):
|
|
641
|
-
|
|
637
|
+
msg = (
|
|
642
638
|
f"Lock expired for token {token} while processing. Consider increasing "
|
|
643
639
|
f"`app.state_manager.lock_expiration` (currently {self.lock_expiration}) "
|
|
644
640
|
"or use `@rx.event(background=True)` decorator for long-running tasks."
|
|
645
641
|
)
|
|
646
|
-
|
|
642
|
+
raise LockExpiredError(msg)
|
|
643
|
+
if lock_id is not None:
|
|
647
644
|
time_taken = self.lock_expiration / 1000 - (
|
|
648
645
|
await self.redis.ttl(self._lock_key(token))
|
|
649
646
|
)
|
|
@@ -657,9 +654,8 @@ class StateManagerRedis(StateManager):
|
|
|
657
654
|
client_token, substate_name = _split_substate_key(token)
|
|
658
655
|
# If the substate name on the token doesn't match the instance name, it cannot have a parent.
|
|
659
656
|
if state.parent_state is not None and state.get_full_name() != substate_name:
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
)
|
|
657
|
+
msg = f"Cannot `set_state` with mismatching token {token} and substate {state.get_full_name()}."
|
|
658
|
+
raise RuntimeError(msg)
|
|
663
659
|
|
|
664
660
|
# Recursively set_state on all known substates.
|
|
665
661
|
tasks = [
|