reflex 0.7.3a2__py3-none-any.whl → 0.7.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/app.py +17 -1
- reflex/compiler/compiler.py +63 -8
- reflex/components/core/client_side_routing.py +3 -3
- reflex/components/core/cond.py +20 -12
- reflex/components/core/upload.py +1 -1
- reflex/components/dynamic.py +2 -4
- reflex/components/lucide/icon.py +20 -27
- reflex/components/plotly/plotly.py +9 -9
- reflex/components/recharts/recharts.py +2 -2
- reflex/components/sonner/toast.py +1 -1
- reflex/config.py +19 -22
- reflex/constants/__init__.py +1 -2
- reflex/constants/base.py +3 -0
- reflex/constants/installer.py +8 -105
- reflex/custom_components/custom_components.py +8 -3
- reflex/reflex.py +18 -4
- reflex/state.py +9 -1
- reflex/testing.py +7 -1
- reflex/utils/build.py +3 -4
- reflex/utils/exec.py +146 -71
- reflex/utils/path_ops.py +15 -25
- reflex/utils/prerequisites.py +133 -182
- reflex/utils/processes.py +24 -21
- reflex/utils/registry.py +5 -5
- reflex/vars/base.py +2 -3
- reflex/vars/sequence.py +84 -0
- {reflex-0.7.3a2.dist-info → reflex-0.7.4a1.dist-info}/METADATA +3 -3
- {reflex-0.7.3a2.dist-info → reflex-0.7.4a1.dist-info}/RECORD +31 -32
- reflex/app_module_for_backend.py +0 -33
- {reflex-0.7.3a2.dist-info → reflex-0.7.4a1.dist-info}/WHEEL +0 -0
- {reflex-0.7.3a2.dist-info → reflex-0.7.4a1.dist-info}/entry_points.txt +0 -0
- {reflex-0.7.3a2.dist-info → reflex-0.7.4a1.dist-info}/licenses/LICENSE +0 -0
reflex/app.py
CHANGED
|
@@ -576,6 +576,22 @@ class App(MiddlewareMixin, LifespanMixin):
|
|
|
576
576
|
"""
|
|
577
577
|
if not self.api:
|
|
578
578
|
raise ValueError("The app has not been initialized.")
|
|
579
|
+
|
|
580
|
+
# For py3.9 compatibility when redis is used, we MUST add any decorator pages
|
|
581
|
+
# before compiling the app in a thread to avoid event loop error (REF-2172).
|
|
582
|
+
self._apply_decorated_pages()
|
|
583
|
+
|
|
584
|
+
compile_future = concurrent.futures.ThreadPoolExecutor(max_workers=1).submit(
|
|
585
|
+
self._compile
|
|
586
|
+
)
|
|
587
|
+
compile_future.add_done_callback(
|
|
588
|
+
# Force background compile errors to print eagerly
|
|
589
|
+
lambda f: f.result()
|
|
590
|
+
)
|
|
591
|
+
# Wait for the compile to finish in prod mode to ensure all optional endpoints are mounted.
|
|
592
|
+
if is_prod_mode():
|
|
593
|
+
compile_future.result()
|
|
594
|
+
|
|
579
595
|
return self.api
|
|
580
596
|
|
|
581
597
|
def _add_default_endpoints(self):
|
|
@@ -1063,7 +1079,7 @@ class App(MiddlewareMixin, LifespanMixin):
|
|
|
1063
1079
|
with stateful_pages_marker.open("r") as f:
|
|
1064
1080
|
stateful_pages = json.load(f)
|
|
1065
1081
|
for route in stateful_pages:
|
|
1066
|
-
console.
|
|
1082
|
+
console.debug(f"BE Evaluating stateful page: {route}")
|
|
1067
1083
|
self._compile_page(route, save_page=False)
|
|
1068
1084
|
self._enable_state()
|
|
1069
1085
|
self._add_optional_endpoints()
|
reflex/compiler/compiler.py
CHANGED
|
@@ -19,6 +19,7 @@ from reflex.components.component import (
|
|
|
19
19
|
from reflex.config import environment, get_config
|
|
20
20
|
from reflex.state import BaseState
|
|
21
21
|
from reflex.style import SYSTEM_COLOR_MODE
|
|
22
|
+
from reflex.utils import console, path_ops
|
|
22
23
|
from reflex.utils.exec import is_prod_mode
|
|
23
24
|
from reflex.utils.imports import ImportVar
|
|
24
25
|
from reflex.utils.prerequisites import get_web_dir
|
|
@@ -190,18 +191,74 @@ def _compile_root_stylesheet(stylesheets: list[str]) -> str:
|
|
|
190
191
|
if get_config().tailwind is not None
|
|
191
192
|
else []
|
|
192
193
|
)
|
|
194
|
+
|
|
195
|
+
failed_to_import_sass = False
|
|
193
196
|
for stylesheet in stylesheets:
|
|
194
197
|
if not utils.is_valid_url(stylesheet):
|
|
195
198
|
# check if stylesheet provided exists.
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
+
assets_app_path = Path.cwd() / constants.Dirs.APP_ASSETS
|
|
200
|
+
stylesheet_full_path = assets_app_path / stylesheet.strip("/")
|
|
201
|
+
|
|
199
202
|
if not stylesheet_full_path.exists():
|
|
200
203
|
raise FileNotFoundError(
|
|
201
204
|
f"The stylesheet file {stylesheet_full_path} does not exist."
|
|
202
205
|
)
|
|
203
|
-
|
|
206
|
+
|
|
207
|
+
if stylesheet_full_path.is_dir():
|
|
208
|
+
# NOTE: this can create an infinite loop, for example:
|
|
209
|
+
# assets/
|
|
210
|
+
# | dir_a/
|
|
211
|
+
# | | dir_c/ (symlink to "assets/dir_a")
|
|
212
|
+
# | dir_b/
|
|
213
|
+
# so to avoid the infinite loop, we don't include symbolic links
|
|
214
|
+
stylesheets += [
|
|
215
|
+
str(p.relative_to(assets_app_path))
|
|
216
|
+
for p in stylesheet_full_path.iterdir()
|
|
217
|
+
if not (p.is_symlink() and p.is_dir())
|
|
218
|
+
]
|
|
219
|
+
continue
|
|
220
|
+
|
|
221
|
+
if (
|
|
222
|
+
stylesheet_full_path.suffix[1:].lower()
|
|
223
|
+
in constants.Reflex.STYLESHEETS_SUPPORTED
|
|
224
|
+
):
|
|
225
|
+
target = (
|
|
226
|
+
Path.cwd()
|
|
227
|
+
/ constants.Dirs.WEB
|
|
228
|
+
/ constants.Dirs.STYLES
|
|
229
|
+
/ (stylesheet.rsplit(".", 1)[0].strip("/") + ".css")
|
|
230
|
+
)
|
|
231
|
+
target.parent.mkdir(parents=True, exist_ok=True)
|
|
232
|
+
|
|
233
|
+
if stylesheet_full_path.suffix == ".css":
|
|
234
|
+
path_ops.cp(src=stylesheet_full_path, dest=target, overwrite=True)
|
|
235
|
+
else:
|
|
236
|
+
try:
|
|
237
|
+
from sass import compile as sass_compile
|
|
238
|
+
|
|
239
|
+
target.write_text(
|
|
240
|
+
data=sass_compile(
|
|
241
|
+
filename=str(stylesheet_full_path),
|
|
242
|
+
output_style="compressed",
|
|
243
|
+
),
|
|
244
|
+
encoding="utf8",
|
|
245
|
+
)
|
|
246
|
+
except ImportError:
|
|
247
|
+
failed_to_import_sass = True
|
|
248
|
+
else:
|
|
249
|
+
raise FileNotFoundError(
|
|
250
|
+
f'The stylesheet file "{stylesheet_full_path}" is not a valid file.'
|
|
251
|
+
)
|
|
252
|
+
|
|
253
|
+
stylesheet = f"./{stylesheet.rsplit('.', 1)[0].strip('/')}.css"
|
|
254
|
+
|
|
204
255
|
sheets.append(stylesheet) if stylesheet not in sheets else None
|
|
256
|
+
|
|
257
|
+
if failed_to_import_sass:
|
|
258
|
+
console.error(
|
|
259
|
+
'The `libsass` package is required to compile sass/scss stylesheet files. Run `pip install "libsass>=0.23.0"`.'
|
|
260
|
+
)
|
|
261
|
+
|
|
205
262
|
return templates.STYLE.render(stylesheets=sheets)
|
|
206
263
|
|
|
207
264
|
|
|
@@ -311,13 +368,11 @@ def _compile_stateful_components(
|
|
|
311
368
|
|
|
312
369
|
# Include dynamic imports in the shared component.
|
|
313
370
|
if dynamic_imports := component._get_all_dynamic_imports():
|
|
314
|
-
rendered_components.update(
|
|
315
|
-
{dynamic_import: None for dynamic_import in dynamic_imports}
|
|
316
|
-
)
|
|
371
|
+
rendered_components.update(dict.fromkeys(dynamic_imports))
|
|
317
372
|
|
|
318
373
|
# Include custom code in the shared component.
|
|
319
374
|
rendered_components.update(
|
|
320
|
-
|
|
375
|
+
dict.fromkeys(component._get_all_custom_code()),
|
|
321
376
|
)
|
|
322
377
|
|
|
323
378
|
# Include all imports in the shared component.
|
|
@@ -53,9 +53,9 @@ def wait_for_client_redirect(component: Component) -> Component:
|
|
|
53
53
|
The conditionally rendered component.
|
|
54
54
|
"""
|
|
55
55
|
return cond(
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
56
|
+
route_not_found,
|
|
57
|
+
component,
|
|
58
|
+
ClientSideRouting.create(),
|
|
59
59
|
)
|
|
60
60
|
|
|
61
61
|
|
reflex/components/core/cond.py
CHANGED
|
@@ -31,7 +31,7 @@ class Cond(MemoizationLeaf):
|
|
|
31
31
|
cls,
|
|
32
32
|
cond: Var,
|
|
33
33
|
comp1: BaseComponent,
|
|
34
|
-
comp2: BaseComponent |
|
|
34
|
+
comp2: BaseComponent | types.Unset = types.Unset(),
|
|
35
35
|
) -> Component:
|
|
36
36
|
"""Create a conditional component.
|
|
37
37
|
|
|
@@ -44,10 +44,14 @@ class Cond(MemoizationLeaf):
|
|
|
44
44
|
The conditional component.
|
|
45
45
|
"""
|
|
46
46
|
# Wrap everything in fragments.
|
|
47
|
-
if type(comp1)
|
|
47
|
+
if type(comp1) is not Fragment:
|
|
48
48
|
comp1 = Fragment.create(comp1)
|
|
49
|
-
if comp2
|
|
50
|
-
comp2 =
|
|
49
|
+
if isinstance(comp2, types.Unset) or type(comp2) is not Fragment:
|
|
50
|
+
comp2 = (
|
|
51
|
+
Fragment.create(comp2)
|
|
52
|
+
if not isinstance(comp2, types.Unset)
|
|
53
|
+
else Fragment.create()
|
|
54
|
+
)
|
|
51
55
|
return Fragment.create(
|
|
52
56
|
cls._create(
|
|
53
57
|
children=[comp1, comp2],
|
|
@@ -96,18 +100,22 @@ class Cond(MemoizationLeaf):
|
|
|
96
100
|
|
|
97
101
|
|
|
98
102
|
@overload
|
|
99
|
-
def cond(condition: Any, c1: Component, c2: Any) -> Component: ... # pyright: ignore [reportOverlappingOverload]
|
|
103
|
+
def cond(condition: Any, c1: Component, c2: Any, /) -> Component: ... # pyright: ignore [reportOverlappingOverload]
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
@overload
|
|
107
|
+
def cond(condition: Any, c1: Component, /) -> Component: ...
|
|
100
108
|
|
|
101
109
|
|
|
102
110
|
@overload
|
|
103
|
-
def cond(condition: Any, c1: Component) -> Component: ...
|
|
111
|
+
def cond(condition: Any, c1: Any, c2: Component, /) -> Component: ... # pyright: ignore [reportOverlappingOverload]
|
|
104
112
|
|
|
105
113
|
|
|
106
114
|
@overload
|
|
107
|
-
def cond(condition: Any, c1: Any, c2: Any) -> Var: ...
|
|
115
|
+
def cond(condition: Any, c1: Any, c2: Any, /) -> Var: ...
|
|
108
116
|
|
|
109
117
|
|
|
110
|
-
def cond(condition: Any, c1: Any, c2: Any =
|
|
118
|
+
def cond(condition: Any, c1: Any, c2: Any = types.Unset(), /) -> Component | Var:
|
|
111
119
|
"""Create a conditional component or Prop.
|
|
112
120
|
|
|
113
121
|
Args:
|
|
@@ -128,15 +136,15 @@ def cond(condition: Any, c1: Any, c2: Any = None) -> Component | Var:
|
|
|
128
136
|
|
|
129
137
|
# If the first component is a component, create a Cond component.
|
|
130
138
|
if isinstance(c1, BaseComponent):
|
|
131
|
-
if c2
|
|
132
|
-
|
|
139
|
+
if not isinstance(c2, types.Unset) and not isinstance(c2, BaseComponent):
|
|
140
|
+
return Cond.create(cond_var.bool(), c1, Fragment.create(c2))
|
|
133
141
|
return Cond.create(cond_var.bool(), c1, c2)
|
|
134
142
|
|
|
135
143
|
# Otherwise, create a conditional Var.
|
|
136
144
|
# Check that the second argument is valid.
|
|
137
145
|
if isinstance(c2, BaseComponent):
|
|
138
|
-
|
|
139
|
-
if c2
|
|
146
|
+
return Cond.create(cond_var.bool(), Fragment.create(c1), c2)
|
|
147
|
+
if isinstance(c2, types.Unset):
|
|
140
148
|
raise ValueError("For conditional vars, the second argument must be set.")
|
|
141
149
|
|
|
142
150
|
# convert the truth and false cond parts into vars so the _var_data can be obtained.
|
reflex/components/core/upload.py
CHANGED
reflex/components/dynamic.py
CHANGED
|
@@ -72,13 +72,11 @@ def load_dynamic_serializer():
|
|
|
72
72
|
rendered_components = {}
|
|
73
73
|
# Include dynamic imports in the shared component.
|
|
74
74
|
if dynamic_imports := component._get_all_dynamic_imports():
|
|
75
|
-
rendered_components.update(
|
|
76
|
-
{dynamic_import: None for dynamic_import in dynamic_imports}
|
|
77
|
-
)
|
|
75
|
+
rendered_components.update(dict.fromkeys(dynamic_imports))
|
|
78
76
|
|
|
79
77
|
# Include custom code in the shared component.
|
|
80
78
|
rendered_components.update(
|
|
81
|
-
|
|
79
|
+
dict.fromkeys(component._get_all_custom_code()),
|
|
82
80
|
)
|
|
83
81
|
|
|
84
82
|
rendered_components[
|
reflex/components/lucide/icon.py
CHANGED
|
@@ -53,42 +53,35 @@ class Icon(LucideIconComponent):
|
|
|
53
53
|
if "tag" not in props:
|
|
54
54
|
raise AttributeError("Missing 'tag' keyword-argument for Icon")
|
|
55
55
|
|
|
56
|
-
|
|
57
|
-
if isinstance(
|
|
58
|
-
if isinstance(
|
|
59
|
-
tag =
|
|
56
|
+
tag_var: Var | LiteralVar = Var.create(props.pop("tag"))
|
|
57
|
+
if isinstance(tag_var, LiteralVar):
|
|
58
|
+
if isinstance(tag_var, LiteralStringVar):
|
|
59
|
+
tag = format.to_snake_case(tag_var._var_value.lower())
|
|
60
60
|
else:
|
|
61
|
-
raise TypeError(f"Icon name must be a string, got {type(
|
|
62
|
-
elif isinstance(
|
|
63
|
-
tag_stringified =
|
|
61
|
+
raise TypeError(f"Icon name must be a string, got {type(tag_var)}")
|
|
62
|
+
elif isinstance(tag_var, Var):
|
|
63
|
+
tag_stringified = tag_var.guess_type()
|
|
64
64
|
if not isinstance(tag_stringified, StringVar):
|
|
65
|
-
raise TypeError(f"Icon name must be a string, got {
|
|
65
|
+
raise TypeError(f"Icon name must be a string, got {tag_var._var_type}")
|
|
66
66
|
return DynamicIcon.create(name=tag_stringified.replace("_", "-"), **props)
|
|
67
67
|
|
|
68
|
-
if
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
tag, s
|
|
77
|
-
),
|
|
78
|
-
reverse=True,
|
|
79
|
-
)
|
|
80
|
-
else:
|
|
81
|
-
icons_sorted = LUCIDE_ICON_LIST
|
|
68
|
+
if tag not in LUCIDE_ICON_LIST:
|
|
69
|
+
icons_sorted = sorted(
|
|
70
|
+
LUCIDE_ICON_LIST,
|
|
71
|
+
key=lambda s, tag=tag: format.length_of_largest_common_substring(
|
|
72
|
+
tag, s
|
|
73
|
+
),
|
|
74
|
+
reverse=True,
|
|
75
|
+
)
|
|
82
76
|
console.warn(
|
|
83
77
|
f"Invalid icon tag: {tag}. Please use one of the following: {', '.join(icons_sorted[0:10])}, ..."
|
|
84
78
|
"\nSee full list at https://reflex.dev/docs/library/data-display/icon/#icons-list. Using 'circle-help' icon instead."
|
|
85
79
|
)
|
|
86
|
-
tag = "
|
|
80
|
+
tag = "circle_help"
|
|
87
81
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
props["tag"] = format.to_title_case(format.to_snake_case(tag)) + "Icon"
|
|
82
|
+
props["tag"] = LUCIDE_ICON_MAPPING_OVERRIDE.get(
|
|
83
|
+
tag, format.to_title_case(tag) + "Icon"
|
|
84
|
+
)
|
|
92
85
|
props["alias"] = f"Lucide{props['tag']}"
|
|
93
86
|
props.setdefault("color", "var(--current-color)")
|
|
94
87
|
return super().create(**props)
|
|
@@ -71,7 +71,7 @@ class Plotly(NoSSRComponent):
|
|
|
71
71
|
|
|
72
72
|
library = "react-plotly.js@2.6.0"
|
|
73
73
|
|
|
74
|
-
lib_dependencies: list[str] = ["plotly.js@
|
|
74
|
+
lib_dependencies: list[str] = ["plotly.js@3.0.1"]
|
|
75
75
|
|
|
76
76
|
tag = "Plot"
|
|
77
77
|
|
|
@@ -289,7 +289,7 @@ class PlotlyBasic(Plotly):
|
|
|
289
289
|
|
|
290
290
|
library = "react-plotly.js@2.6.0"
|
|
291
291
|
|
|
292
|
-
lib_dependencies: list[str] = ["plotly.js-basic-dist-min@3.0.
|
|
292
|
+
lib_dependencies: list[str] = ["plotly.js-basic-dist-min@3.0.1"]
|
|
293
293
|
|
|
294
294
|
def add_imports(self) -> ImportDict | list[ImportDict]:
|
|
295
295
|
"""Add imports for the plotly basic component.
|
|
@@ -315,7 +315,7 @@ class PlotlyCartesian(Plotly):
|
|
|
315
315
|
|
|
316
316
|
library = "react-plotly.js@2.6.0"
|
|
317
317
|
|
|
318
|
-
lib_dependencies: list[str] = ["plotly.js-cartesian-dist-min@3.0.
|
|
318
|
+
lib_dependencies: list[str] = ["plotly.js-cartesian-dist-min@3.0.1"]
|
|
319
319
|
|
|
320
320
|
def add_imports(self) -> ImportDict | list[ImportDict]:
|
|
321
321
|
"""Add imports for the plotly cartesian component.
|
|
@@ -341,7 +341,7 @@ class PlotlyGeo(Plotly):
|
|
|
341
341
|
|
|
342
342
|
library = "react-plotly.js@2.6.0"
|
|
343
343
|
|
|
344
|
-
lib_dependencies: list[str] = ["plotly.js-geo-dist-min@3.0.
|
|
344
|
+
lib_dependencies: list[str] = ["plotly.js-geo-dist-min@3.0.1"]
|
|
345
345
|
|
|
346
346
|
def add_imports(self) -> ImportDict | list[ImportDict]:
|
|
347
347
|
"""Add imports for the plotly geo component.
|
|
@@ -367,7 +367,7 @@ class PlotlyGl3d(Plotly):
|
|
|
367
367
|
|
|
368
368
|
library = "react-plotly.js@2.6.0"
|
|
369
369
|
|
|
370
|
-
lib_dependencies: list[str] = ["plotly.js-gl3d-dist-min@3.0.
|
|
370
|
+
lib_dependencies: list[str] = ["plotly.js-gl3d-dist-min@3.0.1"]
|
|
371
371
|
|
|
372
372
|
def add_imports(self) -> ImportDict | list[ImportDict]:
|
|
373
373
|
"""Add imports for the plotly 3d component.
|
|
@@ -393,7 +393,7 @@ class PlotlyGl2d(Plotly):
|
|
|
393
393
|
|
|
394
394
|
library = "react-plotly.js@2.6.0"
|
|
395
395
|
|
|
396
|
-
lib_dependencies: list[str] = ["plotly.js-gl2d-dist-min@3.0.
|
|
396
|
+
lib_dependencies: list[str] = ["plotly.js-gl2d-dist-min@3.0.1"]
|
|
397
397
|
|
|
398
398
|
def add_imports(self) -> ImportDict | list[ImportDict]:
|
|
399
399
|
"""Add imports for the plotly 2d component.
|
|
@@ -419,7 +419,7 @@ class PlotlyMapbox(Plotly):
|
|
|
419
419
|
|
|
420
420
|
library = "react-plotly.js@2.6.0"
|
|
421
421
|
|
|
422
|
-
lib_dependencies: list[str] = ["plotly.js-mapbox-dist-min@3.0.
|
|
422
|
+
lib_dependencies: list[str] = ["plotly.js-mapbox-dist-min@3.0.1"]
|
|
423
423
|
|
|
424
424
|
def add_imports(self) -> ImportDict | list[ImportDict]:
|
|
425
425
|
"""Add imports for the plotly mapbox component.
|
|
@@ -445,7 +445,7 @@ class PlotlyFinance(Plotly):
|
|
|
445
445
|
|
|
446
446
|
library = "react-plotly.js@2.6.0"
|
|
447
447
|
|
|
448
|
-
lib_dependencies: list[str] = ["plotly.js-finance-dist-min@3.0.
|
|
448
|
+
lib_dependencies: list[str] = ["plotly.js-finance-dist-min@3.0.1"]
|
|
449
449
|
|
|
450
450
|
def add_imports(self) -> ImportDict | list[ImportDict]:
|
|
451
451
|
"""Add imports for the plotly finance component.
|
|
@@ -471,7 +471,7 @@ class PlotlyStrict(Plotly):
|
|
|
471
471
|
|
|
472
472
|
library = "react-plotly.js@2.6.0"
|
|
473
473
|
|
|
474
|
-
lib_dependencies: list[str] = ["plotly.js-strict-dist-min@3.0.
|
|
474
|
+
lib_dependencies: list[str] = ["plotly.js-strict-dist-min@3.0.1"]
|
|
475
475
|
|
|
476
476
|
def add_imports(self) -> ImportDict | list[ImportDict]:
|
|
477
477
|
"""Add imports for the plotly strict component.
|
|
@@ -8,7 +8,7 @@ from reflex.components.component import Component, MemoizationLeaf, NoSSRCompone
|
|
|
8
8
|
class Recharts(Component):
|
|
9
9
|
"""A component that wraps a recharts lib."""
|
|
10
10
|
|
|
11
|
-
library = "recharts@2.15.
|
|
11
|
+
library = "recharts@2.15.1"
|
|
12
12
|
|
|
13
13
|
def _get_style(self) -> dict:
|
|
14
14
|
return {"wrapperStyle": self.style}
|
|
@@ -17,7 +17,7 @@ class Recharts(Component):
|
|
|
17
17
|
class RechartsCharts(NoSSRComponent, MemoizationLeaf):
|
|
18
18
|
"""A component that wraps a recharts lib."""
|
|
19
19
|
|
|
20
|
-
library = "recharts@2.15.
|
|
20
|
+
library = "recharts@2.15.1"
|
|
21
21
|
|
|
22
22
|
|
|
23
23
|
LiteralAnimationEasing = Literal["ease", "ease-in", "ease-out", "ease-in-out", "linear"]
|
|
@@ -172,7 +172,7 @@ class ToastProps(PropsBase, NoExtrasAllowedProps):
|
|
|
172
172
|
class Toaster(Component):
|
|
173
173
|
"""A Toaster Component for displaying toast notifications."""
|
|
174
174
|
|
|
175
|
-
library: str | None = "sonner@
|
|
175
|
+
library: str | None = "sonner@2.0.1"
|
|
176
176
|
|
|
177
177
|
tag = "Toaster"
|
|
178
178
|
|
reflex/config.py
CHANGED
|
@@ -30,7 +30,6 @@ from typing import (
|
|
|
30
30
|
)
|
|
31
31
|
|
|
32
32
|
import pydantic.v1 as pydantic
|
|
33
|
-
from reflex_cli.constants.hosting import Hosting
|
|
34
33
|
|
|
35
34
|
from reflex import constants
|
|
36
35
|
from reflex.base import Base
|
|
@@ -596,13 +595,13 @@ class EnvironmentVariables:
|
|
|
596
595
|
constants.CompileContext.UNDEFINED, internal=True
|
|
597
596
|
)
|
|
598
597
|
|
|
599
|
-
# Whether to use npm over bun to install frontend
|
|
598
|
+
# Whether to use npm over bun to install and run the frontend.
|
|
600
599
|
REFLEX_USE_NPM: EnvVar[bool] = env_var(False)
|
|
601
600
|
|
|
602
601
|
# The npm registry to use.
|
|
603
602
|
NPM_CONFIG_REGISTRY: EnvVar[str | None] = env_var(None)
|
|
604
603
|
|
|
605
|
-
# Whether to use Granian for the backend.
|
|
604
|
+
# Whether to use Granian for the backend. By default, the backend uses Uvicorn if available.
|
|
606
605
|
REFLEX_USE_GRANIAN: EnvVar[bool] = env_var(False)
|
|
607
606
|
|
|
608
607
|
# The username to use for authentication on python package repository. Username and password must both be provided.
|
|
@@ -614,9 +613,6 @@ class EnvironmentVariables:
|
|
|
614
613
|
# Whether to use the system installed bun. If set to false, bun will be bundled with the app.
|
|
615
614
|
REFLEX_USE_SYSTEM_BUN: EnvVar[bool] = env_var(False)
|
|
616
615
|
|
|
617
|
-
# Whether to use the system installed node and npm. If set to false, node and npm will be bundled with the app.
|
|
618
|
-
REFLEX_USE_SYSTEM_NODE: EnvVar[bool] = env_var(False)
|
|
619
|
-
|
|
620
616
|
# The working directory for the next.js commands.
|
|
621
617
|
REFLEX_WEB_WORKDIR: EnvVar[Path] = env_var(Path(constants.Dirs.WEB))
|
|
622
618
|
|
|
@@ -810,8 +806,8 @@ class Config(Base):
|
|
|
810
806
|
# Tailwind config.
|
|
811
807
|
tailwind: dict[str, Any] | None = {"plugins": ["@tailwindcss/typography"]}
|
|
812
808
|
|
|
813
|
-
# Timeout when launching the gunicorn server.
|
|
814
|
-
timeout: int =
|
|
809
|
+
# DEPRECATED. Timeout when launching the gunicorn server.
|
|
810
|
+
timeout: int | None = None
|
|
815
811
|
|
|
816
812
|
# Whether to enable or disable nextJS gzip compression.
|
|
817
813
|
next_compression: bool = True
|
|
@@ -822,22 +818,17 @@ class Config(Base):
|
|
|
822
818
|
# Additional frontend packages to install.
|
|
823
819
|
frontend_packages: list[str] = []
|
|
824
820
|
|
|
825
|
-
# The
|
|
826
|
-
cp_backend_url: str = Hosting.HOSTING_SERVICE
|
|
827
|
-
# The hosting service frontend URL.
|
|
828
|
-
cp_web_url: str = Hosting.HOSTING_SERVICE_UI
|
|
829
|
-
|
|
830
|
-
# The worker class used in production mode
|
|
821
|
+
# DEPRECATED. The worker class used in production mode
|
|
831
822
|
gunicorn_worker_class: str = "uvicorn.workers.UvicornH11Worker"
|
|
832
823
|
|
|
833
|
-
# Number of gunicorn workers from user
|
|
824
|
+
# DEPRECATED. Number of gunicorn workers from user
|
|
834
825
|
gunicorn_workers: int | None = None
|
|
835
826
|
|
|
836
|
-
# Number of requests before a worker is restarted; set to 0 to disable
|
|
837
|
-
gunicorn_max_requests: int =
|
|
827
|
+
# DEPRECATED. Number of requests before a worker is restarted; set to 0 to disable
|
|
828
|
+
gunicorn_max_requests: int | None = None
|
|
838
829
|
|
|
839
|
-
# Variance limit for max requests; gunicorn only
|
|
840
|
-
gunicorn_max_requests_jitter: int =
|
|
830
|
+
# DEPRECATED. Variance limit for max requests; gunicorn only
|
|
831
|
+
gunicorn_max_requests_jitter: int | None = None
|
|
841
832
|
|
|
842
833
|
# Indicate which type of state manager to use
|
|
843
834
|
state_manager_mode: constants.StateManagerMode = constants.StateManagerMode.DISK
|
|
@@ -941,8 +932,14 @@ class Config(Base):
|
|
|
941
932
|
"""The `python-dotenv` package is required to load environment variables from a file. Run `pip install "python-dotenv>=1.0.1"`."""
|
|
942
933
|
)
|
|
943
934
|
else:
|
|
944
|
-
# load env
|
|
945
|
-
|
|
935
|
+
# load env files in reverse order if they exist
|
|
936
|
+
for env_file_path in [
|
|
937
|
+
Path(p)
|
|
938
|
+
for s in reversed(env_file.split(os.pathsep))
|
|
939
|
+
if (p := s.strip())
|
|
940
|
+
]:
|
|
941
|
+
if env_file_path.exists():
|
|
942
|
+
load_dotenv(env_file_path, override=True)
|
|
946
943
|
|
|
947
944
|
updated_values = {}
|
|
948
945
|
# Iterate over the fields.
|
|
@@ -964,7 +961,7 @@ class Config(Base):
|
|
|
964
961
|
env_var = "***"
|
|
965
962
|
|
|
966
963
|
if value != getattr(self, key):
|
|
967
|
-
console.
|
|
964
|
+
console.debug(
|
|
968
965
|
f"Overriding config value {key} with env var {key.upper()}={env_var}",
|
|
969
966
|
dedupe=True,
|
|
970
967
|
)
|
reflex/constants/__init__.py
CHANGED
|
@@ -45,7 +45,7 @@ from .config import (
|
|
|
45
45
|
)
|
|
46
46
|
from .custom_components import CustomComponents
|
|
47
47
|
from .event import Endpoint, EventTriggers, SocketEvent
|
|
48
|
-
from .installer import Bun,
|
|
48
|
+
from .installer import Bun, Node, PackageJson
|
|
49
49
|
from .route import (
|
|
50
50
|
ROUTE_NOT_FOUND,
|
|
51
51
|
ROUTER,
|
|
@@ -94,7 +94,6 @@ __all__ = [
|
|
|
94
94
|
"EventTriggers",
|
|
95
95
|
"Expiration",
|
|
96
96
|
"Ext",
|
|
97
|
-
"Fnm",
|
|
98
97
|
"GitIgnore",
|
|
99
98
|
"Hooks",
|
|
100
99
|
"Imports",
|
reflex/constants/base.py
CHANGED
|
@@ -88,6 +88,9 @@ class Reflex(SimpleNamespace):
|
|
|
88
88
|
|
|
89
89
|
RELEASES_URL = "https://api.github.com/repos/reflex-dev/templates/releases"
|
|
90
90
|
|
|
91
|
+
# The reflex stylesheet language supported
|
|
92
|
+
STYLESHEETS_SUPPORTED = ["css", "sass", "scss"]
|
|
93
|
+
|
|
91
94
|
|
|
92
95
|
class ReflexHostingCLI(SimpleNamespace):
|
|
93
96
|
"""Base constants concerning Reflex Hosting CLI."""
|