reflex 0.6.4a2__py3-none-any.whl → 0.6.5__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of reflex might be problematic. Click here for more details.
- reflex/.templates/jinja/web/pages/custom_component.js.jinja2 +0 -14
- reflex/.templates/jinja/web/pages/utils.js.jinja2 +4 -8
- reflex/.templates/web/components/shiki/code.js +16 -11
- reflex/.templates/web/utils/state.js +29 -21
- reflex/__init__.py +4 -0
- reflex/__init__.pyi +4 -0
- reflex/app.py +148 -154
- reflex/app_mixins/lifespan.py +5 -1
- reflex/app_mixins/middleware.py +3 -1
- reflex/app_mixins/mixin.py +3 -2
- reflex/base.py +2 -4
- reflex/compiler/compiler.py +111 -37
- reflex/components/base/app_wrap.pyi +17 -17
- reflex/components/base/bare.py +72 -3
- reflex/components/base/body.pyi +17 -17
- reflex/components/base/document.pyi +81 -81
- reflex/components/base/error_boundary.pyi +25 -18
- reflex/components/base/fragment.pyi +17 -17
- reflex/components/base/head.pyi +33 -33
- reflex/components/base/link.pyi +33 -33
- reflex/components/base/meta.pyi +65 -65
- reflex/components/base/script.py +4 -4
- reflex/components/base/script.pyi +23 -20
- reflex/components/component.py +250 -31
- reflex/components/core/banner.py +1 -1
- reflex/components/core/banner.pyi +81 -81
- reflex/components/core/client_side_routing.pyi +33 -33
- reflex/components/core/clipboard.py +2 -2
- reflex/components/core/clipboard.pyi +24 -18
- reflex/components/core/debounce.py +2 -2
- reflex/components/core/debounce.pyi +18 -18
- reflex/components/core/html.pyi +17 -17
- reflex/components/core/upload.py +90 -28
- reflex/components/core/upload.pyi +128 -72
- reflex/components/datadisplay/code.py +55 -40
- reflex/components/datadisplay/code.pyi +46 -44
- reflex/components/datadisplay/dataeditor.py +21 -20
- reflex/components/datadisplay/dataeditor.pyi +103 -35
- reflex/components/datadisplay/shiki_code_block.py +60 -27
- reflex/components/datadisplay/shiki_code_block.pyi +86 -65
- reflex/components/dynamic.py +9 -5
- reflex/components/el/element.pyi +17 -17
- reflex/components/el/elements/base.pyi +17 -17
- reflex/components/el/elements/forms.py +12 -3
- reflex/components/el/elements/forms.pyi +293 -233
- reflex/components/el/elements/inline.pyi +449 -449
- reflex/components/el/elements/media.pyi +401 -401
- reflex/components/el/elements/metadata.pyi +97 -97
- reflex/components/el/elements/other.pyi +113 -113
- reflex/components/el/elements/scripts.pyi +49 -49
- reflex/components/el/elements/sectioning.pyi +241 -241
- reflex/components/el/elements/tables.pyi +161 -161
- reflex/components/el/elements/typography.pyi +241 -241
- reflex/components/gridjs/datatable.pyi +33 -33
- reflex/components/lucide/icon.py +1 -1
- reflex/components/lucide/icon.pyi +33 -33
- reflex/components/markdown/markdown.py +180 -49
- reflex/components/markdown/markdown.pyi +36 -19
- reflex/components/moment/moment.py +17 -21
- reflex/components/moment/moment.pyi +26 -21
- reflex/components/next/base.pyi +17 -17
- reflex/components/next/image.py +3 -3
- reflex/components/next/image.pyi +21 -19
- reflex/components/next/link.pyi +17 -17
- reflex/components/next/video.pyi +17 -17
- reflex/components/plotly/plotly.py +79 -78
- reflex/components/plotly/plotly.pyi +91 -41
- reflex/components/props.py +34 -0
- reflex/components/radix/primitives/accordion.py +15 -8
- reflex/components/radix/primitives/accordion.pyi +121 -118
- reflex/components/radix/primitives/base.pyi +33 -33
- reflex/components/radix/primitives/drawer.py +41 -20
- reflex/components/radix/primitives/drawer.pyi +279 -190
- reflex/components/radix/primitives/form.py +2 -2
- reflex/components/radix/primitives/form.pyi +200 -167
- reflex/components/radix/primitives/progress.pyi +81 -81
- reflex/components/radix/primitives/slider.pyi +89 -83
- reflex/components/radix/themes/base.py +30 -1
- reflex/components/radix/themes/base.pyi +286 -113
- reflex/components/radix/themes/color_mode.py +17 -9
- reflex/components/radix/themes/color_mode.pyi +68 -56
- reflex/components/radix/themes/components/alert_dialog.py +8 -5
- reflex/components/radix/themes/components/alert_dialog.pyi +125 -117
- reflex/components/radix/themes/components/aspect_ratio.pyi +17 -17
- reflex/components/radix/themes/components/avatar.py +1 -5
- reflex/components/radix/themes/components/avatar.pyi +17 -17
- reflex/components/radix/themes/components/badge.py +1 -5
- reflex/components/radix/themes/components/badge.pyi +17 -17
- reflex/components/radix/themes/components/button.pyi +18 -21
- reflex/components/radix/themes/components/callout.py +1 -4
- reflex/components/radix/themes/components/callout.pyi +81 -81
- reflex/components/radix/themes/components/card.py +1 -3
- reflex/components/radix/themes/components/card.pyi +17 -17
- reflex/components/radix/themes/components/checkbox.py +4 -8
- reflex/components/radix/themes/components/checkbox.pyi +61 -52
- reflex/components/radix/themes/components/checkbox_cards.pyi +33 -33
- reflex/components/radix/themes/components/checkbox_group.pyi +33 -33
- reflex/components/radix/themes/components/context_menu.py +121 -28
- reflex/components/radix/themes/components/context_menu.pyi +250 -147
- reflex/components/radix/themes/components/data_list.pyi +65 -65
- reflex/components/radix/themes/components/dialog.py +11 -11
- reflex/components/radix/themes/components/dialog.pyi +135 -120
- reflex/components/radix/themes/components/dropdown_menu.py +14 -25
- reflex/components/radix/themes/components/dropdown_menu.pyi +157 -145
- reflex/components/radix/themes/components/hover_card.py +19 -7
- reflex/components/radix/themes/components/hover_card.pyi +102 -67
- reflex/components/radix/themes/components/icon_button.pyi +18 -21
- reflex/components/radix/themes/components/inset.py +1 -3
- reflex/components/radix/themes/components/inset.pyi +17 -17
- reflex/components/radix/themes/components/popover.py +22 -13
- reflex/components/radix/themes/components/popover.pyi +98 -72
- reflex/components/radix/themes/components/progress.pyi +17 -17
- reflex/components/radix/themes/components/radio.pyi +17 -17
- reflex/components/radix/themes/components/radio_cards.py +2 -2
- reflex/components/radix/themes/components/radio_cards.pyi +37 -34
- reflex/components/radix/themes/components/radio_group.py +3 -7
- reflex/components/radix/themes/components/radio_group.pyi +69 -66
- reflex/components/radix/themes/components/scroll_area.py +1 -3
- reflex/components/radix/themes/components/scroll_area.pyi +17 -17
- reflex/components/radix/themes/components/segmented_control.pyi +37 -34
- reflex/components/radix/themes/components/select.py +7 -11
- reflex/components/radix/themes/components/select.pyi +175 -154
- reflex/components/radix/themes/components/separator.py +1 -4
- reflex/components/radix/themes/components/separator.pyi +17 -17
- reflex/components/radix/themes/components/skeleton.pyi +17 -17
- reflex/components/radix/themes/components/slider.py +12 -21
- reflex/components/radix/themes/components/slider.pyi +47 -25
- reflex/components/radix/themes/components/spinner.py +1 -4
- reflex/components/radix/themes/components/spinner.pyi +17 -17
- reflex/components/radix/themes/components/switch.py +3 -6
- reflex/components/radix/themes/components/switch.pyi +21 -18
- reflex/components/radix/themes/components/table.py +21 -5
- reflex/components/radix/themes/components/table.pyi +392 -116
- reflex/components/radix/themes/components/tabs.py +3 -6
- reflex/components/radix/themes/components/tabs.pyi +89 -83
- reflex/components/radix/themes/components/text_area.py +1 -5
- reflex/components/radix/themes/components/text_area.pyi +43 -20
- reflex/components/radix/themes/components/text_field.py +1 -5
- reflex/components/radix/themes/components/text_field.pyi +101 -55
- reflex/components/radix/themes/components/tooltip.py +5 -7
- reflex/components/radix/themes/components/tooltip.pyi +25 -22
- reflex/components/radix/themes/layout/base.py +2 -27
- reflex/components/radix/themes/layout/base.pyi +82 -82
- reflex/components/radix/themes/layout/box.pyi +17 -17
- reflex/components/radix/themes/layout/center.pyi +17 -17
- reflex/components/radix/themes/layout/container.pyi +17 -17
- reflex/components/radix/themes/layout/flex.py +1 -6
- reflex/components/radix/themes/layout/flex.pyi +17 -17
- reflex/components/radix/themes/layout/grid.py +1 -6
- reflex/components/radix/themes/layout/grid.pyi +17 -17
- reflex/components/radix/themes/layout/list.py +20 -15
- reflex/components/radix/themes/layout/list.pyi +175 -92
- reflex/components/radix/themes/layout/section.pyi +17 -17
- reflex/components/radix/themes/layout/spacer.pyi +17 -17
- reflex/components/radix/themes/layout/stack.py +6 -6
- reflex/components/radix/themes/layout/stack.pyi +91 -62
- reflex/components/radix/themes/typography/blockquote.py +2 -8
- reflex/components/radix/themes/typography/blockquote.pyi +17 -17
- reflex/components/radix/themes/typography/code.py +4 -10
- reflex/components/radix/themes/typography/code.pyi +19 -18
- reflex/components/radix/themes/typography/heading.py +4 -11
- reflex/components/radix/themes/typography/heading.pyi +19 -18
- reflex/components/radix/themes/typography/link.py +4 -10
- reflex/components/radix/themes/typography/link.pyi +19 -18
- reflex/components/radix/themes/typography/text.py +4 -11
- reflex/components/radix/themes/typography/text.pyi +115 -114
- reflex/components/react_player/audio.pyi +58 -33
- reflex/components/react_player/react_player.py +17 -17
- reflex/components/react_player/react_player.pyi +55 -33
- reflex/components/react_player/video.pyi +58 -33
- reflex/components/recharts/cartesian.py +45 -45
- reflex/components/recharts/cartesian.pyi +389 -304
- reflex/components/recharts/charts.py +22 -22
- reflex/components/recharts/charts.pyi +226 -179
- reflex/components/recharts/general.py +26 -27
- reflex/components/recharts/general.pyi +106 -99
- reflex/components/recharts/polar.py +33 -33
- reflex/components/recharts/polar.pyi +70 -64
- reflex/components/recharts/recharts.pyi +33 -33
- reflex/components/sonner/toast.py +9 -36
- reflex/components/sonner/toast.pyi +20 -24
- reflex/components/suneditor/editor.py +8 -8
- reflex/components/suneditor/editor.pyi +50 -25
- reflex/components/tags/iter_tag.py +1 -10
- reflex/components/tags/tag.py +1 -4
- reflex/config.py +252 -41
- reflex/constants/__init__.py +4 -16
- reflex/constants/base.py +7 -14
- reflex/constants/colors.py +0 -1
- reflex/constants/installer.py +12 -7
- reflex/constants/state.py +4 -0
- reflex/custom_components/custom_components.py +6 -6
- reflex/event.py +486 -241
- reflex/experimental/client_state.py +9 -9
- reflex/experimental/layout.py +2 -2
- reflex/experimental/layout.pyi +95 -87
- reflex/experimental/misc.py +1 -1
- reflex/istate/__init__.py +1 -0
- reflex/istate/proxy.py +33 -0
- reflex/istate/wrappers.py +27 -0
- reflex/model.py +7 -7
- reflex/page.py +2 -1
- reflex/reflex.py +142 -8
- reflex/state.py +133 -46
- reflex/testing.py +9 -7
- reflex/utils/console.py +0 -1
- reflex/utils/exceptions.py +31 -3
- reflex/utils/exec.py +33 -14
- reflex/utils/format.py +15 -12
- reflex/utils/net.py +1 -1
- reflex/utils/path_ops.py +2 -2
- reflex/utils/prerequisites.py +82 -46
- reflex/utils/pyi_generator.py +63 -20
- reflex/utils/registry.py +1 -1
- reflex/utils/serializers.py +75 -36
- reflex/utils/telemetry.py +3 -2
- reflex/utils/types.py +125 -10
- reflex/vars/base.py +131 -119
- reflex/vars/function.py +59 -12
- reflex/vars/number.py +3 -1
- reflex/vars/object.py +30 -24
- reflex/vars/sequence.py +7 -7
- {reflex-0.6.4a2.dist-info → reflex-0.6.5.dist-info}/METADATA +3 -3
- reflex-0.6.5.dist-info/RECORD +394 -0
- reflex-0.6.4a2.dist-info/RECORD +0 -391
- {reflex-0.6.4a2.dist-info → reflex-0.6.5.dist-info}/LICENSE +0 -0
- {reflex-0.6.4a2.dist-info → reflex-0.6.5.dist-info}/WHEEL +0 -0
- {reflex-0.6.4a2.dist-info → reflex-0.6.5.dist-info}/entry_points.txt +0 -0
reflex/config.py
CHANGED
|
@@ -3,14 +3,26 @@
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
5
|
import dataclasses
|
|
6
|
+
import enum
|
|
6
7
|
import importlib
|
|
8
|
+
import inspect
|
|
7
9
|
import os
|
|
8
10
|
import sys
|
|
9
11
|
import urllib.parse
|
|
10
12
|
from pathlib import Path
|
|
11
|
-
from typing import
|
|
12
|
-
|
|
13
|
-
|
|
13
|
+
from typing import (
|
|
14
|
+
TYPE_CHECKING,
|
|
15
|
+
Any,
|
|
16
|
+
Dict,
|
|
17
|
+
Generic,
|
|
18
|
+
List,
|
|
19
|
+
Optional,
|
|
20
|
+
Set,
|
|
21
|
+
TypeVar,
|
|
22
|
+
get_args,
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
from typing_extensions import Annotated, get_type_hints
|
|
14
26
|
|
|
15
27
|
from reflex.utils.exceptions import ConfigError, EnvironmentVarValueError
|
|
16
28
|
from reflex.utils.types import GenericType, is_union, value_inside_optional
|
|
@@ -202,8 +214,8 @@ def interpret_int_env(value: str, field_name: str) -> int:
|
|
|
202
214
|
) from ve
|
|
203
215
|
|
|
204
216
|
|
|
205
|
-
def
|
|
206
|
-
"""Interpret a path environment variable value.
|
|
217
|
+
def interpret_existing_path_env(value: str, field_name: str) -> ExistingPath:
|
|
218
|
+
"""Interpret a path environment variable value as an existing path.
|
|
207
219
|
|
|
208
220
|
Args:
|
|
209
221
|
value: The environment variable value.
|
|
@@ -221,6 +233,41 @@ def interpret_path_env(value: str, field_name: str) -> Path:
|
|
|
221
233
|
return path
|
|
222
234
|
|
|
223
235
|
|
|
236
|
+
def interpret_path_env(value: str, field_name: str) -> Path:
|
|
237
|
+
"""Interpret a path environment variable value.
|
|
238
|
+
|
|
239
|
+
Args:
|
|
240
|
+
value: The environment variable value.
|
|
241
|
+
field_name: The field name.
|
|
242
|
+
|
|
243
|
+
Returns:
|
|
244
|
+
The interpreted value.
|
|
245
|
+
"""
|
|
246
|
+
return Path(value)
|
|
247
|
+
|
|
248
|
+
|
|
249
|
+
def interpret_enum_env(value: str, field_type: GenericType, field_name: str) -> Any:
|
|
250
|
+
"""Interpret an enum environment variable value.
|
|
251
|
+
|
|
252
|
+
Args:
|
|
253
|
+
value: The environment variable value.
|
|
254
|
+
field_type: The field type.
|
|
255
|
+
field_name: The field name.
|
|
256
|
+
|
|
257
|
+
Returns:
|
|
258
|
+
The interpreted value.
|
|
259
|
+
|
|
260
|
+
Raises:
|
|
261
|
+
EnvironmentVarValueError: If the value is invalid.
|
|
262
|
+
"""
|
|
263
|
+
try:
|
|
264
|
+
return field_type(value)
|
|
265
|
+
except ValueError as ve:
|
|
266
|
+
raise EnvironmentVarValueError(
|
|
267
|
+
f"Invalid enum value: {value} for {field_name}"
|
|
268
|
+
) from ve
|
|
269
|
+
|
|
270
|
+
|
|
224
271
|
def interpret_env_var_value(
|
|
225
272
|
value: str, field_type: GenericType, field_name: str
|
|
226
273
|
) -> Any:
|
|
@@ -252,6 +299,10 @@ def interpret_env_var_value(
|
|
|
252
299
|
return interpret_int_env(value, field_name)
|
|
253
300
|
elif field_type is Path:
|
|
254
301
|
return interpret_path_env(value, field_name)
|
|
302
|
+
elif field_type is ExistingPath:
|
|
303
|
+
return interpret_existing_path_env(value, field_name)
|
|
304
|
+
elif inspect.isclass(field_type) and issubclass(field_type, enum.Enum):
|
|
305
|
+
return interpret_enum_env(value, field_type, field_name)
|
|
255
306
|
|
|
256
307
|
else:
|
|
257
308
|
raise ValueError(
|
|
@@ -259,83 +310,240 @@ def interpret_env_var_value(
|
|
|
259
310
|
)
|
|
260
311
|
|
|
261
312
|
|
|
262
|
-
|
|
313
|
+
T = TypeVar("T")
|
|
314
|
+
|
|
315
|
+
|
|
316
|
+
class EnvVar(Generic[T]):
|
|
317
|
+
"""Environment variable."""
|
|
318
|
+
|
|
319
|
+
name: str
|
|
320
|
+
default: Any
|
|
321
|
+
type_: T
|
|
322
|
+
|
|
323
|
+
def __init__(self, name: str, default: Any, type_: T) -> None:
|
|
324
|
+
"""Initialize the environment variable.
|
|
325
|
+
|
|
326
|
+
Args:
|
|
327
|
+
name: The environment variable name.
|
|
328
|
+
default: The default value.
|
|
329
|
+
type_: The type of the value.
|
|
330
|
+
"""
|
|
331
|
+
self.name = name
|
|
332
|
+
self.default = default
|
|
333
|
+
self.type_ = type_
|
|
334
|
+
|
|
335
|
+
def interpret(self, value: str) -> T:
|
|
336
|
+
"""Interpret the environment variable value.
|
|
337
|
+
|
|
338
|
+
Args:
|
|
339
|
+
value: The environment variable value.
|
|
340
|
+
|
|
341
|
+
Returns:
|
|
342
|
+
The interpreted value.
|
|
343
|
+
"""
|
|
344
|
+
return interpret_env_var_value(value, self.type_, self.name)
|
|
345
|
+
|
|
346
|
+
def getenv(self) -> Optional[T]:
|
|
347
|
+
"""Get the interpreted environment variable value.
|
|
348
|
+
|
|
349
|
+
Returns:
|
|
350
|
+
The environment variable value.
|
|
351
|
+
"""
|
|
352
|
+
env_value = os.getenv(self.name, None)
|
|
353
|
+
if env_value is not None:
|
|
354
|
+
return self.interpret(env_value)
|
|
355
|
+
return None
|
|
356
|
+
|
|
357
|
+
def is_set(self) -> bool:
|
|
358
|
+
"""Check if the environment variable is set.
|
|
359
|
+
|
|
360
|
+
Returns:
|
|
361
|
+
True if the environment variable is set.
|
|
362
|
+
"""
|
|
363
|
+
return self.name in os.environ
|
|
364
|
+
|
|
365
|
+
def get(self) -> T:
|
|
366
|
+
"""Get the interpreted environment variable value or the default value if not set.
|
|
367
|
+
|
|
368
|
+
Returns:
|
|
369
|
+
The interpreted value.
|
|
370
|
+
"""
|
|
371
|
+
env_value = self.getenv()
|
|
372
|
+
if env_value is not None:
|
|
373
|
+
return env_value
|
|
374
|
+
return self.default
|
|
375
|
+
|
|
376
|
+
def set(self, value: T | None) -> None:
|
|
377
|
+
"""Set the environment variable. None unsets the variable.
|
|
378
|
+
|
|
379
|
+
Args:
|
|
380
|
+
value: The value to set.
|
|
381
|
+
"""
|
|
382
|
+
if value is None:
|
|
383
|
+
_ = os.environ.pop(self.name, None)
|
|
384
|
+
else:
|
|
385
|
+
if isinstance(value, enum.Enum):
|
|
386
|
+
value = value.value
|
|
387
|
+
os.environ[self.name] = str(value)
|
|
388
|
+
|
|
389
|
+
|
|
390
|
+
class env_var: # type: ignore
|
|
391
|
+
"""Descriptor for environment variables."""
|
|
392
|
+
|
|
393
|
+
name: str
|
|
394
|
+
default: Any
|
|
395
|
+
internal: bool = False
|
|
396
|
+
|
|
397
|
+
def __init__(self, default: Any, internal: bool = False) -> None:
|
|
398
|
+
"""Initialize the descriptor.
|
|
399
|
+
|
|
400
|
+
Args:
|
|
401
|
+
default: The default value.
|
|
402
|
+
internal: Whether the environment variable is reflex internal.
|
|
403
|
+
"""
|
|
404
|
+
self.default = default
|
|
405
|
+
self.internal = internal
|
|
406
|
+
|
|
407
|
+
def __set_name__(self, owner, name):
|
|
408
|
+
"""Set the name of the descriptor.
|
|
409
|
+
|
|
410
|
+
Args:
|
|
411
|
+
owner: The owner class.
|
|
412
|
+
name: The name of the descriptor.
|
|
413
|
+
"""
|
|
414
|
+
self.name = name
|
|
415
|
+
|
|
416
|
+
def __get__(self, instance, owner):
|
|
417
|
+
"""Get the EnvVar instance.
|
|
418
|
+
|
|
419
|
+
Args:
|
|
420
|
+
instance: The instance.
|
|
421
|
+
owner: The owner class.
|
|
422
|
+
|
|
423
|
+
Returns:
|
|
424
|
+
The EnvVar instance.
|
|
425
|
+
"""
|
|
426
|
+
type_ = get_args(get_type_hints(owner)[self.name])[0]
|
|
427
|
+
env_name = self.name
|
|
428
|
+
if self.internal:
|
|
429
|
+
env_name = f"__{env_name}"
|
|
430
|
+
return EnvVar(name=env_name, default=self.default, type_=type_)
|
|
431
|
+
|
|
432
|
+
|
|
433
|
+
if TYPE_CHECKING:
|
|
434
|
+
|
|
435
|
+
def env_var(default, internal=False) -> EnvVar:
|
|
436
|
+
"""Typing helper for the env_var descriptor.
|
|
437
|
+
|
|
438
|
+
Args:
|
|
439
|
+
default: The default value.
|
|
440
|
+
internal: Whether the environment variable is reflex internal.
|
|
441
|
+
|
|
442
|
+
Returns:
|
|
443
|
+
The EnvVar instance.
|
|
444
|
+
"""
|
|
445
|
+
return default
|
|
446
|
+
|
|
447
|
+
|
|
448
|
+
class PathExistsFlag:
|
|
449
|
+
"""Flag to indicate that a path must exist."""
|
|
450
|
+
|
|
451
|
+
|
|
452
|
+
ExistingPath = Annotated[Path, PathExistsFlag]
|
|
453
|
+
|
|
454
|
+
|
|
263
455
|
class EnvironmentVariables:
|
|
264
456
|
"""Environment variables class to instantiate environment variables."""
|
|
265
457
|
|
|
266
458
|
# Whether to use npm over bun to install frontend packages.
|
|
267
|
-
REFLEX_USE_NPM: bool = False
|
|
459
|
+
REFLEX_USE_NPM: EnvVar[bool] = env_var(False)
|
|
268
460
|
|
|
269
461
|
# The npm registry to use.
|
|
270
|
-
NPM_CONFIG_REGISTRY: Optional[str] = None
|
|
462
|
+
NPM_CONFIG_REGISTRY: EnvVar[Optional[str]] = env_var(None)
|
|
271
463
|
|
|
272
464
|
# Whether to use Granian for the backend. Otherwise, use Uvicorn.
|
|
273
|
-
REFLEX_USE_GRANIAN: bool = False
|
|
465
|
+
REFLEX_USE_GRANIAN: EnvVar[bool] = env_var(False)
|
|
274
466
|
|
|
275
467
|
# The username to use for authentication on python package repository. Username and password must both be provided.
|
|
276
|
-
TWINE_USERNAME: Optional[str] = None
|
|
468
|
+
TWINE_USERNAME: EnvVar[Optional[str]] = env_var(None)
|
|
277
469
|
|
|
278
470
|
# The password to use for authentication on python package repository. Username and password must both be provided.
|
|
279
|
-
TWINE_PASSWORD: Optional[str] = None
|
|
471
|
+
TWINE_PASSWORD: EnvVar[Optional[str]] = env_var(None)
|
|
280
472
|
|
|
281
473
|
# Whether to use the system installed bun. If set to false, bun will be bundled with the app.
|
|
282
|
-
REFLEX_USE_SYSTEM_BUN: bool = False
|
|
474
|
+
REFLEX_USE_SYSTEM_BUN: EnvVar[bool] = env_var(False)
|
|
283
475
|
|
|
284
476
|
# Whether to use the system installed node and npm. If set to false, node and npm will be bundled with the app.
|
|
285
|
-
REFLEX_USE_SYSTEM_NODE: bool = False
|
|
477
|
+
REFLEX_USE_SYSTEM_NODE: EnvVar[bool] = env_var(False)
|
|
286
478
|
|
|
287
479
|
# The working directory for the next.js commands.
|
|
288
|
-
REFLEX_WEB_WORKDIR: Path = Path(constants.Dirs.WEB)
|
|
480
|
+
REFLEX_WEB_WORKDIR: EnvVar[Path] = env_var(Path(constants.Dirs.WEB))
|
|
289
481
|
|
|
290
482
|
# Path to the alembic config file
|
|
291
|
-
ALEMBIC_CONFIG:
|
|
483
|
+
ALEMBIC_CONFIG: EnvVar[ExistingPath] = env_var(Path(constants.ALEMBIC_CONFIG))
|
|
292
484
|
|
|
293
485
|
# Disable SSL verification for HTTPX requests.
|
|
294
|
-
SSL_NO_VERIFY: bool = False
|
|
486
|
+
SSL_NO_VERIFY: EnvVar[bool] = env_var(False)
|
|
295
487
|
|
|
296
488
|
# The directory to store uploaded files.
|
|
297
|
-
REFLEX_UPLOADED_FILES_DIR: Path =
|
|
489
|
+
REFLEX_UPLOADED_FILES_DIR: EnvVar[Path] = env_var(
|
|
490
|
+
Path(constants.Dirs.UPLOADED_FILES)
|
|
491
|
+
)
|
|
298
492
|
|
|
299
|
-
# Whether to use
|
|
300
|
-
REFLEX_COMPILE_PROCESSES: Optional[int] = None
|
|
493
|
+
# Whether to use separate processes to compile the frontend and how many. If not set, defaults to thread executor.
|
|
494
|
+
REFLEX_COMPILE_PROCESSES: EnvVar[Optional[int]] = env_var(None)
|
|
301
495
|
|
|
302
|
-
# Whether to use
|
|
303
|
-
REFLEX_COMPILE_THREADS: Optional[int] = None
|
|
496
|
+
# Whether to use separate threads to compile the frontend and how many. Defaults to `min(32, os.cpu_count() + 4)`.
|
|
497
|
+
REFLEX_COMPILE_THREADS: EnvVar[Optional[int]] = env_var(None)
|
|
304
498
|
|
|
305
499
|
# The directory to store reflex dependencies.
|
|
306
|
-
REFLEX_DIR: Path = Path(constants.Reflex.DIR)
|
|
500
|
+
REFLEX_DIR: EnvVar[Path] = env_var(Path(constants.Reflex.DIR))
|
|
307
501
|
|
|
308
502
|
# Whether to print the SQL queries if the log level is INFO or lower.
|
|
309
|
-
SQLALCHEMY_ECHO: bool = False
|
|
503
|
+
SQLALCHEMY_ECHO: EnvVar[bool] = env_var(False)
|
|
310
504
|
|
|
311
505
|
# Whether to ignore the redis config error. Some redis servers only allow out-of-band configuration.
|
|
312
|
-
REFLEX_IGNORE_REDIS_CONFIG_ERROR: bool = False
|
|
506
|
+
REFLEX_IGNORE_REDIS_CONFIG_ERROR: EnvVar[bool] = env_var(False)
|
|
313
507
|
|
|
314
508
|
# Whether to skip purging the web directory in dev mode.
|
|
315
|
-
REFLEX_PERSIST_WEB_DIR: bool = False
|
|
509
|
+
REFLEX_PERSIST_WEB_DIR: EnvVar[bool] = env_var(False)
|
|
316
510
|
|
|
317
511
|
# The reflex.build frontend host.
|
|
318
|
-
REFLEX_BUILD_FRONTEND: str =
|
|
512
|
+
REFLEX_BUILD_FRONTEND: EnvVar[str] = env_var(
|
|
513
|
+
constants.Templates.REFLEX_BUILD_FRONTEND
|
|
514
|
+
)
|
|
319
515
|
|
|
320
516
|
# The reflex.build backend host.
|
|
321
|
-
REFLEX_BUILD_BACKEND: str =
|
|
517
|
+
REFLEX_BUILD_BACKEND: EnvVar[str] = env_var(
|
|
518
|
+
constants.Templates.REFLEX_BUILD_BACKEND
|
|
519
|
+
)
|
|
322
520
|
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
type_hints = get_type_hints(type(self))
|
|
521
|
+
# This env var stores the execution mode of the app
|
|
522
|
+
REFLEX_ENV_MODE: EnvVar[constants.Env] = env_var(constants.Env.DEV)
|
|
326
523
|
|
|
327
|
-
|
|
328
|
-
|
|
524
|
+
# Whether to run the backend only. Exclusive with REFLEX_FRONTEND_ONLY.
|
|
525
|
+
REFLEX_BACKEND_ONLY: EnvVar[bool] = env_var(False)
|
|
329
526
|
|
|
330
|
-
|
|
527
|
+
# Whether to run the frontend only. Exclusive with REFLEX_BACKEND_ONLY.
|
|
528
|
+
REFLEX_FRONTEND_ONLY: EnvVar[bool] = env_var(False)
|
|
331
529
|
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
530
|
+
# Reflex internal env to reload the config.
|
|
531
|
+
RELOAD_CONFIG: EnvVar[bool] = env_var(False, internal=True)
|
|
532
|
+
|
|
533
|
+
# If this env var is set to "yes", App.compile will be a no-op
|
|
534
|
+
REFLEX_SKIP_COMPILE: EnvVar[bool] = env_var(False, internal=True)
|
|
535
|
+
|
|
536
|
+
# Whether to run app harness tests in headless mode.
|
|
537
|
+
APP_HARNESS_HEADLESS: EnvVar[bool] = env_var(False)
|
|
337
538
|
|
|
338
|
-
|
|
539
|
+
# Which app harness driver to use.
|
|
540
|
+
APP_HARNESS_DRIVER: EnvVar[str] = env_var("Chrome")
|
|
541
|
+
|
|
542
|
+
# Arguments to pass to the app harness driver.
|
|
543
|
+
APP_HARNESS_DRIVER_ARGS: EnvVar[str] = env_var("")
|
|
544
|
+
|
|
545
|
+
# Where to save screenshots when tests fail.
|
|
546
|
+
SCREENSHOT_DIR: EnvVar[Optional[Path]] = env_var(None)
|
|
339
547
|
|
|
340
548
|
|
|
341
549
|
environment = EnvironmentVariables()
|
|
@@ -401,7 +609,10 @@ class Config(Base):
|
|
|
401
609
|
telemetry_enabled: bool = True
|
|
402
610
|
|
|
403
611
|
# The bun path
|
|
404
|
-
bun_path:
|
|
612
|
+
bun_path: ExistingPath = constants.Bun.DEFAULT_PATH
|
|
613
|
+
|
|
614
|
+
# Timeout to do a production build of a frontend page.
|
|
615
|
+
static_page_generation_timeout: int = 60
|
|
405
616
|
|
|
406
617
|
# List of origins that are allowed to connect to the backend API.
|
|
407
618
|
cors_allowed_origins: List[str] = ["*"]
|
|
@@ -525,7 +736,7 @@ class Config(Base):
|
|
|
525
736
|
)
|
|
526
737
|
|
|
527
738
|
# Interpret the value.
|
|
528
|
-
value = interpret_env_var_value(env_var, field.
|
|
739
|
+
value = interpret_env_var_value(env_var, field.outer_type_, field.name)
|
|
529
740
|
|
|
530
741
|
# Set the value.
|
|
531
742
|
updated_values[key] = value
|
reflex/constants/__init__.py
CHANGED
|
@@ -2,18 +2,15 @@
|
|
|
2
2
|
|
|
3
3
|
from .base import (
|
|
4
4
|
COOKIES,
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
ENV_MODE_ENV_VAR,
|
|
5
|
+
IS_LINUX,
|
|
6
|
+
IS_MACOS,
|
|
8
7
|
IS_WINDOWS,
|
|
9
8
|
LOCAL_STORAGE,
|
|
10
9
|
POLLING_MAX_HTTP_BUFFER_SIZE,
|
|
11
10
|
PYTEST_CURRENT_TEST,
|
|
12
11
|
REFLEX_VAR_CLOSING_TAG,
|
|
13
12
|
REFLEX_VAR_OPENING_TAG,
|
|
14
|
-
RELOAD_CONFIG,
|
|
15
13
|
SESSION_STORAGE,
|
|
16
|
-
SKIP_COMPILE_ENV_VAR,
|
|
17
14
|
ColorMode,
|
|
18
15
|
Dirs,
|
|
19
16
|
Env,
|
|
@@ -44,16 +41,9 @@ from .config import (
|
|
|
44
41
|
GitIgnore,
|
|
45
42
|
RequirementsTxt,
|
|
46
43
|
)
|
|
47
|
-
from .custom_components import
|
|
48
|
-
CustomComponents,
|
|
49
|
-
)
|
|
44
|
+
from .custom_components import CustomComponents
|
|
50
45
|
from .event import Endpoint, EventTriggers, SocketEvent
|
|
51
|
-
from .installer import
|
|
52
|
-
Bun,
|
|
53
|
-
Fnm,
|
|
54
|
-
Node,
|
|
55
|
-
PackageJson,
|
|
56
|
-
)
|
|
46
|
+
from .installer import Bun, Fnm, Node, PackageJson
|
|
57
47
|
from .route import (
|
|
58
48
|
ROUTE_NOT_FOUND,
|
|
59
49
|
ROUTER,
|
|
@@ -106,7 +96,6 @@ __ALL__ = [
|
|
|
106
96
|
POLLING_MAX_HTTP_BUFFER_SIZE,
|
|
107
97
|
PYTEST_CURRENT_TEST,
|
|
108
98
|
Reflex,
|
|
109
|
-
RELOAD_CONFIG,
|
|
110
99
|
RequirementsTxt,
|
|
111
100
|
RouteArgType,
|
|
112
101
|
RouteRegex,
|
|
@@ -116,7 +105,6 @@ __ALL__ = [
|
|
|
116
105
|
ROUTER_DATA_INCLUDE,
|
|
117
106
|
ROUTE_NOT_FOUND,
|
|
118
107
|
SETTER_PREFIX,
|
|
119
|
-
SKIP_COMPILE_ENV_VAR,
|
|
120
108
|
SocketEvent,
|
|
121
109
|
StateManagerMode,
|
|
122
110
|
Tailwind,
|
reflex/constants/base.py
CHANGED
|
@@ -13,6 +13,8 @@ from platformdirs import PlatformDirs
|
|
|
13
13
|
from .utils import classproperty
|
|
14
14
|
|
|
15
15
|
IS_WINDOWS = platform.system() == "Windows"
|
|
16
|
+
IS_MACOS = platform.system() == "Darwin"
|
|
17
|
+
IS_LINUX = platform.system() == "Linux"
|
|
16
18
|
|
|
17
19
|
|
|
18
20
|
class Dirs(SimpleNamespace):
|
|
@@ -76,7 +78,7 @@ class Reflex(SimpleNamespace):
|
|
|
76
78
|
# The root directory of the reflex library.
|
|
77
79
|
ROOT_DIR = Path(__file__).parents[2]
|
|
78
80
|
|
|
79
|
-
RELEASES_URL =
|
|
81
|
+
RELEASES_URL = "https://api.github.com/repos/reflex-dev/templates/releases"
|
|
80
82
|
|
|
81
83
|
|
|
82
84
|
class ReflexHostingCLI(SimpleNamespace):
|
|
@@ -112,7 +114,7 @@ class Templates(SimpleNamespace):
|
|
|
112
114
|
from reflex.config import environment
|
|
113
115
|
|
|
114
116
|
return (
|
|
115
|
-
environment.REFLEX_BUILD_FRONTEND
|
|
117
|
+
environment.REFLEX_BUILD_FRONTEND.get()
|
|
116
118
|
+ "/gen?reflex_init_token={reflex_init_token}"
|
|
117
119
|
)
|
|
118
120
|
|
|
@@ -126,7 +128,7 @@ class Templates(SimpleNamespace):
|
|
|
126
128
|
"""
|
|
127
129
|
from reflex.config import environment
|
|
128
130
|
|
|
129
|
-
return environment.REFLEX_BUILD_BACKEND + "/api/init/{reflex_init_token}"
|
|
131
|
+
return environment.REFLEX_BUILD_BACKEND.get() + "/api/init/{reflex_init_token}"
|
|
130
132
|
|
|
131
133
|
@classproperty
|
|
132
134
|
@classmethod
|
|
@@ -139,7 +141,8 @@ class Templates(SimpleNamespace):
|
|
|
139
141
|
from reflex.config import environment
|
|
140
142
|
|
|
141
143
|
return (
|
|
142
|
-
environment.REFLEX_BUILD_BACKEND
|
|
144
|
+
environment.REFLEX_BUILD_BACKEND.get()
|
|
145
|
+
+ "/api/gen/{generation_hash}/refactored"
|
|
143
146
|
)
|
|
144
147
|
|
|
145
148
|
class Dirs(SimpleNamespace):
|
|
@@ -239,19 +242,9 @@ COOKIES = "cookies"
|
|
|
239
242
|
LOCAL_STORAGE = "local_storage"
|
|
240
243
|
SESSION_STORAGE = "session_storage"
|
|
241
244
|
|
|
242
|
-
# If this env var is set to "yes", App.compile will be a no-op
|
|
243
|
-
SKIP_COMPILE_ENV_VAR = "__REFLEX_SKIP_COMPILE"
|
|
244
|
-
|
|
245
|
-
# This env var stores the execution mode of the app
|
|
246
|
-
ENV_MODE_ENV_VAR = "REFLEX_ENV_MODE"
|
|
247
|
-
|
|
248
|
-
ENV_BACKEND_ONLY_ENV_VAR = "REFLEX_BACKEND_ONLY"
|
|
249
|
-
ENV_FRONTEND_ONLY_ENV_VAR = "REFLEX_FRONTEND_ONLY"
|
|
250
|
-
|
|
251
245
|
# Testing variables.
|
|
252
246
|
# Testing os env set by pytest when running a test case.
|
|
253
247
|
PYTEST_CURRENT_TEST = "PYTEST_CURRENT_TEST"
|
|
254
|
-
RELOAD_CONFIG = "__REFLEX_RELOAD_CONFIG"
|
|
255
248
|
|
|
256
249
|
REFLEX_VAR_OPENING_TAG = "<reflex.Var>"
|
|
257
250
|
REFLEX_VAR_CLOSING_TAG = "</reflex.Var>"
|
reflex/constants/colors.py
CHANGED
reflex/constants/installer.py
CHANGED
|
@@ -63,7 +63,7 @@ class Bun(SimpleNamespace):
|
|
|
63
63
|
"""
|
|
64
64
|
from reflex.config import environment
|
|
65
65
|
|
|
66
|
-
return environment.REFLEX_DIR / "bun"
|
|
66
|
+
return environment.REFLEX_DIR.get() / "bun"
|
|
67
67
|
|
|
68
68
|
@classproperty
|
|
69
69
|
@classmethod
|
|
@@ -75,6 +75,11 @@ class Bun(SimpleNamespace):
|
|
|
75
75
|
"""
|
|
76
76
|
return cls.ROOT_PATH / "bin" / ("bun" if not IS_WINDOWS else "bun.exe")
|
|
77
77
|
|
|
78
|
+
DEFAULT_CONFIG = """
|
|
79
|
+
[install]
|
|
80
|
+
registry = "{registry}"
|
|
81
|
+
"""
|
|
82
|
+
|
|
78
83
|
|
|
79
84
|
# FNM config.
|
|
80
85
|
class Fnm(SimpleNamespace):
|
|
@@ -100,7 +105,7 @@ class Fnm(SimpleNamespace):
|
|
|
100
105
|
"""
|
|
101
106
|
from reflex.config import environment
|
|
102
107
|
|
|
103
|
-
return environment.REFLEX_DIR / "fnm"
|
|
108
|
+
return environment.REFLEX_DIR.get() / "fnm"
|
|
104
109
|
|
|
105
110
|
@classproperty
|
|
106
111
|
@classmethod
|
|
@@ -118,9 +123,9 @@ class Node(SimpleNamespace):
|
|
|
118
123
|
"""Node/ NPM constants."""
|
|
119
124
|
|
|
120
125
|
# The Node version.
|
|
121
|
-
VERSION = "22.
|
|
126
|
+
VERSION = "22.11.0"
|
|
122
127
|
# The minimum required node version.
|
|
123
|
-
MIN_VERSION = "18.
|
|
128
|
+
MIN_VERSION = "18.18.0"
|
|
124
129
|
|
|
125
130
|
@classproperty
|
|
126
131
|
@classmethod
|
|
@@ -173,17 +178,17 @@ class PackageJson(SimpleNamespace):
|
|
|
173
178
|
PATH = "package.json"
|
|
174
179
|
|
|
175
180
|
DEPENDENCIES = {
|
|
176
|
-
"@babel/standalone": "7.
|
|
181
|
+
"@babel/standalone": "7.26.0",
|
|
177
182
|
"@emotion/react": "11.13.3",
|
|
178
183
|
"axios": "1.7.7",
|
|
179
184
|
"json5": "2.2.3",
|
|
180
|
-
"next": "14.2.
|
|
185
|
+
"next": "14.2.16",
|
|
181
186
|
"next-sitemap": "4.2.3",
|
|
182
187
|
"next-themes": "0.3.0",
|
|
183
188
|
"react": "18.3.1",
|
|
184
189
|
"react-dom": "18.3.1",
|
|
185
190
|
"react-focus-lock": "2.13.2",
|
|
186
|
-
"socket.io-client": "4.8.
|
|
191
|
+
"socket.io-client": "4.8.1",
|
|
187
192
|
"universal-cookie": "7.2.1",
|
|
188
193
|
}
|
|
189
194
|
DEV_DEPENDENCIES = {
|
reflex/constants/state.py
CHANGED
|
@@ -609,14 +609,14 @@ def publish(
|
|
|
609
609
|
help="The API token to use for authentication on python package repository. If token is provided, no username/password should be provided at the same time",
|
|
610
610
|
),
|
|
611
611
|
username: Optional[str] = typer.Option(
|
|
612
|
-
environment.TWINE_USERNAME,
|
|
612
|
+
environment.TWINE_USERNAME.get(),
|
|
613
613
|
"-u",
|
|
614
614
|
"--username",
|
|
615
615
|
show_default="TWINE_USERNAME environment variable value if set",
|
|
616
616
|
help="The username to use for authentication on python package repository. Username and password must both be provided.",
|
|
617
617
|
),
|
|
618
618
|
password: Optional[str] = typer.Option(
|
|
619
|
-
environment.TWINE_PASSWORD,
|
|
619
|
+
environment.TWINE_PASSWORD.get(),
|
|
620
620
|
"-p",
|
|
621
621
|
"--password",
|
|
622
622
|
show_default="TWINE_PASSWORD environment variable value if set",
|
|
@@ -779,8 +779,8 @@ def _validate_project_info():
|
|
|
779
779
|
)
|
|
780
780
|
# PyPI only shows the first author.
|
|
781
781
|
author = project.get("authors", [{}])[0]
|
|
782
|
-
author["name"] = console.ask(
|
|
783
|
-
author["email"] = console.ask(
|
|
782
|
+
author["name"] = console.ask("Author Name", default=author.get("name", ""))
|
|
783
|
+
author["email"] = console.ask("Author Email", default=author.get("email", ""))
|
|
784
784
|
|
|
785
785
|
console.print(f'Current keywords are: {project.get("keywords") or []}')
|
|
786
786
|
keyword_action = console.ask(
|
|
@@ -923,7 +923,7 @@ def _get_file_from_prompt_in_loop() -> Tuple[bytes, str] | None:
|
|
|
923
923
|
image_file = file_extension = None
|
|
924
924
|
while image_file is None:
|
|
925
925
|
image_filepath = console.ask(
|
|
926
|
-
|
|
926
|
+
"Upload a preview image of your demo app (enter to skip)"
|
|
927
927
|
)
|
|
928
928
|
if not image_filepath:
|
|
929
929
|
break
|
|
@@ -973,6 +973,6 @@ def install(
|
|
|
973
973
|
console.set_log_level(loglevel)
|
|
974
974
|
|
|
975
975
|
if _pip_install_on_demand(package_name=".", install_args=["-e"]):
|
|
976
|
-
console.info(
|
|
976
|
+
console.info("Package installed successfully!")
|
|
977
977
|
else:
|
|
978
978
|
raise typer.Exit(code=1)
|