reflex 0.5.3a2__py3-none-any.whl → 0.5.4a1__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/demo/code/webui/state.py +3 -2
- reflex/.templates/web/components/reflex/radix_themes_color_mode_provider.js +19 -20
- reflex/.templates/web/utils/state.js +6 -0
- reflex/__init__.py +7 -1
- reflex/__init__.pyi +2 -0
- reflex/app.py +2 -5
- reflex/compiler/compiler.py +2 -2
- reflex/components/component.py +19 -6
- reflex/components/core/client_side_routing.py +2 -2
- reflex/components/core/client_side_routing.pyi +1 -0
- reflex/components/core/upload.py +1 -1
- reflex/components/datadisplay/dataeditor.py +7 -2
- reflex/components/datadisplay/dataeditor.pyi +1 -0
- reflex/components/el/elements/forms.py +18 -11
- reflex/components/el/elements/forms.pyi +1 -0
- reflex/components/markdown/markdown.py +1 -1
- reflex/components/plotly/plotly.py +76 -12
- reflex/components/plotly/plotly.pyi +15 -82
- reflex/components/radix/themes/base.py +9 -2
- reflex/components/radix/themes/base.pyi +1 -0
- reflex/components/recharts/cartesian.py +42 -14
- reflex/components/recharts/cartesian.pyi +81 -17
- reflex/components/recharts/charts.py +12 -21
- reflex/components/recharts/charts.pyi +53 -14
- reflex/components/sonner/toast.py +30 -14
- reflex/components/sonner/toast.pyi +8 -4
- reflex/config.py +22 -14
- reflex/constants/__init__.py +2 -0
- reflex/constants/config.py +7 -0
- reflex/event.py +12 -6
- reflex/experimental/__init__.py +22 -2
- reflex/experimental/client_state.py +81 -23
- reflex/experimental/hooks.py +29 -35
- reflex/experimental/layout.py +8 -3
- reflex/experimental/layout.pyi +536 -0
- reflex/reflex.py +9 -5
- reflex/style.py +1 -0
- reflex/testing.py +44 -13
- reflex/utils/format.py +8 -1
- reflex/utils/processes.py +27 -0
- reflex/utils/pyi_generator.py +11 -4
- reflex/utils/serializers.py +114 -15
- reflex/utils/types.py +6 -2
- reflex/vars.py +39 -10
- reflex/vars.pyi +2 -2
- {reflex-0.5.3a2.dist-info → reflex-0.5.4a1.dist-info}/METADATA +1 -1
- {reflex-0.5.3a2.dist-info → reflex-0.5.4a1.dist-info}/RECORD +50 -49
- {reflex-0.5.3a2.dist-info → reflex-0.5.4a1.dist-info}/LICENSE +0 -0
- {reflex-0.5.3a2.dist-info → reflex-0.5.4a1.dist-info}/WHEEL +0 -0
- {reflex-0.5.3a2.dist-info → reflex-0.5.4a1.dist-info}/entry_points.txt +0 -0
|
@@ -11,6 +11,7 @@ from typing import Any, Dict, List, Union
|
|
|
11
11
|
from reflex.components.component import Component
|
|
12
12
|
from reflex.components.recharts.general import ResponsiveContainer
|
|
13
13
|
from reflex.constants import EventTriggers
|
|
14
|
+
from reflex.event import EventHandler
|
|
14
15
|
from reflex.vars import Var
|
|
15
16
|
from .recharts import (
|
|
16
17
|
LiteralAnimationEasing,
|
|
@@ -105,12 +106,6 @@ class AreaChart(ChartBase):
|
|
|
105
106
|
Union[int, Literal["dataMin", "dataMax", "auto"]],
|
|
106
107
|
]
|
|
107
108
|
] = None,
|
|
108
|
-
stack_offset: Optional[
|
|
109
|
-
Union[
|
|
110
|
-
Var[Literal["expand", "none", "wiggle", "silhouette"]],
|
|
111
|
-
Literal["expand", "none", "wiggle", "silhouette"],
|
|
112
|
-
]
|
|
113
|
-
] = None,
|
|
114
109
|
data: Optional[Union[Var[List[Dict[str, Any]]], List[Dict[str, Any]]]] = None,
|
|
115
110
|
sync_id: Optional[Union[Var[str], str]] = None,
|
|
116
111
|
sync_method: Optional[
|
|
@@ -125,6 +120,12 @@ class AreaChart(ChartBase):
|
|
|
125
120
|
]
|
|
126
121
|
] = None,
|
|
127
122
|
margin: Optional[Union[Var[Dict[str, Any]], Dict[str, Any]]] = None,
|
|
123
|
+
stack_offset: Optional[
|
|
124
|
+
Union[
|
|
125
|
+
Var[Literal["expand", "none", "wiggle", "silhouette"]],
|
|
126
|
+
Literal["expand", "none", "wiggle", "silhouette"],
|
|
127
|
+
]
|
|
128
|
+
] = None,
|
|
128
129
|
style: Optional[Style] = None,
|
|
129
130
|
key: Optional[Any] = None,
|
|
130
131
|
id: Optional[Any] = None,
|
|
@@ -150,7 +151,6 @@ class AreaChart(ChartBase):
|
|
|
150
151
|
Args:
|
|
151
152
|
*children: The children of the chart component.
|
|
152
153
|
base_value: The base value of area. Number | 'dataMin' | 'dataMax' | 'auto'
|
|
153
|
-
stack_offset: The type of offset function used to generate the lower and upper values in the series array. The four types are built-in offsets in d3-shape. 'expand' | 'none' | 'wiggle' | 'silhouette'
|
|
154
154
|
data: The source data, in which each element is an object.
|
|
155
155
|
sync_id: If any two categorical charts(rx.line_chart, rx.area_chart, rx.bar_chart, rx.composed_chart) have the same sync_id, these two charts can sync the position GraphingTooltip, and the start_index, end_index of Brush.
|
|
156
156
|
sync_method: When sync_id is provided, allows customisation of how the charts will synchronize GraphingTooltips and brushes. Using 'index' (default setting), other charts will reuse current datum's index within the data array. In cases where data does not have the same length, this might yield unexpected results. In that case use 'value' which will try to match other charts values, or a fully custom function which will receive tick, data as argument and should return an index. 'index' | 'value' | function
|
|
@@ -158,6 +158,7 @@ class AreaChart(ChartBase):
|
|
|
158
158
|
height: The height of chart container.
|
|
159
159
|
layout: The layout of area in the chart. 'horizontal' | 'vertical'
|
|
160
160
|
margin: The sizes of whitespace around the chart.
|
|
161
|
+
stack_offset: The type of offset function used to generate the lower and upper values in the series array. The four types are built-in offsets in d3-shape. 'expand' | 'none' | 'wiggle' | 'silhouette'
|
|
161
162
|
style: The style of the component.
|
|
162
163
|
key: A unique key for the component.
|
|
163
164
|
id: The id for the component.
|
|
@@ -526,9 +527,6 @@ class RadarChart(ChartBase):
|
|
|
526
527
|
on_mouse_leave: Optional[
|
|
527
528
|
Union[EventHandler, EventSpec, list, function, BaseVar]
|
|
528
529
|
] = None,
|
|
529
|
-
on_mouse_move: Optional[
|
|
530
|
-
Union[EventHandler, EventSpec, list, function, BaseVar]
|
|
531
|
-
] = None,
|
|
532
530
|
**props
|
|
533
531
|
) -> "RadarChart":
|
|
534
532
|
"""Create a chart component.
|
|
@@ -613,9 +611,6 @@ class RadialBarChart(ChartBase):
|
|
|
613
611
|
on_mouse_leave: Optional[
|
|
614
612
|
Union[EventHandler, EventSpec, list, function, BaseVar]
|
|
615
613
|
] = None,
|
|
616
|
-
on_mouse_move: Optional[
|
|
617
|
-
Union[EventHandler, EventSpec, list, function, BaseVar]
|
|
618
|
-
] = None,
|
|
619
614
|
**props
|
|
620
615
|
) -> "RadialBarChart":
|
|
621
616
|
"""Create a chart component.
|
|
@@ -688,6 +683,9 @@ class ScatterChart(ChartBase):
|
|
|
688
683
|
on_click: Optional[
|
|
689
684
|
Union[EventHandler, EventSpec, list, function, BaseVar]
|
|
690
685
|
] = None,
|
|
686
|
+
on_mouse_down: Optional[
|
|
687
|
+
Union[EventHandler, EventSpec, list, function, BaseVar]
|
|
688
|
+
] = None,
|
|
691
689
|
on_mouse_enter: Optional[
|
|
692
690
|
Union[EventHandler, EventSpec, list, function, BaseVar]
|
|
693
691
|
] = None,
|
|
@@ -703,6 +701,9 @@ class ScatterChart(ChartBase):
|
|
|
703
701
|
on_mouse_over: Optional[
|
|
704
702
|
Union[EventHandler, EventSpec, list, function, BaseVar]
|
|
705
703
|
] = None,
|
|
704
|
+
on_mouse_up: Optional[
|
|
705
|
+
Union[EventHandler, EventSpec, list, function, BaseVar]
|
|
706
|
+
] = None,
|
|
706
707
|
**props
|
|
707
708
|
) -> "ScatterChart":
|
|
708
709
|
"""Create a chart component.
|
|
@@ -731,7 +732,6 @@ class ScatterChart(ChartBase):
|
|
|
731
732
|
...
|
|
732
733
|
|
|
733
734
|
class FunnelChart(RechartsCharts):
|
|
734
|
-
def get_event_triggers(self) -> dict[str, Union[Var, Any]]: ...
|
|
735
735
|
@overload
|
|
736
736
|
@classmethod
|
|
737
737
|
def create( # type: ignore
|
|
@@ -756,9 +756,27 @@ class FunnelChart(RechartsCharts):
|
|
|
756
756
|
class_name: Optional[Any] = None,
|
|
757
757
|
autofocus: Optional[bool] = None,
|
|
758
758
|
custom_attrs: Optional[Dict[str, Union[Var, str]]] = None,
|
|
759
|
+
on_blur: Optional[
|
|
760
|
+
Union[EventHandler, EventSpec, list, function, BaseVar]
|
|
761
|
+
] = None,
|
|
759
762
|
on_click: Optional[
|
|
760
763
|
Union[EventHandler, EventSpec, list, function, BaseVar]
|
|
761
764
|
] = None,
|
|
765
|
+
on_context_menu: Optional[
|
|
766
|
+
Union[EventHandler, EventSpec, list, function, BaseVar]
|
|
767
|
+
] = None,
|
|
768
|
+
on_double_click: Optional[
|
|
769
|
+
Union[EventHandler, EventSpec, list, function, BaseVar]
|
|
770
|
+
] = None,
|
|
771
|
+
on_focus: Optional[
|
|
772
|
+
Union[EventHandler, EventSpec, list, function, BaseVar]
|
|
773
|
+
] = None,
|
|
774
|
+
on_mount: Optional[
|
|
775
|
+
Union[EventHandler, EventSpec, list, function, BaseVar]
|
|
776
|
+
] = None,
|
|
777
|
+
on_mouse_down: Optional[
|
|
778
|
+
Union[EventHandler, EventSpec, list, function, BaseVar]
|
|
779
|
+
] = None,
|
|
762
780
|
on_mouse_enter: Optional[
|
|
763
781
|
Union[EventHandler, EventSpec, list, function, BaseVar]
|
|
764
782
|
] = None,
|
|
@@ -768,6 +786,21 @@ class FunnelChart(RechartsCharts):
|
|
|
768
786
|
on_mouse_move: Optional[
|
|
769
787
|
Union[EventHandler, EventSpec, list, function, BaseVar]
|
|
770
788
|
] = None,
|
|
789
|
+
on_mouse_out: Optional[
|
|
790
|
+
Union[EventHandler, EventSpec, list, function, BaseVar]
|
|
791
|
+
] = None,
|
|
792
|
+
on_mouse_over: Optional[
|
|
793
|
+
Union[EventHandler, EventSpec, list, function, BaseVar]
|
|
794
|
+
] = None,
|
|
795
|
+
on_mouse_up: Optional[
|
|
796
|
+
Union[EventHandler, EventSpec, list, function, BaseVar]
|
|
797
|
+
] = None,
|
|
798
|
+
on_scroll: Optional[
|
|
799
|
+
Union[EventHandler, EventSpec, list, function, BaseVar]
|
|
800
|
+
] = None,
|
|
801
|
+
on_unmount: Optional[
|
|
802
|
+
Union[EventHandler, EventSpec, list, function, BaseVar]
|
|
803
|
+
] = None,
|
|
771
804
|
**props
|
|
772
805
|
) -> "FunnelChart":
|
|
773
806
|
"""Create a new memoization leaf component.
|
|
@@ -821,6 +854,12 @@ class Treemap(RechartsCharts):
|
|
|
821
854
|
class_name: Optional[Any] = None,
|
|
822
855
|
autofocus: Optional[bool] = None,
|
|
823
856
|
custom_attrs: Optional[Dict[str, Union[Var, str]]] = None,
|
|
857
|
+
on_animation_end: Optional[
|
|
858
|
+
Union[EventHandler, EventSpec, list, function, BaseVar]
|
|
859
|
+
] = None,
|
|
860
|
+
on_animation_start: Optional[
|
|
861
|
+
Union[EventHandler, EventSpec, list, function, BaseVar]
|
|
862
|
+
] = None,
|
|
824
863
|
on_blur: Optional[
|
|
825
864
|
Union[EventHandler, EventSpec, list, function, BaseVar]
|
|
826
865
|
] = None,
|
|
@@ -106,7 +106,7 @@ class ToastProps(PropsBase):
|
|
|
106
106
|
cancel: Optional[ToastAction]
|
|
107
107
|
|
|
108
108
|
# Custom id for the toast.
|
|
109
|
-
id: Optional[str]
|
|
109
|
+
id: Optional[Union[str, Var]]
|
|
110
110
|
|
|
111
111
|
# Removes the default styling, which allows for easier customization.
|
|
112
112
|
unstyled: Optional[bool]
|
|
@@ -127,7 +127,7 @@ class ToastProps(PropsBase):
|
|
|
127
127
|
# Function that gets called when the toast disappears automatically after it's timeout (duration` prop).
|
|
128
128
|
on_auto_close: Optional[Any]
|
|
129
129
|
|
|
130
|
-
def dict(self, *args, **kwargs) -> dict:
|
|
130
|
+
def dict(self, *args, **kwargs) -> dict[str, Any]:
|
|
131
131
|
"""Convert the object to a dictionary.
|
|
132
132
|
|
|
133
133
|
Args:
|
|
@@ -137,7 +137,7 @@ class ToastProps(PropsBase):
|
|
|
137
137
|
Returns:
|
|
138
138
|
The object as a dictionary with ToastAction fields intact.
|
|
139
139
|
"""
|
|
140
|
-
kwargs.setdefault("exclude_none", True)
|
|
140
|
+
kwargs.setdefault("exclude_none", True) # type: ignore
|
|
141
141
|
d = super().dict(*args, **kwargs)
|
|
142
142
|
# Keep these fields as ToastAction so they can be serialized specially
|
|
143
143
|
if "action" in d:
|
|
@@ -208,7 +208,12 @@ class Toaster(Component):
|
|
|
208
208
|
# Pauses toast timers when the page is hidden, e.g., when the tab is backgrounded, the browser is minimized, or the OS is locked.
|
|
209
209
|
pause_when_page_is_hidden: Var[bool]
|
|
210
210
|
|
|
211
|
-
def
|
|
211
|
+
def add_hooks(self) -> list[Var | str]:
|
|
212
|
+
"""Add hooks for the toaster component.
|
|
213
|
+
|
|
214
|
+
Returns:
|
|
215
|
+
The hooks for the toaster component.
|
|
216
|
+
"""
|
|
212
217
|
hook = Var.create_safe(
|
|
213
218
|
f"{toast_ref} = toast",
|
|
214
219
|
_var_is_local=True,
|
|
@@ -219,7 +224,7 @@ class Toaster(Component):
|
|
|
219
224
|
}
|
|
220
225
|
),
|
|
221
226
|
)
|
|
222
|
-
return hook
|
|
227
|
+
return [hook]
|
|
223
228
|
|
|
224
229
|
@staticmethod
|
|
225
230
|
def send_toast(message: str, level: str | None = None, **props) -> EventSpec:
|
|
@@ -235,13 +240,13 @@ class Toaster(Component):
|
|
|
235
240
|
"""
|
|
236
241
|
toast_command = f"{toast_ref}.{level}" if level is not None else toast_ref
|
|
237
242
|
if props:
|
|
238
|
-
args = serialize(ToastProps(**props))
|
|
243
|
+
args = serialize(ToastProps(**props)) # type: ignore
|
|
239
244
|
toast = f"{toast_command}(`{message}`, {args})"
|
|
240
245
|
else:
|
|
241
246
|
toast = f"{toast_command}(`{message}`)"
|
|
242
247
|
|
|
243
|
-
toast_action = Var.
|
|
244
|
-
return call_script(toast_action)
|
|
248
|
+
toast_action = Var.create_safe(toast, _var_is_string=False, _var_is_local=True)
|
|
249
|
+
return call_script(toast_action)
|
|
245
250
|
|
|
246
251
|
@staticmethod
|
|
247
252
|
def toast_info(message: str, **kwargs):
|
|
@@ -295,7 +300,8 @@ class Toaster(Component):
|
|
|
295
300
|
"""
|
|
296
301
|
return Toaster.send_toast(message, level="success", **kwargs)
|
|
297
302
|
|
|
298
|
-
|
|
303
|
+
@staticmethod
|
|
304
|
+
def toast_dismiss(id: Var | str | None = None):
|
|
299
305
|
"""Dismiss a toast.
|
|
300
306
|
|
|
301
307
|
Args:
|
|
@@ -304,12 +310,22 @@ class Toaster(Component):
|
|
|
304
310
|
Returns:
|
|
305
311
|
The toast dismiss event.
|
|
306
312
|
"""
|
|
307
|
-
|
|
308
|
-
|
|
313
|
+
dismiss_var_data = None
|
|
314
|
+
|
|
315
|
+
if isinstance(id, Var):
|
|
316
|
+
dismiss = f"{toast_ref}.dismiss({id._var_name_unwrapped})"
|
|
317
|
+
dismiss_var_data = id._var_data
|
|
318
|
+
elif isinstance(id, str):
|
|
319
|
+
dismiss = f"{toast_ref}.dismiss('{id}')"
|
|
309
320
|
else:
|
|
310
|
-
dismiss = f"{toast_ref}.dismiss(
|
|
311
|
-
dismiss_action = Var.
|
|
312
|
-
|
|
321
|
+
dismiss = f"{toast_ref}.dismiss()"
|
|
322
|
+
dismiss_action = Var.create_safe(
|
|
323
|
+
dismiss,
|
|
324
|
+
_var_is_string=False,
|
|
325
|
+
_var_is_local=True,
|
|
326
|
+
_var_data=dismiss_var_data,
|
|
327
|
+
)
|
|
328
|
+
return call_script(dismiss_action)
|
|
313
329
|
|
|
314
330
|
|
|
315
331
|
# TODO: figure out why loading toast stay open forever
|
|
@@ -46,7 +46,7 @@ class ToastProps(PropsBase):
|
|
|
46
46
|
dismissible: Optional[bool]
|
|
47
47
|
action: Optional[ToastAction]
|
|
48
48
|
cancel: Optional[ToastAction]
|
|
49
|
-
id: Optional[str]
|
|
49
|
+
id: Optional[Union[str, Var]]
|
|
50
50
|
unstyled: Optional[bool]
|
|
51
51
|
style: Optional[Style]
|
|
52
52
|
action_button_styles: Optional[Style]
|
|
@@ -54,9 +54,10 @@ class ToastProps(PropsBase):
|
|
|
54
54
|
on_dismiss: Optional[Any]
|
|
55
55
|
on_auto_close: Optional[Any]
|
|
56
56
|
|
|
57
|
-
def dict(self, *args, **kwargs) -> dict: ...
|
|
57
|
+
def dict(self, *args, **kwargs) -> dict[str, Any]: ...
|
|
58
58
|
|
|
59
59
|
class Toaster(Component):
|
|
60
|
+
def add_hooks(self) -> list[Var | str]: ...
|
|
60
61
|
@staticmethod
|
|
61
62
|
def send_toast(message: str, level: str | None = None, **props) -> EventSpec: ...
|
|
62
63
|
@staticmethod
|
|
@@ -67,7 +68,8 @@ class Toaster(Component):
|
|
|
67
68
|
def toast_error(message: str, **kwargs): ...
|
|
68
69
|
@staticmethod
|
|
69
70
|
def toast_success(message: str, **kwargs): ...
|
|
70
|
-
|
|
71
|
+
@staticmethod
|
|
72
|
+
def toast_dismiss(id: Var | str | None = None): ...
|
|
71
73
|
@overload
|
|
72
74
|
@classmethod
|
|
73
75
|
def create( # type: ignore
|
|
@@ -202,7 +204,9 @@ class ToastNamespace(ComponentNamespace):
|
|
|
202
204
|
dismiss = staticmethod(Toaster.toast_dismiss)
|
|
203
205
|
|
|
204
206
|
@staticmethod
|
|
205
|
-
def __call__(
|
|
207
|
+
def __call__(
|
|
208
|
+
message: str, level: Optional[str] = None, **props
|
|
209
|
+
) -> "Optional[EventSpec]":
|
|
206
210
|
"""Send a toast message.
|
|
207
211
|
|
|
208
212
|
Args:
|
reflex/config.py
CHANGED
|
@@ -161,13 +161,13 @@ class Config(Base):
|
|
|
161
161
|
loglevel: constants.LogLevel = constants.LogLevel.INFO
|
|
162
162
|
|
|
163
163
|
# The port to run the frontend on. NOTE: When running in dev mode, the next available port will be used if this is taken.
|
|
164
|
-
frontend_port: int =
|
|
164
|
+
frontend_port: int = constants.DefaultPorts.FRONTEND_PORT
|
|
165
165
|
|
|
166
166
|
# The path to run the frontend on. For example, "/app" will run the frontend on http://localhost:3000/app
|
|
167
167
|
frontend_path: str = ""
|
|
168
168
|
|
|
169
169
|
# The port to run the backend on. NOTE: When running in dev mode, the next available port will be used if this is taken.
|
|
170
|
-
backend_port: int =
|
|
170
|
+
backend_port: int = constants.DefaultPorts.BACKEND_PORT
|
|
171
171
|
|
|
172
172
|
# The backend url the frontend will connect to. This must be updated if the backend is hosted elsewhere, or in production.
|
|
173
173
|
api_url: str = f"http://localhost:{backend_port}"
|
|
@@ -316,17 +316,22 @@ class Config(Base):
|
|
|
316
316
|
):
|
|
317
317
|
self.deploy_url = f"http://localhost:{kwargs['frontend_port']}"
|
|
318
318
|
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
319
|
+
if "api_url" not in self._non_default_attributes:
|
|
320
|
+
# If running in Github Codespaces, override API_URL
|
|
321
|
+
codespace_name = os.getenv("CODESPACE_NAME")
|
|
322
322
|
GITHUB_CODESPACES_PORT_FORWARDING_DOMAIN = os.getenv(
|
|
323
323
|
"GITHUB_CODESPACES_PORT_FORWARDING_DOMAIN"
|
|
324
324
|
)
|
|
325
|
-
|
|
325
|
+
# If running on Replit.com interactively, override API_URL to ensure we maintain the backend_port
|
|
326
|
+
replit_dev_domain = os.getenv("REPLIT_DEV_DOMAIN")
|
|
327
|
+
backend_port = kwargs.get("backend_port", self.backend_port)
|
|
328
|
+
if codespace_name and GITHUB_CODESPACES_PORT_FORWARDING_DOMAIN:
|
|
326
329
|
self.api_url = (
|
|
327
330
|
f"https://{codespace_name}-{kwargs.get('backend_port', self.backend_port)}"
|
|
328
331
|
f".{GITHUB_CODESPACES_PORT_FORWARDING_DOMAIN}"
|
|
329
332
|
)
|
|
333
|
+
elif replit_dev_domain and backend_port:
|
|
334
|
+
self.api_url = f"https://{replit_dev_domain}:{backend_port}"
|
|
330
335
|
|
|
331
336
|
def _set_persistent(self, **kwargs):
|
|
332
337
|
"""Set values in this config and in the environment so they persist into subprocess.
|
|
@@ -352,11 +357,14 @@ def get_config(reload: bool = False) -> Config:
|
|
|
352
357
|
The app config.
|
|
353
358
|
"""
|
|
354
359
|
sys.path.insert(0, os.getcwd())
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
360
|
+
# only import the module if it exists. If a module spec exists then
|
|
361
|
+
# the module exists.
|
|
362
|
+
spec = importlib.util.find_spec(constants.Config.MODULE) # type: ignore
|
|
363
|
+
if not spec:
|
|
364
|
+
# we need this condition to ensure that a ModuleNotFound error is not thrown when
|
|
365
|
+
# running unit/integration tests.
|
|
366
|
+
return Config(app_name="")
|
|
367
|
+
rxconfig = importlib.import_module(constants.Config.MODULE)
|
|
368
|
+
if reload:
|
|
369
|
+
importlib.reload(rxconfig)
|
|
370
|
+
return rxconfig.config
|
reflex/constants/__init__.py
CHANGED
|
@@ -36,6 +36,7 @@ from .compiler import (
|
|
|
36
36
|
from .config import (
|
|
37
37
|
ALEMBIC_CONFIG,
|
|
38
38
|
Config,
|
|
39
|
+
DefaultPorts,
|
|
39
40
|
Expiration,
|
|
40
41
|
GitIgnore,
|
|
41
42
|
RequirementsTxt,
|
|
@@ -72,6 +73,7 @@ __ALL__ = [
|
|
|
72
73
|
ComponentName,
|
|
73
74
|
CustomComponents,
|
|
74
75
|
DefaultPage,
|
|
76
|
+
DefaultPorts,
|
|
75
77
|
Dirs,
|
|
76
78
|
Endpoint,
|
|
77
79
|
Env,
|
reflex/constants/config.py
CHANGED
|
@@ -50,5 +50,12 @@ class RequirementsTxt(SimpleNamespace):
|
|
|
50
50
|
DEFAULTS_STUB = f"{Reflex.MODULE_NAME}=="
|
|
51
51
|
|
|
52
52
|
|
|
53
|
+
class DefaultPorts(SimpleNamespace):
|
|
54
|
+
"""Default port constants."""
|
|
55
|
+
|
|
56
|
+
FRONTEND_PORT = 3000
|
|
57
|
+
BACKEND_PORT = 8000
|
|
58
|
+
|
|
59
|
+
|
|
53
60
|
# The deployment URL.
|
|
54
61
|
PRODUCTION_BACKEND_URL = "https://{username}-{app_name}.api.pynecone.app"
|
reflex/event.py
CHANGED
|
@@ -415,6 +415,8 @@ class FileUpload(Base):
|
|
|
415
415
|
) # type: ignore
|
|
416
416
|
else:
|
|
417
417
|
raise ValueError(f"{on_upload_progress} is not a valid event handler.")
|
|
418
|
+
if isinstance(events, Var):
|
|
419
|
+
raise ValueError(f"{on_upload_progress} cannot return a var {events}.")
|
|
418
420
|
on_upload_progress_chain = EventChain(
|
|
419
421
|
events=events,
|
|
420
422
|
args_spec=self.on_upload_progress_args_spec,
|
|
@@ -714,7 +716,7 @@ def _callback_arg_spec(eval_result):
|
|
|
714
716
|
|
|
715
717
|
|
|
716
718
|
def call_script(
|
|
717
|
-
javascript_code: str,
|
|
719
|
+
javascript_code: str | Var[str],
|
|
718
720
|
callback: EventSpec
|
|
719
721
|
| EventHandler
|
|
720
722
|
| Callable
|
|
@@ -831,19 +833,19 @@ def parse_args_spec(arg_spec: ArgsSpec):
|
|
|
831
833
|
)
|
|
832
834
|
|
|
833
835
|
|
|
834
|
-
def call_event_fn(fn: Callable, arg: Union[Var, ArgsSpec]) -> list[EventSpec]:
|
|
836
|
+
def call_event_fn(fn: Callable, arg: Union[Var, ArgsSpec]) -> list[EventSpec] | Var:
|
|
835
837
|
"""Call a function to a list of event specs.
|
|
836
838
|
|
|
837
|
-
The function should return
|
|
838
|
-
If the function takes in an arg, the arg will be passed to the
|
|
839
|
-
Otherwise, the function will be called with no args.
|
|
839
|
+
The function should return a single EventSpec, a list of EventSpecs, or a
|
|
840
|
+
single Var. If the function takes in an arg, the arg will be passed to the
|
|
841
|
+
function. Otherwise, the function will be called with no args.
|
|
840
842
|
|
|
841
843
|
Args:
|
|
842
844
|
fn: The function to call.
|
|
843
845
|
arg: The argument to pass to the function.
|
|
844
846
|
|
|
845
847
|
Returns:
|
|
846
|
-
The event specs from calling the function.
|
|
848
|
+
The event specs from calling the function or a Var.
|
|
847
849
|
|
|
848
850
|
Raises:
|
|
849
851
|
EventHandlerValueError: If the lambda has an invalid signature.
|
|
@@ -866,6 +868,10 @@ def call_event_fn(fn: Callable, arg: Union[Var, ArgsSpec]) -> list[EventSpec]:
|
|
|
866
868
|
else:
|
|
867
869
|
raise EventHandlerValueError(f"Lambda {fn} must have 0 or 1 arguments.")
|
|
868
870
|
|
|
871
|
+
# If the function returns a Var, assume it's an EventChain and render it directly.
|
|
872
|
+
if isinstance(out, Var):
|
|
873
|
+
return out
|
|
874
|
+
|
|
869
875
|
# Convert the output to a list.
|
|
870
876
|
if not isinstance(out, List):
|
|
871
877
|
out = [out]
|
reflex/experimental/__init__.py
CHANGED
|
@@ -17,7 +17,28 @@ warn(
|
|
|
17
17
|
"`rx._x` contains experimental features and might be removed at any time in the future .",
|
|
18
18
|
)
|
|
19
19
|
|
|
20
|
-
|
|
20
|
+
_EMITTED_PROMOTION_WARNINGS = set()
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class ExperimentalNamespace(SimpleNamespace):
|
|
24
|
+
"""Namespace for experimental features."""
|
|
25
|
+
|
|
26
|
+
@property
|
|
27
|
+
def toast(self):
|
|
28
|
+
"""Temporary property returning the toast namespace.
|
|
29
|
+
|
|
30
|
+
Remove this property when toast is fully promoted.
|
|
31
|
+
|
|
32
|
+
Returns:
|
|
33
|
+
The toast namespace.
|
|
34
|
+
"""
|
|
35
|
+
if "toast" not in _EMITTED_PROMOTION_WARNINGS:
|
|
36
|
+
_EMITTED_PROMOTION_WARNINGS.add("toast")
|
|
37
|
+
warn(f"`rx._x.toast` was promoted to `rx.toast`.")
|
|
38
|
+
return toast
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
_x = ExperimentalNamespace(
|
|
21
42
|
asset=asset,
|
|
22
43
|
client_state=ClientStateVar.create,
|
|
23
44
|
hooks=hooks,
|
|
@@ -25,5 +46,4 @@ _x = SimpleNamespace(
|
|
|
25
46
|
progress=progress,
|
|
26
47
|
PropsBase=PropsBase,
|
|
27
48
|
run_in_thread=run_in_thread,
|
|
28
|
-
toast=toast,
|
|
29
49
|
)
|