reflex 0.7.14a6__py3-none-any.whl → 0.8.0__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/app/rxconfig.py.jinja2 +4 -1
- reflex/.templates/jinja/web/package.json.jinja2 +1 -1
- reflex/.templates/jinja/web/pages/_app.js.jinja2 +21 -11
- reflex/.templates/jinja/web/pages/_document.js.jinja2 +1 -1
- reflex/.templates/jinja/web/pages/base_page.js.jinja2 +0 -1
- reflex/.templates/jinja/web/pages/stateful_component.js.jinja2 +4 -0
- reflex/.templates/jinja/web/styles/styles.css.jinja2 +1 -0
- reflex/.templates/jinja/web/utils/context.js.jinja2 +25 -8
- reflex/.templates/web/app/entry.client.js +8 -0
- reflex/.templates/web/app/routes.js +10 -0
- reflex/.templates/web/components/reflex/radix_themes_color_mode_provider.js +12 -37
- reflex/.templates/web/postcss.config.js +1 -1
- reflex/.templates/web/react-router.config.js +6 -0
- reflex/.templates/web/styles/__reflex_style_reset.css +399 -0
- reflex/.templates/web/utils/client_side_routing.js +21 -19
- reflex/.templates/web/utils/react-theme.js +92 -0
- reflex/.templates/web/utils/state.js +251 -100
- reflex/.templates/web/vite-plugin-safari-cachebust.js +160 -0
- reflex/.templates/web/vite.config.js +39 -0
- reflex/__init__.py +1 -6
- reflex/__init__.pyi +327 -192
- reflex/app.py +86 -135
- reflex/base.py +1 -87
- reflex/compiler/compiler.py +70 -19
- reflex/compiler/templates.py +3 -3
- reflex/compiler/utils.py +91 -33
- reflex/components/__init__.py +0 -2
- reflex/components/__init__.pyi +34 -18
- reflex/components/base/__init__.py +1 -5
- reflex/components/base/__init__.pyi +30 -21
- reflex/components/base/app_wrap.pyi +7 -7
- reflex/components/base/body.pyi +7 -7
- reflex/components/base/document.py +18 -14
- reflex/components/base/document.pyi +88 -38
- reflex/components/base/error_boundary.pyi +7 -7
- reflex/components/base/fragment.pyi +7 -7
- reflex/components/base/link.pyi +12 -12
- reflex/components/base/meta.py +4 -15
- reflex/components/base/meta.pyi +31 -31
- reflex/components/base/script.py +60 -58
- reflex/components/base/script.pyi +248 -34
- reflex/components/base/strict_mode.pyi +7 -7
- reflex/components/component.py +146 -217
- reflex/components/core/__init__.py +1 -0
- reflex/components/core/__init__.pyi +77 -37
- reflex/components/core/auto_scroll.pyi +7 -7
- reflex/components/core/banner.pyi +33 -33
- reflex/components/core/client_side_routing.py +7 -6
- reflex/components/core/client_side_routing.pyi +8 -59
- reflex/components/core/clipboard.pyi +7 -7
- reflex/components/core/debounce.py +1 -0
- reflex/components/core/debounce.pyi +7 -7
- reflex/components/core/foreach.py +5 -4
- reflex/components/core/helmet.py +14 -0
- reflex/components/{next/base.pyi → core/helmet.pyi} +12 -10
- reflex/components/core/html.pyi +7 -7
- reflex/components/core/match.py +3 -3
- reflex/components/core/sticky.pyi +21 -20
- reflex/components/core/upload.py +4 -2
- reflex/components/core/upload.pyi +26 -25
- reflex/components/datadisplay/__init__.pyi +13 -7
- reflex/components/datadisplay/code.py +14 -79
- reflex/components/datadisplay/code.pyi +11 -13
- reflex/components/datadisplay/dataeditor.pyi +38 -15
- reflex/components/datadisplay/shiki_code_block.py +5 -3
- reflex/components/datadisplay/shiki_code_block.pyi +16 -15
- reflex/components/dynamic.py +5 -5
- reflex/components/el/__init__.pyi +506 -246
- reflex/components/el/element.pyi +7 -7
- reflex/components/el/elements/__init__.pyi +504 -245
- reflex/components/el/elements/base.pyi +7 -7
- reflex/components/el/elements/forms.pyi +146 -101
- reflex/components/el/elements/inline.pyi +142 -142
- reflex/components/el/elements/media.pyi +131 -130
- reflex/components/el/elements/metadata.pyi +32 -32
- reflex/components/el/elements/other.pyi +37 -37
- reflex/components/el/elements/scripts.pyi +17 -17
- reflex/components/el/elements/sectioning.pyi +77 -77
- reflex/components/el/elements/tables.pyi +52 -52
- reflex/components/el/elements/typography.pyi +77 -77
- reflex/components/field.py +175 -0
- reflex/components/gridjs/datatable.py +2 -2
- reflex/components/gridjs/datatable.pyi +14 -14
- reflex/components/lucide/icon.py +6 -2
- reflex/components/lucide/icon.pyi +19 -17
- reflex/components/markdown/markdown.py +5 -3
- reflex/components/markdown/markdown.pyi +7 -7
- reflex/components/moment/moment.py +1 -1
- reflex/components/moment/moment.pyi +7 -7
- reflex/components/plotly/plotly.py +12 -6
- reflex/components/plotly/plotly.pyi +50 -49
- reflex/components/props.py +376 -27
- reflex/components/radix/__init__.pyi +123 -65
- reflex/components/radix/primitives/__init__.pyi +6 -4
- reflex/components/radix/primitives/accordion.py +8 -1
- reflex/components/radix/primitives/accordion.pyi +37 -37
- reflex/components/radix/primitives/base.pyi +12 -12
- reflex/components/radix/primitives/drawer.pyi +56 -55
- reflex/components/radix/primitives/form.pyi +63 -53
- reflex/components/radix/primitives/progress.pyi +26 -25
- reflex/components/radix/primitives/slider.pyi +27 -27
- reflex/components/radix/themes/__init__.pyi +5 -6
- reflex/components/radix/themes/base.py +3 -3
- reflex/components/radix/themes/base.pyi +42 -42
- reflex/components/radix/themes/color_mode.py +5 -6
- reflex/components/radix/themes/color_mode.pyi +17 -17
- reflex/components/radix/themes/components/__init__.pyi +75 -38
- reflex/components/radix/themes/components/alert_dialog.pyi +37 -37
- reflex/components/radix/themes/components/aspect_ratio.pyi +7 -7
- reflex/components/radix/themes/components/avatar.pyi +7 -7
- reflex/components/radix/themes/components/badge.pyi +7 -7
- reflex/components/radix/themes/components/button.pyi +7 -7
- reflex/components/radix/themes/components/callout.pyi +26 -25
- reflex/components/radix/themes/components/card.pyi +7 -7
- reflex/components/radix/themes/components/checkbox.pyi +16 -15
- reflex/components/radix/themes/components/checkbox_cards.pyi +12 -12
- reflex/components/radix/themes/components/checkbox_group.pyi +12 -12
- reflex/components/radix/themes/components/context_menu.pyi +67 -67
- reflex/components/radix/themes/components/data_list.pyi +22 -22
- reflex/components/radix/themes/components/dialog.pyi +36 -35
- reflex/components/radix/themes/components/dropdown_menu.pyi +42 -42
- reflex/components/radix/themes/components/hover_card.pyi +21 -20
- reflex/components/radix/themes/components/icon_button.pyi +7 -7
- reflex/components/radix/themes/components/inset.pyi +7 -7
- reflex/components/radix/themes/components/popover.pyi +22 -22
- reflex/components/radix/themes/components/progress.pyi +7 -7
- reflex/components/radix/themes/components/radio.pyi +7 -7
- reflex/components/radix/themes/components/radio_cards.pyi +12 -12
- reflex/components/radix/themes/components/radio_group.pyi +21 -20
- reflex/components/radix/themes/components/scroll_area.pyi +7 -7
- reflex/components/radix/themes/components/segmented_control.pyi +12 -12
- reflex/components/radix/themes/components/select.pyi +46 -45
- reflex/components/radix/themes/components/separator.pyi +7 -7
- reflex/components/radix/themes/components/skeleton.pyi +7 -7
- reflex/components/radix/themes/components/slider.pyi +17 -9
- reflex/components/radix/themes/components/spinner.pyi +7 -7
- reflex/components/radix/themes/components/switch.pyi +7 -7
- reflex/components/radix/themes/components/table.pyi +37 -37
- reflex/components/radix/themes/components/tabs.pyi +26 -25
- reflex/components/radix/themes/components/text_area.pyi +15 -9
- reflex/components/radix/themes/components/text_field.pyi +32 -19
- reflex/components/radix/themes/components/tooltip.pyi +7 -7
- reflex/components/radix/themes/layout/__init__.pyi +27 -14
- reflex/components/radix/themes/layout/base.pyi +7 -7
- reflex/components/radix/themes/layout/box.pyi +7 -7
- reflex/components/radix/themes/layout/center.pyi +7 -7
- reflex/components/radix/themes/layout/container.pyi +7 -7
- reflex/components/radix/themes/layout/flex.pyi +7 -7
- reflex/components/radix/themes/layout/grid.pyi +7 -7
- reflex/components/radix/themes/layout/list.pyi +26 -25
- reflex/components/radix/themes/layout/section.pyi +7 -7
- reflex/components/radix/themes/layout/spacer.pyi +7 -7
- reflex/components/radix/themes/layout/stack.pyi +17 -17
- reflex/components/radix/themes/typography/__init__.pyi +7 -5
- reflex/components/radix/themes/typography/blockquote.pyi +7 -7
- reflex/components/radix/themes/typography/code.pyi +7 -7
- reflex/components/radix/themes/typography/heading.pyi +7 -7
- reflex/components/radix/themes/typography/link.py +46 -11
- reflex/components/radix/themes/typography/link.pyi +312 -9
- reflex/components/radix/themes/typography/text.pyi +36 -35
- reflex/components/react_player/audio.pyi +10 -8
- reflex/components/react_player/react_player.pyi +7 -7
- reflex/components/react_player/video.pyi +10 -8
- reflex/components/recharts/__init__.pyi +208 -100
- reflex/components/recharts/cartesian.py +10 -8
- reflex/components/recharts/cartesian.pyi +90 -94
- reflex/components/recharts/charts.py +4 -2
- reflex/components/recharts/charts.pyi +49 -49
- reflex/components/recharts/general.pyi +31 -31
- reflex/components/recharts/polar.py +8 -4
- reflex/components/recharts/polar.pyi +23 -23
- reflex/components/recharts/recharts.py +2 -2
- reflex/components/recharts/recharts.pyi +12 -12
- reflex/components/sonner/toast.py +3 -3
- reflex/components/sonner/toast.pyi +9 -9
- reflex/config.py +10 -113
- reflex/constants/__init__.py +2 -2
- reflex/constants/base.py +28 -11
- reflex/constants/compiler.py +12 -3
- reflex/constants/event.py +1 -0
- reflex/constants/installer.py +26 -20
- reflex/constants/route.py +27 -8
- reflex/constants/state.py +2 -0
- reflex/custom_components/custom_components.py +0 -14
- reflex/environment.py +77 -5
- reflex/event.py +178 -81
- reflex/experimental/__init__.py +0 -30
- reflex/istate/__init__.py +69 -0
- reflex/istate/manager.py +1 -0
- reflex/istate/proxy.py +5 -3
- reflex/page.py +0 -27
- reflex/plugins/__init__.py +3 -2
- reflex/plugins/base.py +5 -1
- reflex/plugins/shared_tailwind.py +215 -0
- reflex/plugins/sitemap.py +206 -0
- reflex/plugins/tailwind_v3.py +15 -108
- reflex/plugins/tailwind_v4.py +18 -110
- reflex/reflex.py +1 -0
- reflex/route.py +157 -75
- reflex/state.py +171 -155
- reflex/testing.py +86 -16
- reflex/utils/build.py +38 -82
- reflex/utils/exec.py +83 -175
- reflex/utils/export.py +2 -2
- reflex/utils/format.py +1 -5
- reflex/utils/imports.py +5 -16
- reflex/utils/misc.py +67 -0
- reflex/utils/prerequisites.py +66 -68
- reflex/utils/processes.py +24 -47
- reflex/utils/pyi_generator.py +44 -49
- reflex/utils/serializers.py +14 -1
- reflex/utils/telemetry.py +0 -15
- reflex/utils/types.py +197 -62
- reflex/vars/__init__.py +2 -0
- reflex/vars/base.py +367 -134
- {reflex-0.7.14a6.dist-info → reflex-0.8.0.dist-info}/METADATA +15 -8
- reflex-0.8.0.dist-info/RECORD +403 -0
- reflex/.templates/web/next.config.js +0 -7
- reflex/components/base/head.py +0 -20
- reflex/components/base/head.pyi +0 -116
- reflex/components/next/__init__.py +0 -10
- reflex/components/next/base.py +0 -7
- reflex/components/next/image.py +0 -117
- reflex/components/next/image.pyi +0 -94
- reflex/components/next/link.py +0 -20
- reflex/components/next/link.pyi +0 -67
- reflex/components/next/video.py +0 -38
- reflex/components/next/video.pyi +0 -68
- reflex/components/suneditor/__init__.py +0 -5
- reflex/components/suneditor/editor.py +0 -269
- reflex/components/suneditor/editor.pyi +0 -199
- reflex/experimental/layout.py +0 -254
- reflex/experimental/layout.pyi +0 -814
- reflex-0.7.14a6.dist-info/RECORD +0 -408
- {reflex-0.7.14a6.dist-info → reflex-0.8.0.dist-info}/WHEEL +0 -0
- {reflex-0.7.14a6.dist-info → reflex-0.8.0.dist-info}/entry_points.txt +0 -0
- {reflex-0.7.14a6.dist-info → reflex-0.8.0.dist-info}/licenses/LICENSE +0 -0
reflex/constants/installer.py
CHANGED
|
@@ -14,10 +14,10 @@ class Bun(SimpleNamespace):
|
|
|
14
14
|
"""Bun constants."""
|
|
15
15
|
|
|
16
16
|
# The Bun version.
|
|
17
|
-
VERSION = "1.2.
|
|
17
|
+
VERSION = "1.2.17"
|
|
18
18
|
|
|
19
19
|
# Min Bun Version
|
|
20
|
-
MIN_VERSION = "1.2.
|
|
20
|
+
MIN_VERSION = "1.2.17"
|
|
21
21
|
|
|
22
22
|
# URL to bun install script.
|
|
23
23
|
INSTALL_URL = "https://raw.githubusercontent.com/reflex-dev/reflex/main/scripts/bun_install.sh"
|
|
@@ -63,7 +63,7 @@ class Node(SimpleNamespace):
|
|
|
63
63
|
"""Node/ NPM constants."""
|
|
64
64
|
|
|
65
65
|
# The minimum required node version.
|
|
66
|
-
MIN_VERSION = "
|
|
66
|
+
MIN_VERSION = "20.19.0"
|
|
67
67
|
|
|
68
68
|
# Path of the node config file.
|
|
69
69
|
CONFIG_PATH = ".npmrc"
|
|
@@ -74,13 +74,13 @@ fetch-retries=0
|
|
|
74
74
|
"""
|
|
75
75
|
|
|
76
76
|
|
|
77
|
-
def
|
|
78
|
-
default_version = "
|
|
79
|
-
if (version := os.getenv("
|
|
77
|
+
def _determine_react_router_version() -> str:
|
|
78
|
+
default_version = "7.6.2"
|
|
79
|
+
if (version := os.getenv("REACT_ROUTER_VERSION")) and version != default_version:
|
|
80
80
|
from reflex.utils import console
|
|
81
81
|
|
|
82
82
|
console.warn(
|
|
83
|
-
f"You have requested
|
|
83
|
+
f"You have requested react-router@{version} but the supported version is {default_version}, abandon all hope ye who enter here."
|
|
84
84
|
)
|
|
85
85
|
return version
|
|
86
86
|
return default_version
|
|
@@ -104,15 +104,16 @@ class PackageJson(SimpleNamespace):
|
|
|
104
104
|
class Commands(SimpleNamespace):
|
|
105
105
|
"""The commands to define in package.json."""
|
|
106
106
|
|
|
107
|
-
DEV = "
|
|
108
|
-
EXPORT = "
|
|
109
|
-
|
|
110
|
-
PROD = "next start"
|
|
107
|
+
DEV = "react-router dev"
|
|
108
|
+
EXPORT = "react-router build"
|
|
109
|
+
PROD = "serve ./build/client"
|
|
111
110
|
|
|
112
111
|
PATH = "package.json"
|
|
113
112
|
|
|
114
113
|
_react_version = _determine_react_version()
|
|
115
114
|
|
|
115
|
+
_react_router_version = _determine_react_router_version()
|
|
116
|
+
|
|
116
117
|
@classproperty
|
|
117
118
|
@classmethod
|
|
118
119
|
def DEPENDENCIES(cls) -> dict[str, str]:
|
|
@@ -122,25 +123,30 @@ class PackageJson(SimpleNamespace):
|
|
|
122
123
|
A dictionary of dependencies with their versions.
|
|
123
124
|
"""
|
|
124
125
|
return {
|
|
125
|
-
"@emotion/react": "11.14.0",
|
|
126
|
-
"axios": "1.9.0",
|
|
127
126
|
"json5": "2.2.3",
|
|
128
|
-
"
|
|
129
|
-
"
|
|
130
|
-
"
|
|
127
|
+
"react-router": cls._react_router_version,
|
|
128
|
+
"react-router-dom": cls._react_router_version,
|
|
129
|
+
"@react-router/node": cls._react_router_version,
|
|
130
|
+
"serve": "14.2.4",
|
|
131
131
|
"react": cls._react_version,
|
|
132
|
+
"react-helmet": "6.1.0",
|
|
132
133
|
"react-dom": cls._react_version,
|
|
133
|
-
"
|
|
134
|
+
"isbot": "5.1.28",
|
|
134
135
|
"socket.io-client": "4.8.1",
|
|
135
136
|
"universal-cookie": "7.2.2",
|
|
136
137
|
}
|
|
137
138
|
|
|
138
139
|
DEV_DEPENDENCIES = {
|
|
140
|
+
"@emotion/react": "11.14.0",
|
|
139
141
|
"autoprefixer": "10.4.21",
|
|
140
|
-
"postcss": "8.5.
|
|
141
|
-
"postcss-import": "16.1.
|
|
142
|
+
"postcss": "8.5.6",
|
|
143
|
+
"postcss-import": "16.1.1",
|
|
144
|
+
"@react-router/dev": _react_router_version,
|
|
145
|
+
"@react-router/fs-routes": _react_router_version,
|
|
146
|
+
"rolldown-vite": "7.0.1",
|
|
142
147
|
}
|
|
143
148
|
OVERRIDES = {
|
|
144
149
|
# This should always match the `react` version in DEPENDENCIES for recharts compatibility.
|
|
145
|
-
"react-is": _react_version
|
|
150
|
+
"react-is": _react_version,
|
|
151
|
+
"cookie": "1.0.2",
|
|
146
152
|
}
|
reflex/constants/route.py
CHANGED
|
@@ -36,16 +36,35 @@ ROUTER_DATA_INCLUDE = {RouteVar.PATH, RouteVar.ORIGIN, RouteVar.QUERY}
|
|
|
36
36
|
class RouteRegex(SimpleNamespace):
|
|
37
37
|
"""Regex used for extracting route args in route."""
|
|
38
38
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
#
|
|
45
|
-
|
|
39
|
+
_DOT_DOT_DOT = r"\.\.\."
|
|
40
|
+
_OPENING_BRACKET = r"\["
|
|
41
|
+
_CLOSING_BRACKET = r"\]"
|
|
42
|
+
_ARG_NAME = r"[a-zA-Z_]\w*"
|
|
43
|
+
|
|
44
|
+
# The regex for a valid arg name, e.g. "slug" in "[slug]"
|
|
45
|
+
_ARG_NAME_PATTERN = re.compile(_ARG_NAME)
|
|
46
|
+
|
|
47
|
+
SLUG = re.compile(r"[a-zA-Z0-9_-]+")
|
|
48
|
+
# match a single arg (i.e. "[slug]"), returns the name of the arg
|
|
49
|
+
ARG = re.compile(rf"{_OPENING_BRACKET}({_ARG_NAME}){_CLOSING_BRACKET}")
|
|
50
|
+
# match a single optional arg (i.e. "[[slug]]"), returns the name of the arg
|
|
51
|
+
OPTIONAL_ARG = re.compile(
|
|
52
|
+
rf"{_OPENING_BRACKET * 2}({_ARG_NAME}){_CLOSING_BRACKET * 2}"
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
# match a single non-optional catch-all arg (i.e. "[...slug]"), returns the name of the arg
|
|
56
|
+
STRICT_CATCHALL = re.compile(
|
|
57
|
+
rf"{_OPENING_BRACKET}{_DOT_DOT_DOT}({_ARG_NAME}){_CLOSING_BRACKET}"
|
|
58
|
+
)
|
|
59
|
+
|
|
60
|
+
# match a single optional catch-all arg (i.e. "[[...slug]]"), returns the name of the arg
|
|
61
|
+
OPTIONAL_CATCHALL = re.compile(
|
|
62
|
+
rf"{_OPENING_BRACKET * 2}{_DOT_DOT_DOT}({_ARG_NAME}){_CLOSING_BRACKET * 2}"
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
SPLAT_CATCHALL = "[[...splat]]"
|
|
46
66
|
SINGLE_SEGMENT = "__SINGLE_SEGMENT__"
|
|
47
67
|
DOUBLE_SEGMENT = "__DOUBLE_SEGMENT__"
|
|
48
|
-
SINGLE_CATCHALL_SEGMENT = "__SINGLE_CATCHALL_SEGMENT__"
|
|
49
68
|
DOUBLE_CATCHALL_SEGMENT = "__DOUBLE_CATCHALL_SEGMENT__"
|
|
50
69
|
|
|
51
70
|
|
reflex/constants/state.py
CHANGED
|
@@ -461,20 +461,6 @@ def build():
|
|
|
461
461
|
_run_build()
|
|
462
462
|
|
|
463
463
|
|
|
464
|
-
@custom_components_cli.command(name="publish", deprecated=True)
|
|
465
|
-
def publish():
|
|
466
|
-
"""Publish a custom component. This command is deprecated and will be removed in future releases.
|
|
467
|
-
|
|
468
|
-
Raises:
|
|
469
|
-
Exit: If the publish command fails.
|
|
470
|
-
"""
|
|
471
|
-
console.error(
|
|
472
|
-
"The publish command is deprecated. You can use `reflex component build` followed by `twine upload` or a similar publishing command to publish your custom component."
|
|
473
|
-
"\nIf you want to share your custom component with the Reflex community, please use `reflex component share`."
|
|
474
|
-
)
|
|
475
|
-
raise click.exceptions.Exit(code=1)
|
|
476
|
-
|
|
477
|
-
|
|
478
464
|
def _collect_details_for_gallery():
|
|
479
465
|
"""Helper to collect details on the custom component to be included in the gallery.
|
|
480
466
|
|
reflex/environment.py
CHANGED
|
@@ -69,7 +69,7 @@ def interpret_boolean_env(value: str, field_name: str) -> bool:
|
|
|
69
69
|
return True
|
|
70
70
|
if value.lower() in false_values:
|
|
71
71
|
return False
|
|
72
|
-
msg = f"Invalid boolean value: {value} for {field_name}"
|
|
72
|
+
msg = f"Invalid boolean value: {value!r} for {field_name}"
|
|
73
73
|
raise EnvironmentVarValueError(msg)
|
|
74
74
|
|
|
75
75
|
|
|
@@ -89,7 +89,7 @@ def interpret_int_env(value: str, field_name: str) -> int:
|
|
|
89
89
|
try:
|
|
90
90
|
return int(value)
|
|
91
91
|
except ValueError as ve:
|
|
92
|
-
msg = f"Invalid integer value: {value} for {field_name}"
|
|
92
|
+
msg = f"Invalid integer value: {value!r} for {field_name}"
|
|
93
93
|
raise EnvironmentVarValueError(msg) from ve
|
|
94
94
|
|
|
95
95
|
|
|
@@ -108,7 +108,7 @@ def interpret_existing_path_env(value: str, field_name: str) -> ExistingPath:
|
|
|
108
108
|
"""
|
|
109
109
|
path = Path(value)
|
|
110
110
|
if not path.exists():
|
|
111
|
-
msg = f"Path does not exist: {path} for {field_name}"
|
|
111
|
+
msg = f"Path does not exist: {path!r} for {field_name}"
|
|
112
112
|
raise EnvironmentVarValueError(msg)
|
|
113
113
|
return path
|
|
114
114
|
|
|
@@ -143,7 +143,7 @@ def interpret_enum_env(value: str, field_type: GenericType, field_name: str) ->
|
|
|
143
143
|
try:
|
|
144
144
|
return field_type(value)
|
|
145
145
|
except ValueError as ve:
|
|
146
|
-
msg = f"Invalid enum value: {value} for {field_name}"
|
|
146
|
+
msg = f"Invalid enum value: {value!r} for {field_name}"
|
|
147
147
|
raise EnvironmentVarValueError(msg) from ve
|
|
148
148
|
|
|
149
149
|
|
|
@@ -169,6 +169,8 @@ def interpret_env_var_value(
|
|
|
169
169
|
msg = f"Union types are not supported for environment variables: {field_name}."
|
|
170
170
|
raise ValueError(msg)
|
|
171
171
|
|
|
172
|
+
value = value.strip()
|
|
173
|
+
|
|
172
174
|
if field_type is bool:
|
|
173
175
|
return interpret_boolean_env(value, field_name)
|
|
174
176
|
if field_type is str:
|
|
@@ -475,7 +477,7 @@ class EnvironmentVariables:
|
|
|
475
477
|
# Whether to use the system installed bun. If set to false, bun will be bundled with the app.
|
|
476
478
|
REFLEX_USE_SYSTEM_BUN: EnvVar[bool] = env_var(False)
|
|
477
479
|
|
|
478
|
-
# The working directory for the
|
|
480
|
+
# The working directory for the frontend directory.
|
|
479
481
|
REFLEX_WEB_WORKDIR: EnvVar[Path] = env_var(Path(constants.Dirs.WEB))
|
|
480
482
|
|
|
481
483
|
# The working directory for the states directory.
|
|
@@ -604,3 +606,73 @@ class EnvironmentVariables:
|
|
|
604
606
|
|
|
605
607
|
|
|
606
608
|
environment = EnvironmentVariables()
|
|
609
|
+
|
|
610
|
+
try:
|
|
611
|
+
from dotenv import load_dotenv
|
|
612
|
+
except ImportError:
|
|
613
|
+
load_dotenv = None
|
|
614
|
+
|
|
615
|
+
|
|
616
|
+
def _paths_from_env_files(env_files: str) -> list[Path]:
|
|
617
|
+
"""Convert a string of paths separated by os.pathsep into a list of Path objects.
|
|
618
|
+
|
|
619
|
+
Args:
|
|
620
|
+
env_files: The string of paths.
|
|
621
|
+
|
|
622
|
+
Returns:
|
|
623
|
+
A list of Path objects.
|
|
624
|
+
"""
|
|
625
|
+
# load env files in reverse order
|
|
626
|
+
return list(
|
|
627
|
+
reversed(
|
|
628
|
+
[
|
|
629
|
+
Path(path)
|
|
630
|
+
for path_element in env_files.split(os.pathsep)
|
|
631
|
+
if (path := path_element.strip())
|
|
632
|
+
]
|
|
633
|
+
)
|
|
634
|
+
)
|
|
635
|
+
|
|
636
|
+
|
|
637
|
+
def _load_dotenv_from_files(files: list[Path]):
|
|
638
|
+
"""Load environment variables from a list of files.
|
|
639
|
+
|
|
640
|
+
Args:
|
|
641
|
+
files: A list of Path objects representing the environment variable files.
|
|
642
|
+
"""
|
|
643
|
+
from reflex.utils import console
|
|
644
|
+
|
|
645
|
+
if not files:
|
|
646
|
+
return
|
|
647
|
+
|
|
648
|
+
if load_dotenv is None:
|
|
649
|
+
console.error(
|
|
650
|
+
"""The `python-dotenv` package is required to load environment variables from a file. Run `pip install "python-dotenv>=1.1.0"`."""
|
|
651
|
+
)
|
|
652
|
+
return
|
|
653
|
+
|
|
654
|
+
for env_file in files:
|
|
655
|
+
if env_file.exists():
|
|
656
|
+
load_dotenv(env_file, override=True)
|
|
657
|
+
|
|
658
|
+
|
|
659
|
+
def _paths_from_environment() -> list[Path]:
|
|
660
|
+
"""Get the paths from the REFLEX_ENV_FILE environment variable.
|
|
661
|
+
|
|
662
|
+
Returns:
|
|
663
|
+
A list of Path objects.
|
|
664
|
+
"""
|
|
665
|
+
env_files = os.environ.get("REFLEX_ENV_FILE")
|
|
666
|
+
if not env_files:
|
|
667
|
+
return []
|
|
668
|
+
|
|
669
|
+
return _paths_from_env_files(env_files)
|
|
670
|
+
|
|
671
|
+
|
|
672
|
+
def _load_dotenv_from_env():
|
|
673
|
+
"""Load environment variables from paths specified in REFLEX_ENV_FILE."""
|
|
674
|
+
_load_dotenv_from_files(_paths_from_environment())
|
|
675
|
+
|
|
676
|
+
|
|
677
|
+
# Load the env files at import time if they are set in the ENV_FILE environment variable.
|
|
678
|
+
_load_dotenv_from_env()
|