reflex 0.6.0a1__py3-none-any.whl → 0.6.0a3__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/custom_components/pyproject.toml.jinja2 +2 -2
- reflex/.templates/jinja/web/pages/_app.js.jinja2 +1 -1
- reflex/.templates/jinja/web/pages/utils.js.jinja2 +2 -2
- reflex/__init__.py +8 -2
- reflex/__init__.pyi +2 -1
- reflex/app.py +10 -4
- reflex/base.py +1 -1
- reflex/compiler/compiler.py +2 -2
- reflex/compiler/utils.py +3 -3
- reflex/components/base/app_wrap.py +2 -2
- reflex/components/base/app_wrap.pyi +17 -27
- reflex/components/base/bare.py +4 -5
- reflex/components/base/body.pyi +17 -27
- reflex/components/base/document.pyi +81 -131
- reflex/components/base/error_boundary.py +6 -7
- reflex/components/base/error_boundary.pyi +20 -33
- reflex/components/base/fragment.pyi +17 -27
- reflex/components/base/head.pyi +33 -53
- reflex/components/base/link.py +1 -1
- reflex/components/base/link.pyi +33 -54
- reflex/components/base/meta.pyi +65 -105
- reflex/components/base/script.py +1 -2
- reflex/components/base/script.pyi +21 -38
- reflex/components/component.py +45 -47
- reflex/components/core/banner.py +23 -27
- reflex/components/core/banner.pyi +134 -171
- reflex/components/core/breakpoints.py +3 -1
- reflex/components/core/client_side_routing.py +2 -3
- reflex/components/core/client_side_routing.pyi +33 -54
- reflex/components/core/clipboard.py +2 -1
- reflex/components/core/clipboard.pyi +20 -33
- reflex/components/core/cond.py +5 -5
- reflex/components/core/debounce.py +5 -5
- reflex/components/core/debounce.pyi +20 -33
- reflex/components/core/foreach.py +3 -4
- reflex/components/core/html.py +1 -1
- reflex/components/core/html.pyi +35 -46
- reflex/components/core/match.py +17 -17
- reflex/components/core/upload.py +17 -23
- reflex/components/core/upload.pyi +78 -124
- reflex/components/datadisplay/code.py +9 -10
- reflex/components/datadisplay/code.pyi +302 -412
- reflex/components/datadisplay/dataeditor.py +8 -10
- reflex/components/datadisplay/dataeditor.pyi +40 -53
- reflex/components/el/element.pyi +17 -27
- reflex/components/el/elements/base.py +1 -1
- reflex/components/el/elements/base.pyi +34 -45
- reflex/components/el/elements/forms.py +16 -16
- reflex/components/el/elements/forms.pyi +554 -707
- reflex/components/el/elements/inline.py +1 -1
- reflex/components/el/elements/inline.pyi +937 -1218
- reflex/components/el/elements/media.py +1 -1
- reflex/components/el/elements/media.pyi +786 -997
- reflex/components/el/elements/metadata.py +3 -6
- reflex/components/el/elements/metadata.pyi +181 -242
- reflex/components/el/elements/other.py +1 -1
- reflex/components/el/elements/other.pyi +235 -306
- reflex/components/el/elements/scripts.py +1 -1
- reflex/components/el/elements/scripts.pyi +109 -140
- reflex/components/el/elements/sectioning.py +0 -2
- reflex/components/el/elements/sectioning.pyi +496 -647
- reflex/components/el/elements/tables.py +1 -1
- reflex/components/el/elements/tables.pyi +351 -452
- reflex/components/el/elements/typography.py +1 -1
- reflex/components/el/elements/typography.pyi +506 -657
- reflex/components/gridjs/datatable.py +6 -9
- reflex/components/gridjs/datatable.pyi +35 -56
- reflex/components/lucide/icon.py +1 -1
- reflex/components/lucide/icon.pyi +33 -54
- reflex/components/markdown/markdown.py +26 -31
- reflex/components/markdown/markdown.pyi +27 -37
- reflex/components/moment/moment.py +13 -12
- reflex/components/moment/moment.pyi +23 -35
- reflex/components/next/base.pyi +17 -27
- reflex/components/next/image.py +1 -1
- reflex/components/next/image.pyi +22 -37
- reflex/components/next/link.py +1 -1
- reflex/components/next/link.pyi +17 -28
- reflex/components/next/video.py +1 -1
- reflex/components/next/video.pyi +17 -28
- reflex/components/plotly/plotly.py +12 -13
- reflex/components/plotly/plotly.pyi +39 -54
- reflex/components/props.py +1 -1
- reflex/components/radix/__init__.pyi +1 -0
- reflex/components/radix/primitives/__init__.pyi +1 -0
- reflex/components/radix/primitives/accordion.py +4 -4
- reflex/components/radix/primitives/accordion.pyi +424 -495
- reflex/components/radix/primitives/base.py +1 -1
- reflex/components/radix/primitives/base.pyi +33 -54
- reflex/components/radix/primitives/drawer.py +1 -1
- reflex/components/radix/primitives/drawer.pyi +172 -273
- reflex/components/radix/primitives/form.py +1 -1
- reflex/components/radix/primitives/form.pyi +257 -364
- reflex/components/radix/primitives/progress.py +1 -1
- reflex/components/radix/primitives/progress.pyi +231 -282
- reflex/components/radix/primitives/slider.py +1 -1
- reflex/components/radix/primitives/slider.pyi +87 -138
- reflex/components/radix/themes/base.py +3 -24
- reflex/components/radix/themes/base.pyi +178 -250
- reflex/components/radix/themes/color_mode.py +5 -5
- reflex/components/radix/themes/color_mode.pyi +187 -220
- reflex/components/radix/themes/components/alert_dialog.py +1 -1
- reflex/components/radix/themes/components/alert_dialog.pyi +136 -207
- reflex/components/radix/themes/components/aspect_ratio.py +1 -1
- reflex/components/radix/themes/components/aspect_ratio.pyi +17 -28
- reflex/components/radix/themes/components/avatar.py +1 -1
- reflex/components/radix/themes/components/avatar.pyi +70 -81
- reflex/components/radix/themes/components/badge.py +1 -1
- reflex/components/radix/themes/components/badge.pyi +88 -99
- reflex/components/radix/themes/components/button.py +1 -1
- reflex/components/radix/themes/components/button.pyi +98 -109
- reflex/components/radix/themes/components/callout.py +1 -1
- reflex/components/radix/themes/components/callout.pyi +322 -373
- reflex/components/radix/themes/components/card.py +1 -1
- reflex/components/radix/themes/components/card.pyi +38 -49
- reflex/components/radix/themes/components/checkbox.py +1 -2
- reflex/components/radix/themes/components/checkbox.pyi +208 -245
- reflex/components/radix/themes/components/checkbox_cards.py +1 -1
- reflex/components/radix/themes/components/checkbox_cards.pyi +94 -115
- reflex/components/radix/themes/components/checkbox_group.py +1 -1
- reflex/components/radix/themes/components/checkbox_group.pyi +86 -107
- reflex/components/radix/themes/components/context_menu.py +1 -1
- reflex/components/radix/themes/components/context_menu.pyi +238 -319
- reflex/components/radix/themes/components/data_list.py +1 -1
- reflex/components/radix/themes/components/data_list.pyi +130 -171
- reflex/components/radix/themes/components/dialog.py +1 -1
- reflex/components/radix/themes/components/dialog.pyi +139 -210
- reflex/components/radix/themes/components/dropdown_menu.py +1 -1
- reflex/components/radix/themes/components/dropdown_menu.pyi +249 -332
- reflex/components/radix/themes/components/hover_card.py +1 -1
- reflex/components/radix/themes/components/hover_card.pyi +90 -131
- reflex/components/radix/themes/components/icon_button.py +2 -3
- reflex/components/radix/themes/components/icon_button.pyi +98 -109
- reflex/components/radix/themes/components/inset.py +1 -1
- reflex/components/radix/themes/components/inset.pyi +47 -58
- reflex/components/radix/themes/components/popover.py +1 -1
- reflex/components/radix/themes/components/popover.pyi +95 -136
- reflex/components/radix/themes/components/progress.py +1 -1
- reflex/components/radix/themes/components/progress.pyi +71 -82
- reflex/components/radix/themes/components/radio.py +1 -1
- reflex/components/radix/themes/components/radio.pyi +69 -80
- reflex/components/radix/themes/components/radio_cards.py +1 -1
- reflex/components/radix/themes/components/radio_cards.pyi +98 -119
- reflex/components/radix/themes/components/radio_group.py +8 -11
- reflex/components/radix/themes/components/radio_group.pyi +228 -271
- reflex/components/radix/themes/components/scroll_area.py +1 -1
- reflex/components/radix/themes/components/scroll_area.pyi +21 -32
- reflex/components/radix/themes/components/segmented_control.py +1 -1
- reflex/components/radix/themes/components/segmented_control.pyi +90 -113
- reflex/components/radix/themes/components/select.py +2 -3
- reflex/components/radix/themes/components/select.pyi +374 -471
- reflex/components/radix/themes/components/separator.py +1 -2
- reflex/components/radix/themes/components/separator.pyi +69 -80
- reflex/components/radix/themes/components/skeleton.py +1 -1
- reflex/components/radix/themes/components/skeleton.pyi +23 -34
- reflex/components/radix/themes/components/slider.py +2 -3
- reflex/components/radix/themes/components/slider.pyi +75 -88
- reflex/components/radix/themes/components/spinner.py +1 -1
- reflex/components/radix/themes/components/spinner.pyi +19 -30
- reflex/components/radix/themes/components/switch.py +1 -1
- reflex/components/radix/themes/components/switch.pyi +71 -84
- reflex/components/radix/themes/components/table.py +1 -1
- reflex/components/radix/themes/components/table.pyi +261 -332
- reflex/components/radix/themes/components/tabs.py +1 -1
- reflex/components/radix/themes/components/tabs.pyi +139 -194
- reflex/components/radix/themes/components/text_area.py +1 -1
- reflex/components/radix/themes/components/text_area.pyi +96 -111
- reflex/components/radix/themes/components/text_field.py +1 -1
- reflex/components/radix/themes/components/text_field.pyi +247 -286
- reflex/components/radix/themes/components/tooltip.py +1 -1
- reflex/components/radix/themes/components/tooltip.pyi +26 -37
- reflex/components/radix/themes/layout/__init__.pyi +1 -0
- reflex/components/radix/themes/layout/base.py +1 -1
- reflex/components/radix/themes/layout/base.pyi +56 -67
- reflex/components/radix/themes/layout/box.pyi +34 -45
- reflex/components/radix/themes/layout/center.pyi +56 -67
- reflex/components/radix/themes/layout/container.py +1 -2
- reflex/components/radix/themes/layout/container.pyi +36 -47
- reflex/components/radix/themes/layout/flex.py +1 -1
- reflex/components/radix/themes/layout/flex.pyi +56 -67
- reflex/components/radix/themes/layout/grid.py +1 -1
- reflex/components/radix/themes/layout/grid.pyi +64 -75
- reflex/components/radix/themes/layout/list.py +5 -6
- reflex/components/radix/themes/layout/list.pyi +193 -244
- reflex/components/radix/themes/layout/section.py +1 -2
- reflex/components/radix/themes/layout/section.pyi +36 -47
- reflex/components/radix/themes/layout/spacer.pyi +56 -67
- reflex/components/radix/themes/layout/stack.py +1 -1
- reflex/components/radix/themes/layout/stack.pyi +128 -159
- reflex/components/radix/themes/typography/blockquote.py +1 -1
- reflex/components/radix/themes/typography/blockquote.pyi +89 -100
- reflex/components/radix/themes/typography/code.py +1 -1
- reflex/components/radix/themes/typography/code.pyi +90 -101
- reflex/components/radix/themes/typography/heading.py +1 -1
- reflex/components/radix/themes/typography/heading.pyi +96 -107
- reflex/components/radix/themes/typography/link.py +1 -1
- reflex/components/radix/themes/typography/link.pyi +102 -113
- reflex/components/radix/themes/typography/text.py +1 -1
- reflex/components/radix/themes/typography/text.pyi +501 -572
- reflex/components/react_player/audio.pyi +33 -60
- reflex/components/react_player/react_player.py +1 -1
- reflex/components/react_player/react_player.pyi +33 -60
- reflex/components/react_player/video.pyi +33 -60
- reflex/components/recharts/cartesian.py +2 -3
- reflex/components/recharts/cartesian.pyi +678 -861
- reflex/components/recharts/charts.py +4 -5
- reflex/components/recharts/charts.pyi +252 -357
- reflex/components/recharts/general.py +1 -2
- reflex/components/recharts/general.pyi +180 -231
- reflex/components/recharts/polar.py +4 -5
- reflex/components/recharts/polar.pyi +144 -181
- reflex/components/recharts/recharts.pyi +33 -53
- reflex/components/sonner/toast.py +16 -17
- reflex/components/sonner/toast.pyi +36 -47
- reflex/components/suneditor/editor.py +2 -3
- reflex/components/suneditor/editor.pyi +55 -78
- reflex/components/tags/cond_tag.py +6 -4
- reflex/components/tags/iter_tag.py +28 -16
- reflex/components/tags/match_tag.py +6 -4
- reflex/components/tags/tag.py +40 -23
- reflex/custom_components/custom_components.py +3 -1
- reflex/event.py +115 -67
- reflex/experimental/client_state.py +18 -18
- reflex/experimental/hooks.py +16 -16
- reflex/experimental/layout.py +5 -5
- reflex/experimental/layout.pyi +136 -187
- reflex/middleware/hydrate_middleware.py +2 -0
- reflex/middleware/middleware.py +3 -3
- reflex/state.py +149 -82
- reflex/style.py +21 -22
- reflex/utils/exceptions.py +20 -0
- reflex/utils/format.py +54 -34
- reflex/utils/imports.py +16 -73
- reflex/utils/prerequisites.py +15 -8
- reflex/utils/pyi_generator.py +13 -8
- reflex/utils/serializers.py +12 -22
- reflex/utils/telemetry.py +3 -2
- reflex/utils/types.py +11 -6
- reflex/{ivars → vars}/__init__.py +6 -2
- reflex/{ivars → vars}/base.py +599 -216
- reflex/{ivars → vars}/function.py +15 -19
- reflex/{ivars → vars}/number.py +41 -20
- reflex/{ivars → vars}/object.py +28 -30
- reflex/{ivars → vars}/sequence.py +53 -42
- {reflex-0.6.0a1.dist-info → reflex-0.6.0a3.dist-info}/METADATA +4 -6
- reflex-0.6.0a3.dist-info/RECORD +382 -0
- reflex/.templates/web/components/reflex/chakra_color_mode_provider.js +0 -36
- reflex/vars.py +0 -501
- reflex-0.6.0a1.dist-info/RECORD +0 -384
- {reflex-0.6.0a1.dist-info → reflex-0.6.0a3.dist-info}/LICENSE +0 -0
- {reflex-0.6.0a1.dist-info → reflex-0.6.0a3.dist-info}/WHEEL +0 -0
- {reflex-0.6.0a1.dist-info → reflex-0.6.0a3.dist-info}/entry_points.txt +0 -0
reflex/utils/format.py
CHANGED
|
@@ -10,7 +10,7 @@ from typing import TYPE_CHECKING, Any, Callable, List, Optional, Union
|
|
|
10
10
|
|
|
11
11
|
from reflex import constants
|
|
12
12
|
from reflex.utils import exceptions, types
|
|
13
|
-
from reflex.
|
|
13
|
+
from reflex.utils.console import deprecate
|
|
14
14
|
|
|
15
15
|
if TYPE_CHECKING:
|
|
16
16
|
from reflex.components.component import ComponentStyle
|
|
@@ -298,9 +298,9 @@ def format_route(route: str, format_case=True) -> str:
|
|
|
298
298
|
|
|
299
299
|
|
|
300
300
|
def format_match(
|
|
301
|
-
cond: str |
|
|
302
|
-
match_cases: List[List[
|
|
303
|
-
default:
|
|
301
|
+
cond: str | Var,
|
|
302
|
+
match_cases: List[List[Var]],
|
|
303
|
+
default: Var,
|
|
304
304
|
) -> str:
|
|
305
305
|
"""Format a match expression whose return type is a Var.
|
|
306
306
|
|
|
@@ -332,7 +332,7 @@ def format_match(
|
|
|
332
332
|
|
|
333
333
|
|
|
334
334
|
def format_prop(
|
|
335
|
-
prop: Union[
|
|
335
|
+
prop: Union[Var, EventChain, ComponentStyle, str],
|
|
336
336
|
) -> Union[int, float, str]:
|
|
337
337
|
"""Format a prop.
|
|
338
338
|
|
|
@@ -348,12 +348,12 @@ def format_prop(
|
|
|
348
348
|
"""
|
|
349
349
|
# import here to avoid circular import.
|
|
350
350
|
from reflex.event import EventChain
|
|
351
|
-
from reflex.ivars import ImmutableVar
|
|
352
351
|
from reflex.utils import serializers
|
|
352
|
+
from reflex.vars import Var
|
|
353
353
|
|
|
354
354
|
try:
|
|
355
355
|
# Handle var props.
|
|
356
|
-
if isinstance(prop,
|
|
356
|
+
if isinstance(prop, Var):
|
|
357
357
|
return str(prop)
|
|
358
358
|
|
|
359
359
|
# Handle event props.
|
|
@@ -406,26 +406,15 @@ def format_props(*single_props, **key_value_props) -> list[str]:
|
|
|
406
406
|
The formatted props list.
|
|
407
407
|
"""
|
|
408
408
|
# Format all the props.
|
|
409
|
-
from reflex.
|
|
409
|
+
from reflex.vars.base import LiteralVar, Var
|
|
410
410
|
|
|
411
411
|
return [
|
|
412
412
|
(
|
|
413
|
-
f"{name}={format_prop(prop)}"
|
|
414
|
-
if isinstance(prop, ImmutableVar) and not isinstance(prop, ImmutableVar)
|
|
415
|
-
else (
|
|
416
|
-
f"{name}={{{format_prop(prop if isinstance(prop, ImmutableVar) else LiteralVar.create(prop))}}}"
|
|
417
|
-
)
|
|
413
|
+
f"{name}={{{format_prop(prop if isinstance(prop, Var) else LiteralVar.create(prop))}}}"
|
|
418
414
|
)
|
|
419
415
|
for name, prop in sorted(key_value_props.items())
|
|
420
416
|
if prop is not None
|
|
421
|
-
] + [
|
|
422
|
-
(
|
|
423
|
-
str(prop)
|
|
424
|
-
if isinstance(prop, ImmutableVar) and not isinstance(prop, ImmutableVar)
|
|
425
|
-
else f"{str(LiteralVar.create(prop))}"
|
|
426
|
-
)
|
|
427
|
-
for prop in single_props
|
|
428
|
-
]
|
|
417
|
+
] + [(f"{str(LiteralVar.create(prop))}") for prop in single_props]
|
|
429
418
|
|
|
430
419
|
|
|
431
420
|
def get_event_handler_parts(handler: EventHandler) -> tuple[str, str]:
|
|
@@ -486,10 +475,10 @@ def format_event(event_spec: EventSpec) -> str:
|
|
|
486
475
|
[
|
|
487
476
|
":".join(
|
|
488
477
|
(
|
|
489
|
-
name.
|
|
478
|
+
name._js_expr,
|
|
490
479
|
(
|
|
491
480
|
wrap(
|
|
492
|
-
json.dumps(val.
|
|
481
|
+
json.dumps(val._js_expr).strip('"').replace("`", "\\`"),
|
|
493
482
|
"`",
|
|
494
483
|
)
|
|
495
484
|
if val._var_is_string
|
|
@@ -511,7 +500,38 @@ def format_event(event_spec: EventSpec) -> str:
|
|
|
511
500
|
|
|
512
501
|
|
|
513
502
|
if TYPE_CHECKING:
|
|
514
|
-
from reflex.
|
|
503
|
+
from reflex.vars import Var
|
|
504
|
+
|
|
505
|
+
|
|
506
|
+
def format_event_chain(
|
|
507
|
+
event_chain: EventChain | Var[EventChain],
|
|
508
|
+
event_arg: Var | None = None,
|
|
509
|
+
) -> str:
|
|
510
|
+
"""DEPRECATED: format an event chain as a javascript invocation.
|
|
511
|
+
|
|
512
|
+
Use str(rx.Var.create(event_chain)) instead.
|
|
513
|
+
|
|
514
|
+
Args:
|
|
515
|
+
event_chain: The event chain to format.
|
|
516
|
+
event_arg: this argument is ignored.
|
|
517
|
+
|
|
518
|
+
Returns:
|
|
519
|
+
Compiled javascript code to queue the given event chain on the frontend.
|
|
520
|
+
"""
|
|
521
|
+
deprecate(
|
|
522
|
+
feature_name="format_event_chain",
|
|
523
|
+
reason="Use str(rx.Var.create(event_chain)) instead",
|
|
524
|
+
deprecation_version="0.6.0",
|
|
525
|
+
removal_version="0.7.0",
|
|
526
|
+
)
|
|
527
|
+
|
|
528
|
+
from reflex.vars import Var
|
|
529
|
+
from reflex.vars.function import ArgsFunctionOperation
|
|
530
|
+
|
|
531
|
+
result = Var.create(event_chain)
|
|
532
|
+
if isinstance(result, ArgsFunctionOperation):
|
|
533
|
+
result = result._return_expr
|
|
534
|
+
return str(result)
|
|
515
535
|
|
|
516
536
|
|
|
517
537
|
def format_queue_events(
|
|
@@ -523,7 +543,7 @@ def format_queue_events(
|
|
|
523
543
|
| None
|
|
524
544
|
) = None,
|
|
525
545
|
args_spec: Optional[ArgsSpec] = None,
|
|
526
|
-
) ->
|
|
546
|
+
) -> Var[EventChain]:
|
|
527
547
|
"""Format a list of event handler / event spec as a javascript callback.
|
|
528
548
|
|
|
529
549
|
The resulting code can be passed to interfaces that expect a callback
|
|
@@ -549,10 +569,10 @@ def format_queue_events(
|
|
|
549
569
|
call_event_fn,
|
|
550
570
|
call_event_handler,
|
|
551
571
|
)
|
|
552
|
-
from reflex.
|
|
572
|
+
from reflex.vars import FunctionVar, Var
|
|
553
573
|
|
|
554
574
|
if not events:
|
|
555
|
-
return
|
|
575
|
+
return Var("(() => null)").to(FunctionVar, EventChain) # type: ignore
|
|
556
576
|
|
|
557
577
|
# If no spec is provided, the function will take no arguments.
|
|
558
578
|
def _default_args_spec():
|
|
@@ -577,7 +597,7 @@ def format_queue_events(
|
|
|
577
597
|
specs = [call_event_handler(spec, args_spec or _default_args_spec)]
|
|
578
598
|
elif isinstance(spec, type(lambda: None)):
|
|
579
599
|
specs = call_event_fn(spec, args_spec or _default_args_spec) # type: ignore
|
|
580
|
-
if isinstance(specs,
|
|
600
|
+
if isinstance(specs, Var):
|
|
581
601
|
raise ValueError(
|
|
582
602
|
f"Invalid event spec: {specs}. Expected a list of EventSpecs."
|
|
583
603
|
)
|
|
@@ -585,7 +605,7 @@ def format_queue_events(
|
|
|
585
605
|
|
|
586
606
|
# Return the final code snippet, expecting queueEvents, processEvent, and socket to be in scope.
|
|
587
607
|
# Typically this snippet will _only_ run from within an rx.call_script eval context.
|
|
588
|
-
return
|
|
608
|
+
return Var(
|
|
589
609
|
f"{arg_def} => {{queueEvents([{','.join(payloads)}], {constants.CompileVars.SOCKET}); "
|
|
590
610
|
f"processEvent({constants.CompileVars.SOCKET})}}",
|
|
591
611
|
).to(FunctionVar, EventChain) # type: ignore
|
|
@@ -727,7 +747,7 @@ def collect_form_dict_names(form_dict: dict[str, Any]) -> dict[str, Any]:
|
|
|
727
747
|
return collapsed
|
|
728
748
|
|
|
729
749
|
|
|
730
|
-
def format_array_ref(refs: str, idx:
|
|
750
|
+
def format_array_ref(refs: str, idx: Var | None) -> str:
|
|
731
751
|
"""Format a ref accessed by array.
|
|
732
752
|
|
|
733
753
|
Args:
|
|
@@ -756,7 +776,7 @@ def format_data_editor_column(col: str | dict):
|
|
|
756
776
|
Returns:
|
|
757
777
|
The formatted column.
|
|
758
778
|
"""
|
|
759
|
-
from reflex.
|
|
779
|
+
from reflex.vars import Var
|
|
760
780
|
|
|
761
781
|
if isinstance(col, str):
|
|
762
782
|
return {"title": col, "id": col.lower(), "type": "str"}
|
|
@@ -770,7 +790,7 @@ def format_data_editor_column(col: str | dict):
|
|
|
770
790
|
col["overlayIcon"] = None
|
|
771
791
|
return col
|
|
772
792
|
|
|
773
|
-
if isinstance(col,
|
|
793
|
+
if isinstance(col, Var):
|
|
774
794
|
return col
|
|
775
795
|
|
|
776
796
|
raise ValueError(
|
|
@@ -787,9 +807,9 @@ def format_data_editor_cell(cell: Any):
|
|
|
787
807
|
Returns:
|
|
788
808
|
The formatted cell.
|
|
789
809
|
"""
|
|
790
|
-
from reflex.
|
|
810
|
+
from reflex.vars.base import Var
|
|
791
811
|
|
|
792
812
|
return {
|
|
793
|
-
"kind":
|
|
813
|
+
"kind": Var(_js_expr="GridCellKind.Text"),
|
|
794
814
|
"data": cell,
|
|
795
815
|
}
|
reflex/utils/imports.py
CHANGED
|
@@ -2,10 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
|
+
import dataclasses
|
|
5
6
|
from collections import defaultdict
|
|
6
|
-
from typing import Dict, List, Optional, Tuple, Union
|
|
7
|
-
|
|
8
|
-
from reflex.base import Base
|
|
7
|
+
from typing import DefaultDict, Dict, List, Optional, Tuple, Union
|
|
9
8
|
|
|
10
9
|
|
|
11
10
|
def merge_imports(
|
|
@@ -19,12 +18,22 @@ def merge_imports(
|
|
|
19
18
|
Returns:
|
|
20
19
|
The merged import dicts.
|
|
21
20
|
"""
|
|
22
|
-
all_imports = defaultdict(list)
|
|
21
|
+
all_imports: DefaultDict[str, List[ImportVar]] = defaultdict(list)
|
|
23
22
|
for import_dict in imports:
|
|
24
23
|
for lib, fields in (
|
|
25
24
|
import_dict if isinstance(import_dict, tuple) else import_dict.items()
|
|
26
25
|
):
|
|
27
|
-
|
|
26
|
+
if isinstance(fields, (list, tuple, set)):
|
|
27
|
+
all_imports[lib].extend(
|
|
28
|
+
(
|
|
29
|
+
ImportVar(field) if isinstance(field, str) else field
|
|
30
|
+
for field in fields
|
|
31
|
+
)
|
|
32
|
+
)
|
|
33
|
+
else:
|
|
34
|
+
all_imports[lib].append(
|
|
35
|
+
ImportVar(fields) if isinstance(fields, str) else fields
|
|
36
|
+
)
|
|
28
37
|
return all_imports
|
|
29
38
|
|
|
30
39
|
|
|
@@ -75,7 +84,8 @@ def collapse_imports(
|
|
|
75
84
|
}
|
|
76
85
|
|
|
77
86
|
|
|
78
|
-
|
|
87
|
+
@dataclasses.dataclass(order=True, frozen=True)
|
|
88
|
+
class ImportVar:
|
|
79
89
|
"""An import var."""
|
|
80
90
|
|
|
81
91
|
# The name of the import tag.
|
|
@@ -111,73 +121,6 @@ class ImportVar(Base):
|
|
|
111
121
|
else:
|
|
112
122
|
return self.tag or ""
|
|
113
123
|
|
|
114
|
-
def __lt__(self, other: ImportVar) -> bool:
|
|
115
|
-
"""Compare two ImportVar objects.
|
|
116
|
-
|
|
117
|
-
Args:
|
|
118
|
-
other: The other ImportVar object to compare.
|
|
119
|
-
|
|
120
|
-
Returns:
|
|
121
|
-
Whether this ImportVar object is less than the other.
|
|
122
|
-
"""
|
|
123
|
-
return (
|
|
124
|
-
self.tag,
|
|
125
|
-
self.is_default,
|
|
126
|
-
self.alias,
|
|
127
|
-
self.install,
|
|
128
|
-
self.render,
|
|
129
|
-
self.transpile,
|
|
130
|
-
) < (
|
|
131
|
-
other.tag,
|
|
132
|
-
other.is_default,
|
|
133
|
-
other.alias,
|
|
134
|
-
other.install,
|
|
135
|
-
other.render,
|
|
136
|
-
other.transpile,
|
|
137
|
-
)
|
|
138
|
-
|
|
139
|
-
def __eq__(self, other: ImportVar) -> bool:
|
|
140
|
-
"""Check if two ImportVar objects are equal.
|
|
141
|
-
|
|
142
|
-
Args:
|
|
143
|
-
other: The other ImportVar object to compare.
|
|
144
|
-
|
|
145
|
-
Returns:
|
|
146
|
-
Whether the two ImportVar objects are equal.
|
|
147
|
-
"""
|
|
148
|
-
return (
|
|
149
|
-
self.tag,
|
|
150
|
-
self.is_default,
|
|
151
|
-
self.alias,
|
|
152
|
-
self.install,
|
|
153
|
-
self.render,
|
|
154
|
-
self.transpile,
|
|
155
|
-
) == (
|
|
156
|
-
other.tag,
|
|
157
|
-
other.is_default,
|
|
158
|
-
other.alias,
|
|
159
|
-
other.install,
|
|
160
|
-
other.render,
|
|
161
|
-
other.transpile,
|
|
162
|
-
)
|
|
163
|
-
|
|
164
|
-
def __hash__(self) -> int:
|
|
165
|
-
"""Hash the ImportVar object.
|
|
166
|
-
|
|
167
|
-
Returns:
|
|
168
|
-
The hash of the ImportVar object.
|
|
169
|
-
"""
|
|
170
|
-
return hash(
|
|
171
|
-
(
|
|
172
|
-
self.tag,
|
|
173
|
-
self.is_default,
|
|
174
|
-
self.alias,
|
|
175
|
-
self.install,
|
|
176
|
-
self.render,
|
|
177
|
-
self.transpile,
|
|
178
|
-
)
|
|
179
|
-
)
|
|
180
|
-
|
|
181
124
|
|
|
182
125
|
ImportTypes = Union[str, ImportVar, List[Union[str, ImportVar]], List[ImportVar]]
|
|
183
126
|
ImportDict = Dict[str, ImportTypes]
|
reflex/utils/prerequisites.py
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
|
+
import dataclasses
|
|
5
6
|
import functools
|
|
6
7
|
import glob
|
|
7
8
|
import importlib
|
|
@@ -32,7 +33,6 @@ from redis import exceptions
|
|
|
32
33
|
from redis.asyncio import Redis
|
|
33
34
|
|
|
34
35
|
from reflex import constants, model
|
|
35
|
-
from reflex.base import Base
|
|
36
36
|
from reflex.compiler import templates
|
|
37
37
|
from reflex.config import Config, get_config
|
|
38
38
|
from reflex.utils import console, net, path_ops, processes
|
|
@@ -42,7 +42,8 @@ from reflex.utils.registry import _get_best_registry
|
|
|
42
42
|
CURRENTLY_INSTALLING_NODE = False
|
|
43
43
|
|
|
44
44
|
|
|
45
|
-
|
|
45
|
+
@dataclasses.dataclass(frozen=True)
|
|
46
|
+
class Template:
|
|
46
47
|
"""A template for a Reflex app."""
|
|
47
48
|
|
|
48
49
|
name: str
|
|
@@ -51,7 +52,8 @@ class Template(Base):
|
|
|
51
52
|
demo_url: str
|
|
52
53
|
|
|
53
54
|
|
|
54
|
-
|
|
55
|
+
@dataclasses.dataclass(frozen=True)
|
|
56
|
+
class CpuInfo:
|
|
55
57
|
"""Model to save cpu info."""
|
|
56
58
|
|
|
57
59
|
manufacturer_id: Optional[str]
|
|
@@ -1277,11 +1279,16 @@ def fetch_app_templates(version: str) -> dict[str, Template]:
|
|
|
1277
1279
|
),
|
|
1278
1280
|
None,
|
|
1279
1281
|
)
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
if
|
|
1284
|
-
|
|
1282
|
+
|
|
1283
|
+
filtered_templates = {}
|
|
1284
|
+
for tp in templates_data:
|
|
1285
|
+
if tp["hidden"] or tp["code_url"] is None:
|
|
1286
|
+
continue
|
|
1287
|
+
known_fields = set(f.name for f in dataclasses.fields(Template))
|
|
1288
|
+
filtered_templates[tp["name"]] = Template(
|
|
1289
|
+
**{k: v for k, v in tp.items() if k in known_fields}
|
|
1290
|
+
)
|
|
1291
|
+
return filtered_templates
|
|
1285
1292
|
|
|
1286
1293
|
|
|
1287
1294
|
def create_config_init_app_from_remote_template(app_name: str, template_url: str):
|
reflex/utils/pyi_generator.py
CHANGED
|
@@ -19,8 +19,8 @@ from types import ModuleType, SimpleNamespace
|
|
|
19
19
|
from typing import Any, Callable, Iterable, Type, get_args
|
|
20
20
|
|
|
21
21
|
from reflex.components.component import Component
|
|
22
|
-
from reflex.ivars.base import ImmutableVar
|
|
23
22
|
from reflex.utils import types as rx_types
|
|
23
|
+
from reflex.vars.base import Var
|
|
24
24
|
|
|
25
25
|
logger = logging.getLogger("pyi_generator")
|
|
26
26
|
|
|
@@ -69,11 +69,10 @@ DEFAULT_TYPING_IMPORTS = {
|
|
|
69
69
|
# TODO: fix import ordering and unused imports with ruff later
|
|
70
70
|
DEFAULT_IMPORTS = {
|
|
71
71
|
"typing": sorted(DEFAULT_TYPING_IMPORTS),
|
|
72
|
-
"reflex.vars": ["Var"],
|
|
73
72
|
"reflex.components.core.breakpoints": ["Breakpoints"],
|
|
74
73
|
"reflex.event": ["EventChain", "EventHandler", "EventSpec"],
|
|
75
74
|
"reflex.style": ["Style"],
|
|
76
|
-
"reflex.
|
|
75
|
+
"reflex.vars.base": ["Var"],
|
|
77
76
|
}
|
|
78
77
|
|
|
79
78
|
|
|
@@ -151,7 +150,7 @@ def _get_type_hint(value, type_hint_globals, is_optional=True) -> str:
|
|
|
151
150
|
|
|
152
151
|
if args:
|
|
153
152
|
inner_container_type_args = (
|
|
154
|
-
|
|
153
|
+
sorted((repr(arg) for arg in args))
|
|
155
154
|
if rx_types.is_literal(value)
|
|
156
155
|
else [
|
|
157
156
|
_get_type_hint(arg, type_hint_globals, is_optional=False)
|
|
@@ -185,7 +184,7 @@ def _get_type_hint(value, type_hint_globals, is_optional=True) -> str:
|
|
|
185
184
|
if arg is not type(None)
|
|
186
185
|
]
|
|
187
186
|
if len(types) > 1:
|
|
188
|
-
res = ", ".join(types)
|
|
187
|
+
res = ", ".join(sorted(types))
|
|
189
188
|
res = f"Union[{res}]"
|
|
190
189
|
elif isinstance(value, str):
|
|
191
190
|
ev = eval(value, type_hint_globals)
|
|
@@ -356,7 +355,7 @@ def _extract_class_props_as_ast_nodes(
|
|
|
356
355
|
with contextlib.suppress(AttributeError, KeyError):
|
|
357
356
|
# Try to get default from pydantic field definition.
|
|
358
357
|
default = target_class.__fields__[name].default
|
|
359
|
-
if isinstance(default,
|
|
358
|
+
if isinstance(default, Var):
|
|
360
359
|
default = default._decode() # type: ignore
|
|
361
360
|
|
|
362
361
|
kwargs.append(
|
|
@@ -434,7 +433,7 @@ def _generate_component_create_functiondef(
|
|
|
434
433
|
ast.arg(
|
|
435
434
|
arg=trigger,
|
|
436
435
|
annotation=ast.Name(
|
|
437
|
-
id="Optional[Union[EventHandler, EventSpec, list, Callable,
|
|
436
|
+
id="Optional[Union[EventHandler, EventSpec, list, Callable, Var]]"
|
|
438
437
|
),
|
|
439
438
|
),
|
|
440
439
|
ast.Constant(value=None),
|
|
@@ -903,7 +902,13 @@ class PyiGenerator:
|
|
|
903
902
|
# construct the import statement and handle special cases for aliases
|
|
904
903
|
sub_mod_attrs_imports = [
|
|
905
904
|
f"from .{path} import {mod if not isinstance(mod, tuple) else mod[0]} as {mod if not isinstance(mod, tuple) else mod[1]}"
|
|
906
|
-
+ (
|
|
905
|
+
+ (
|
|
906
|
+
" # type: ignore"
|
|
907
|
+
if mod in pyright_ignore_imports
|
|
908
|
+
else " # noqa" # ignore ruff formatting here for cases like rx.list.
|
|
909
|
+
if isinstance(mod, tuple)
|
|
910
|
+
else ""
|
|
911
|
+
)
|
|
907
912
|
for mod, path in sub_mod_attrs.items()
|
|
908
913
|
]
|
|
909
914
|
sub_mod_attrs_imports.append("")
|
reflex/utils/serializers.py
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
|
+
import dataclasses
|
|
5
6
|
import functools
|
|
6
7
|
import json
|
|
7
8
|
import warnings
|
|
@@ -29,7 +30,7 @@ from reflex.utils import types
|
|
|
29
30
|
|
|
30
31
|
# Mapping from type to a serializer.
|
|
31
32
|
# The serializer should convert the type to a JSON object.
|
|
32
|
-
SerializedType = Union[str, bool, int, float, list, dict]
|
|
33
|
+
SerializedType = Union[str, bool, int, float, list, dict, None]
|
|
33
34
|
|
|
34
35
|
|
|
35
36
|
Serializer = Callable[[Type], SerializedType]
|
|
@@ -124,6 +125,8 @@ def serialize(
|
|
|
124
125
|
|
|
125
126
|
# If there is no serializer, return None.
|
|
126
127
|
if serializer is None:
|
|
128
|
+
if dataclasses.is_dataclass(value) and not isinstance(value, type):
|
|
129
|
+
return serialize(dataclasses.asdict(value))
|
|
127
130
|
if get_type:
|
|
128
131
|
return None, None
|
|
129
132
|
return None
|
|
@@ -225,7 +228,7 @@ def serialize_str(value: str) -> str:
|
|
|
225
228
|
|
|
226
229
|
|
|
227
230
|
@serializer
|
|
228
|
-
def serialize_primitive(value: Union[bool, int, float, None])
|
|
231
|
+
def serialize_primitive(value: Union[bool, int, float, None]):
|
|
229
232
|
"""Serialize a primitive type.
|
|
230
233
|
|
|
231
234
|
Args:
|
|
@@ -234,13 +237,11 @@ def serialize_primitive(value: Union[bool, int, float, None]) -> str:
|
|
|
234
237
|
Returns:
|
|
235
238
|
The serialized number/bool/None.
|
|
236
239
|
"""
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
return format.json_dumps(value)
|
|
240
|
+
return value
|
|
240
241
|
|
|
241
242
|
|
|
242
243
|
@serializer
|
|
243
|
-
def serialize_base(value: Base) ->
|
|
244
|
+
def serialize_base(value: Base) -> dict:
|
|
244
245
|
"""Serialize a Base instance.
|
|
245
246
|
|
|
246
247
|
Args:
|
|
@@ -249,18 +250,11 @@ def serialize_base(value: Base) -> str:
|
|
|
249
250
|
Returns:
|
|
250
251
|
The serialized Base.
|
|
251
252
|
"""
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
return str(
|
|
255
|
-
LiteralObjectVar.create(
|
|
256
|
-
{k: (None if callable(v) else v) for k, v in value.dict().items()},
|
|
257
|
-
_var_type=type(value),
|
|
258
|
-
)
|
|
259
|
-
)
|
|
253
|
+
return {k: serialize(v) for k, v in value.dict().items() if not callable(v)}
|
|
260
254
|
|
|
261
255
|
|
|
262
256
|
@serializer
|
|
263
|
-
def serialize_list(value: Union[List, Tuple, Set]) ->
|
|
257
|
+
def serialize_list(value: Union[List, Tuple, Set]) -> list:
|
|
264
258
|
"""Serialize a list to a JSON string.
|
|
265
259
|
|
|
266
260
|
Args:
|
|
@@ -269,13 +263,11 @@ def serialize_list(value: Union[List, Tuple, Set]) -> str:
|
|
|
269
263
|
Returns:
|
|
270
264
|
The serialized list.
|
|
271
265
|
"""
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
return str(LiteralArrayVar.create(value))
|
|
266
|
+
return [serialize(item) for item in value]
|
|
275
267
|
|
|
276
268
|
|
|
277
269
|
@serializer
|
|
278
|
-
def serialize_dict(prop: Dict[str, Any]) ->
|
|
270
|
+
def serialize_dict(prop: Dict[str, Any]) -> dict:
|
|
279
271
|
"""Serialize a dictionary to a JSON string.
|
|
280
272
|
|
|
281
273
|
Args:
|
|
@@ -284,9 +276,7 @@ def serialize_dict(prop: Dict[str, Any]) -> str:
|
|
|
284
276
|
Returns:
|
|
285
277
|
The serialized dictionary.
|
|
286
278
|
"""
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
return str(LiteralObjectVar.create(prop))
|
|
279
|
+
return {k: serialize(v) for k, v in prop.items()}
|
|
290
280
|
|
|
291
281
|
|
|
292
282
|
@serializer(to=str)
|
reflex/utils/telemetry.py
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
5
|
import asyncio
|
|
6
|
+
import dataclasses
|
|
6
7
|
import multiprocessing
|
|
7
8
|
import platform
|
|
8
9
|
import warnings
|
|
@@ -120,7 +121,7 @@ def _prepare_event(event: str, **kwargs) -> dict:
|
|
|
120
121
|
return {}
|
|
121
122
|
|
|
122
123
|
if UTC is None:
|
|
123
|
-
# for python 3.
|
|
124
|
+
# for python 3.10
|
|
124
125
|
stamp = datetime.utcnow().isoformat()
|
|
125
126
|
else:
|
|
126
127
|
# for python 3.11 & 3.12
|
|
@@ -144,7 +145,7 @@ def _prepare_event(event: str, **kwargs) -> dict:
|
|
|
144
145
|
"python_version": get_python_version(),
|
|
145
146
|
"cpu_count": get_cpu_count(),
|
|
146
147
|
"memory": get_memory(),
|
|
147
|
-
"cpu_info":
|
|
148
|
+
"cpu_info": dataclasses.asdict(cpuinfo) if cpuinfo else {},
|
|
148
149
|
**additional_fields,
|
|
149
150
|
},
|
|
150
151
|
"timestamp": stamp,
|
reflex/utils/types.py
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
5
|
import contextlib
|
|
6
|
+
import dataclasses
|
|
6
7
|
import inspect
|
|
7
8
|
import sys
|
|
8
9
|
import types
|
|
@@ -95,7 +96,7 @@ PrimitiveType = Union[int, float, bool, str, list, dict, set, tuple]
|
|
|
95
96
|
StateVar = Union[PrimitiveType, Base, None]
|
|
96
97
|
StateIterVar = Union[list, set, tuple]
|
|
97
98
|
|
|
98
|
-
# ArgsSpec = Callable[[
|
|
99
|
+
# ArgsSpec = Callable[[Var], list[Var]]
|
|
99
100
|
ArgsSpec = Callable
|
|
100
101
|
|
|
101
102
|
|
|
@@ -480,7 +481,11 @@ def is_valid_var_type(type_: Type) -> bool:
|
|
|
480
481
|
|
|
481
482
|
if is_union(type_):
|
|
482
483
|
return all((is_valid_var_type(arg) for arg in get_args(type_)))
|
|
483
|
-
return
|
|
484
|
+
return (
|
|
485
|
+
_issubclass(type_, StateVar)
|
|
486
|
+
or serializers.has_serializer(type_)
|
|
487
|
+
or dataclasses.is_dataclass(type_)
|
|
488
|
+
)
|
|
484
489
|
|
|
485
490
|
|
|
486
491
|
def is_backend_base_variable(name: str, cls: Type) -> bool:
|
|
@@ -514,7 +519,7 @@ def is_backend_base_variable(name: str, cls: Type) -> bool:
|
|
|
514
519
|
if name in cls.inherited_backend_vars:
|
|
515
520
|
return False
|
|
516
521
|
|
|
517
|
-
from reflex.
|
|
522
|
+
from reflex.vars.base import is_computed_var
|
|
518
523
|
|
|
519
524
|
if name in cls.__dict__:
|
|
520
525
|
value = cls.__dict__[name]
|
|
@@ -590,11 +595,11 @@ def validate_literal(key: str, value: Any, expected_type: Type, comp_name: str):
|
|
|
590
595
|
Raises:
|
|
591
596
|
ValueError: When the value is not a valid literal.
|
|
592
597
|
"""
|
|
593
|
-
from reflex.
|
|
598
|
+
from reflex.vars import Var
|
|
594
599
|
|
|
595
600
|
if (
|
|
596
601
|
is_literal(expected_type)
|
|
597
|
-
and not isinstance(value,
|
|
602
|
+
and not isinstance(value, Var) # validating vars is not supported yet.
|
|
598
603
|
and not is_encoded_fstring(value) # f-strings are not supported.
|
|
599
604
|
and value not in expected_type.__args__
|
|
600
605
|
):
|
|
@@ -627,7 +632,7 @@ def validate_parameter_literals(func):
|
|
|
627
632
|
annotations = {param[0]: param[1].annotation for param in func_params}
|
|
628
633
|
|
|
629
634
|
# validate args
|
|
630
|
-
for param, arg in zip(annotations, args):
|
|
635
|
+
for param, arg in zip(annotations, args, strict=False):
|
|
631
636
|
if annotations[param] is inspect.Parameter.empty:
|
|
632
637
|
continue
|
|
633
638
|
validate_literal(param, arg, annotations[param], func.__name__)
|
|
@@ -1,8 +1,12 @@
|
|
|
1
|
-
"""
|
|
1
|
+
"""Immutable-Based Var System."""
|
|
2
2
|
|
|
3
|
-
from .base import ImmutableVar as ImmutableVar
|
|
4
3
|
from .base import LiteralVar as LiteralVar
|
|
4
|
+
from .base import Var as Var
|
|
5
|
+
from .base import VarData as VarData
|
|
6
|
+
from .base import get_unique_variable_name as get_unique_variable_name
|
|
7
|
+
from .base import get_uuid_string_var as get_uuid_string_var
|
|
5
8
|
from .base import var_operation as var_operation
|
|
9
|
+
from .base import var_operation_return as var_operation_return
|
|
6
10
|
from .function import FunctionStringVar as FunctionStringVar
|
|
7
11
|
from .function import FunctionVar as FunctionVar
|
|
8
12
|
from .function import VarOperationCall as VarOperationCall
|