reflex 0.7.7a2__py3-none-any.whl → 0.7.8__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/web/utils/state.js +26 -16
- reflex/admin.py +1 -1
- reflex/app.py +6 -17
- reflex/app_mixins/lifespan.py +1 -1
- reflex/base.py +2 -2
- reflex/compiler/compiler.py +8 -7
- reflex/compiler/utils.py +6 -5
- reflex/components/base/app_wrap.pyi +18 -17
- reflex/components/base/bare.py +2 -1
- reflex/components/base/body.pyi +18 -17
- reflex/components/base/document.pyi +82 -81
- reflex/components/base/error_boundary.pyi +19 -18
- reflex/components/base/fragment.pyi +18 -17
- reflex/components/base/head.pyi +34 -33
- reflex/components/base/link.pyi +34 -33
- reflex/components/base/meta.pyi +66 -65
- reflex/components/base/script.pyi +21 -20
- reflex/components/base/strict_mode.pyi +18 -17
- reflex/components/component.py +20 -36
- reflex/components/core/auto_scroll.pyi +18 -17
- reflex/components/core/banner.pyi +98 -97
- reflex/components/core/breakpoints.py +1 -1
- reflex/components/core/client_side_routing.pyi +34 -33
- reflex/components/core/clipboard.py +1 -1
- reflex/components/core/clipboard.pyi +19 -18
- reflex/components/core/cond.py +2 -2
- reflex/components/core/debounce.py +3 -3
- reflex/components/core/debounce.pyi +20 -19
- reflex/components/core/foreach.py +2 -1
- reflex/components/core/html.pyi +18 -17
- reflex/components/core/match.py +2 -2
- reflex/components/core/sticky.pyi +66 -65
- reflex/components/core/upload.py +7 -10
- reflex/components/core/upload.pyi +86 -85
- reflex/components/datadisplay/code.pyi +34 -33
- reflex/components/datadisplay/dataeditor.py +3 -2
- reflex/components/datadisplay/dataeditor.pyi +35 -68
- reflex/components/datadisplay/shiki_code_block.pyi +50 -49
- reflex/components/el/element.pyi +18 -17
- reflex/components/el/elements/base.pyi +18 -17
- reflex/components/el/elements/forms.py +2 -1
- reflex/components/el/elements/forms.pyi +290 -332
- reflex/components/el/elements/inline.pyi +450 -449
- reflex/components/el/elements/media.pyi +402 -401
- reflex/components/el/elements/metadata.pyi +98 -97
- reflex/components/el/elements/other.pyi +114 -113
- reflex/components/el/elements/scripts.pyi +50 -49
- reflex/components/el/elements/sectioning.pyi +242 -241
- reflex/components/el/elements/tables.pyi +162 -161
- reflex/components/el/elements/typography.pyi +242 -241
- reflex/components/gridjs/datatable.py +3 -2
- reflex/components/gridjs/datatable.pyi +35 -34
- reflex/components/lucide/icon.pyi +50 -49
- reflex/components/markdown/markdown.py +2 -1
- reflex/components/markdown/markdown.pyi +18 -17
- reflex/components/moment/moment.pyi +19 -18
- reflex/components/next/base.pyi +18 -17
- reflex/components/next/image.pyi +20 -19
- reflex/components/next/link.pyi +18 -17
- reflex/components/next/video.pyi +18 -17
- reflex/components/plotly/plotly.py +3 -3
- reflex/components/plotly/plotly.pyi +326 -325
- reflex/components/radix/primitives/accordion.py +2 -1
- reflex/components/radix/primitives/accordion.pyi +115 -114
- reflex/components/radix/primitives/base.pyi +34 -33
- reflex/components/radix/primitives/drawer.py +2 -1
- reflex/components/radix/primitives/drawer.pyi +187 -186
- reflex/components/radix/primitives/form.pyi +168 -182
- reflex/components/radix/primitives/progress.pyi +82 -81
- reflex/components/radix/primitives/slider.py +2 -1
- reflex/components/radix/primitives/slider.pyi +84 -83
- reflex/components/radix/themes/base.pyi +130 -129
- reflex/components/radix/themes/color_mode.pyi +51 -50
- reflex/components/radix/themes/components/alert_dialog.pyi +118 -117
- reflex/components/radix/themes/components/aspect_ratio.pyi +18 -17
- reflex/components/radix/themes/components/avatar.pyi +18 -17
- reflex/components/radix/themes/components/badge.pyi +18 -17
- reflex/components/radix/themes/components/button.pyi +18 -17
- reflex/components/radix/themes/components/callout.pyi +82 -81
- reflex/components/radix/themes/components/card.pyi +18 -17
- reflex/components/radix/themes/components/checkbox.pyi +53 -52
- reflex/components/radix/themes/components/checkbox_cards.pyi +34 -33
- reflex/components/radix/themes/components/checkbox_group.py +2 -1
- reflex/components/radix/themes/components/checkbox_group.pyi +34 -33
- reflex/components/radix/themes/components/context_menu.pyi +225 -224
- reflex/components/radix/themes/components/data_list.pyi +66 -65
- reflex/components/radix/themes/components/dialog.pyi +121 -120
- reflex/components/radix/themes/components/dropdown_menu.pyi +142 -141
- reflex/components/radix/themes/components/hover_card.pyi +68 -67
- reflex/components/radix/themes/components/icon_button.pyi +18 -17
- reflex/components/radix/themes/components/inset.pyi +18 -17
- reflex/components/radix/themes/components/popover.pyi +73 -72
- reflex/components/radix/themes/components/progress.pyi +18 -17
- reflex/components/radix/themes/components/radio.pyi +18 -17
- reflex/components/radix/themes/components/radio_cards.pyi +35 -34
- reflex/components/radix/themes/components/radio_group.py +2 -1
- reflex/components/radix/themes/components/radio_group.pyi +67 -66
- reflex/components/radix/themes/components/scroll_area.pyi +18 -17
- reflex/components/radix/themes/components/segmented_control.py +2 -1
- reflex/components/radix/themes/components/segmented_control.pyi +35 -34
- reflex/components/radix/themes/components/select.py +2 -1
- reflex/components/radix/themes/components/select.pyi +155 -154
- reflex/components/radix/themes/components/separator.pyi +18 -17
- reflex/components/radix/themes/components/skeleton.pyi +18 -17
- reflex/components/radix/themes/components/slider.py +2 -1
- reflex/components/radix/themes/components/slider.pyi +20 -31
- reflex/components/radix/themes/components/spinner.pyi +18 -17
- reflex/components/radix/themes/components/switch.pyi +19 -18
- reflex/components/radix/themes/components/table.pyi +114 -113
- reflex/components/radix/themes/components/tabs.pyi +84 -83
- reflex/components/radix/themes/components/text_area.pyi +21 -24
- reflex/components/radix/themes/components/text_field.pyi +56 -63
- reflex/components/radix/themes/components/tooltip.py +2 -2
- reflex/components/radix/themes/components/tooltip.pyi +21 -20
- reflex/components/radix/themes/layout/base.pyi +18 -17
- reflex/components/radix/themes/layout/box.pyi +18 -17
- reflex/components/radix/themes/layout/center.pyi +18 -17
- reflex/components/radix/themes/layout/container.pyi +18 -17
- reflex/components/radix/themes/layout/flex.pyi +18 -17
- reflex/components/radix/themes/layout/grid.pyi +18 -17
- reflex/components/radix/themes/layout/list.py +2 -1
- reflex/components/radix/themes/layout/list.pyi +82 -81
- reflex/components/radix/themes/layout/section.pyi +18 -17
- reflex/components/radix/themes/layout/spacer.pyi +18 -17
- reflex/components/radix/themes/layout/stack.pyi +50 -49
- reflex/components/radix/themes/typography/blockquote.pyi +18 -17
- reflex/components/radix/themes/typography/code.pyi +18 -17
- reflex/components/radix/themes/typography/heading.pyi +18 -17
- reflex/components/radix/themes/typography/link.pyi +18 -17
- reflex/components/radix/themes/typography/text.pyi +114 -113
- reflex/components/react_player/audio.pyi +34 -36
- reflex/components/react_player/react_player.pyi +34 -33
- reflex/components/react_player/video.pyi +34 -36
- reflex/components/recharts/cartesian.py +7 -6
- reflex/components/recharts/cartesian.pyi +302 -301
- reflex/components/recharts/charts.py +2 -1
- reflex/components/recharts/charts.pyi +177 -176
- reflex/components/recharts/general.py +3 -2
- reflex/components/recharts/general.pyi +99 -98
- reflex/components/recharts/polar.py +9 -8
- reflex/components/recharts/polar.pyi +62 -61
- reflex/components/recharts/recharts.pyi +34 -33
- reflex/components/sonner/toast.pyi +19 -18
- reflex/components/suneditor/editor.py +22 -24
- reflex/components/suneditor/editor.pyi +27 -28
- reflex/components/tags/cond_tag.py +3 -3
- reflex/components/tags/iter_tag.py +2 -1
- reflex/components/tags/tag.py +3 -2
- reflex/config.py +27 -17
- reflex/constants/installer.py +4 -4
- reflex/constants/route.py +2 -3
- reflex/constants/utils.py +4 -3
- reflex/event.py +56 -28
- reflex/experimental/client_state.py +3 -2
- reflex/experimental/layout.pyi +84 -83
- reflex/istate/data.py +1 -1
- reflex/istate/storage.py +2 -2
- reflex/model.py +3 -3
- reflex/page.py +3 -2
- reflex/state.py +56 -57
- reflex/style.py +3 -2
- reflex/testing.py +12 -21
- reflex/utils/codespaces.py +14 -15
- reflex/utils/decorator.py +2 -1
- reflex/utils/exec.py +1 -1
- reflex/utils/format.py +2 -2
- reflex/utils/imports.py +6 -8
- reflex/utils/misc.py +2 -1
- reflex/utils/net.py +2 -1
- reflex/utils/prerequisites.py +12 -5
- reflex/utils/processes.py +6 -5
- reflex/utils/pyi_generator.py +6 -5
- reflex/utils/serializers.py +13 -25
- reflex/utils/types.py +34 -46
- reflex/vars/base.py +60 -56
- reflex/vars/dep_tracking.py +4 -4
- reflex/vars/function.py +13 -36
- reflex/vars/number.py +5 -17
- reflex/vars/object.py +9 -16
- reflex/vars/sequence.py +11 -23
- {reflex-0.7.7a2.dist-info → reflex-0.7.8.dist-info}/METADATA +1 -1
- {reflex-0.7.7a2.dist-info → reflex-0.7.8.dist-info}/RECORD +185 -185
- {reflex-0.7.7a2.dist-info → reflex-0.7.8.dist-info}/WHEEL +0 -0
- {reflex-0.7.7a2.dist-info → reflex-0.7.8.dist-info}/entry_points.txt +0 -0
- {reflex-0.7.7a2.dist-info → reflex-0.7.8.dist-info}/licenses/LICENSE +0 -0
reflex/style.py
CHANGED
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
|
-
from
|
|
5
|
+
from collections.abc import Mapping
|
|
6
|
+
from typing import Any, Literal
|
|
6
7
|
|
|
7
8
|
from reflex import constants
|
|
8
9
|
from reflex.components.core.breakpoints import Breakpoints, breakpoints_values
|
|
@@ -28,7 +29,7 @@ color_mode_imports = {
|
|
|
28
29
|
}
|
|
29
30
|
|
|
30
31
|
|
|
31
|
-
def _color_mode_var(_js_expr: str, _var_type:
|
|
32
|
+
def _color_mode_var(_js_expr: str, _var_type: type = str) -> Var:
|
|
32
33
|
"""Create a Var that destructs the _js_expr from ColorModeContext.
|
|
33
34
|
|
|
34
35
|
Args:
|
reflex/testing.py
CHANGED
|
@@ -18,19 +18,10 @@ import textwrap
|
|
|
18
18
|
import threading
|
|
19
19
|
import time
|
|
20
20
|
import types
|
|
21
|
+
from collections.abc import AsyncIterator, Callable, Coroutine, Sequence
|
|
21
22
|
from http.server import SimpleHTTPRequestHandler
|
|
22
23
|
from pathlib import Path
|
|
23
|
-
from typing import
|
|
24
|
-
TYPE_CHECKING,
|
|
25
|
-
Any,
|
|
26
|
-
AsyncIterator,
|
|
27
|
-
Callable,
|
|
28
|
-
Coroutine,
|
|
29
|
-
Optional,
|
|
30
|
-
Sequence,
|
|
31
|
-
Type,
|
|
32
|
-
TypeVar,
|
|
33
|
-
)
|
|
24
|
+
from typing import TYPE_CHECKING, Any, TypeVar
|
|
34
25
|
|
|
35
26
|
import psutil
|
|
36
27
|
import uvicorn
|
|
@@ -124,7 +115,7 @@ class AppHarness:
|
|
|
124
115
|
backend_thread: threading.Thread | None = None
|
|
125
116
|
backend: uvicorn.Server | None = None
|
|
126
117
|
state_manager: StateManager | None = None
|
|
127
|
-
_frontends: list[
|
|
118
|
+
_frontends: list[WebDriver] = dataclasses.field(default_factory=list)
|
|
128
119
|
_decorated_pages: list = dataclasses.field(default_factory=list)
|
|
129
120
|
|
|
130
121
|
@classmethod
|
|
@@ -135,7 +126,7 @@ class AppHarness:
|
|
|
135
126
|
Callable[[], None] | types.ModuleType | str | functools.partial[Any] | None
|
|
136
127
|
) = None,
|
|
137
128
|
app_name: str | None = None,
|
|
138
|
-
) ->
|
|
129
|
+
) -> AppHarness:
|
|
139
130
|
"""Create an AppHarness instance at root.
|
|
140
131
|
|
|
141
132
|
Args:
|
|
@@ -371,7 +362,7 @@ class AppHarness:
|
|
|
371
362
|
# Set up the frontend.
|
|
372
363
|
with chdir(self.app_path):
|
|
373
364
|
config = reflex.config.get_config()
|
|
374
|
-
config.api_url = "http://{
|
|
365
|
+
config.api_url = "http://{}:{}".format(
|
|
375
366
|
*self._poll_for_servers().getsockname(),
|
|
376
367
|
)
|
|
377
368
|
reflex.utils.build.setup_frontend(self.app_path)
|
|
@@ -423,7 +414,7 @@ class AppHarness:
|
|
|
423
414
|
self.frontend_output_thread = threading.Thread(target=consume_frontend_output)
|
|
424
415
|
self.frontend_output_thread.start()
|
|
425
416
|
|
|
426
|
-
def start(self) ->
|
|
417
|
+
def start(self) -> AppHarness:
|
|
427
418
|
"""Start the backend in a new thread and dev frontend as a separate process.
|
|
428
419
|
|
|
429
420
|
Returns:
|
|
@@ -452,7 +443,7 @@ class AppHarness:
|
|
|
452
443
|
return f"{key} = {value!r}"
|
|
453
444
|
return inspect.getsource(value)
|
|
454
445
|
|
|
455
|
-
def __enter__(self) ->
|
|
446
|
+
def __enter__(self) -> AppHarness:
|
|
456
447
|
"""Contextmanager protocol for `start()`.
|
|
457
448
|
|
|
458
449
|
Returns:
|
|
@@ -599,12 +590,12 @@ class AppHarness:
|
|
|
599
590
|
|
|
600
591
|
def frontend(
|
|
601
592
|
self,
|
|
602
|
-
driver_clz:
|
|
593
|
+
driver_clz: type[WebDriver] | None = None,
|
|
603
594
|
driver_kwargs: dict[str, Any] | None = None,
|
|
604
595
|
driver_options: ArgOptions | None = None,
|
|
605
596
|
driver_option_args: list[str] | None = None,
|
|
606
597
|
driver_option_capabilities: dict[str, Any] | None = None,
|
|
607
|
-
) ->
|
|
598
|
+
) -> WebDriver:
|
|
608
599
|
"""Get a selenium webdriver instance pointed at the app.
|
|
609
600
|
|
|
610
601
|
Args:
|
|
@@ -743,7 +734,7 @@ class AppHarness:
|
|
|
743
734
|
|
|
744
735
|
def poll_for_content(
|
|
745
736
|
self,
|
|
746
|
-
element:
|
|
737
|
+
element: WebElement,
|
|
747
738
|
timeout: TimeoutType = None,
|
|
748
739
|
exp_not_equal: str = "",
|
|
749
740
|
) -> str:
|
|
@@ -771,7 +762,7 @@ class AppHarness:
|
|
|
771
762
|
|
|
772
763
|
def poll_for_value(
|
|
773
764
|
self,
|
|
774
|
-
element:
|
|
765
|
+
element: WebElement,
|
|
775
766
|
timeout: TimeoutType = None,
|
|
776
767
|
exp_not_equal: str | Sequence[str] = "",
|
|
777
768
|
) -> str | None:
|
|
@@ -940,7 +931,7 @@ class AppHarnessProd(AppHarness):
|
|
|
940
931
|
# Set up the frontend.
|
|
941
932
|
with chdir(self.app_path):
|
|
942
933
|
config = reflex.config.get_config()
|
|
943
|
-
config.api_url = "http://{
|
|
934
|
+
config.api_url = "http://{}:{}".format(
|
|
944
935
|
*self._poll_for_servers().getsockname(),
|
|
945
936
|
)
|
|
946
937
|
reflex.reflex.export(
|
reflex/utils/codespaces.py
CHANGED
|
@@ -21,28 +21,28 @@ def redirect_script() -> str:
|
|
|
21
21
|
Returns:
|
|
22
22
|
The redirect script as a string.
|
|
23
23
|
"""
|
|
24
|
-
return """
|
|
24
|
+
return f"""
|
|
25
25
|
const thisUrl = new URL(window.location.href);
|
|
26
26
|
const params = new URLSearchParams(thisUrl.search)
|
|
27
27
|
|
|
28
|
-
function doRedirect(url) {
|
|
29
|
-
if (!window.sessionStorage.getItem("authenticated_github_codespaces")) {
|
|
28
|
+
function doRedirect(url) {{
|
|
29
|
+
if (!window.sessionStorage.getItem("authenticated_github_codespaces")) {{
|
|
30
30
|
const a = document.createElement("a");
|
|
31
|
-
if (params.has("redirect_to")) {
|
|
31
|
+
if (params.has("redirect_to")) {{
|
|
32
32
|
a.href = params.get("redirect_to")
|
|
33
|
-
} else if (!window.location.href.startsWith(url)) {
|
|
34
|
-
a.href = url + `?redirect_to=${window.location.href}`
|
|
35
|
-
} else {
|
|
33
|
+
}} else if (!window.location.href.startsWith(url)) {{
|
|
34
|
+
a.href = url + `?redirect_to=${{window.location.href}}`
|
|
35
|
+
}} else {{
|
|
36
36
|
return
|
|
37
|
-
}
|
|
37
|
+
}}
|
|
38
38
|
a.hidden = true;
|
|
39
39
|
a.click();
|
|
40
40
|
a.remove();
|
|
41
41
|
window.sessionStorage.setItem("authenticated_github_codespaces", "true")
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
doRedirect("
|
|
45
|
-
"""
|
|
42
|
+
}}
|
|
43
|
+
}}
|
|
44
|
+
doRedirect("{Endpoint.AUTH_CODESPACE.get_url()}")
|
|
45
|
+
"""
|
|
46
46
|
|
|
47
47
|
|
|
48
48
|
def codespaces_port_forwarding_domain() -> str | None:
|
|
@@ -81,7 +81,7 @@ async def auth_codespace() -> HTMLResponse:
|
|
|
81
81
|
An HTML response with an embedded script to redirect back to the app.
|
|
82
82
|
"""
|
|
83
83
|
return HTMLResponse(
|
|
84
|
-
"""
|
|
84
|
+
f"""
|
|
85
85
|
<html>
|
|
86
86
|
<head>
|
|
87
87
|
<title>Reflex Github Codespace Forward Successfully Authenticated</title>
|
|
@@ -91,10 +91,9 @@ async def auth_codespace() -> HTMLResponse:
|
|
|
91
91
|
<h2>Successfully Authenticated</h2>
|
|
92
92
|
</center>
|
|
93
93
|
<script language="javascript">
|
|
94
|
-
|
|
94
|
+
{redirect_script()}
|
|
95
95
|
</script>
|
|
96
96
|
</body>
|
|
97
97
|
</html>
|
|
98
98
|
"""
|
|
99
|
-
% redirect_script()
|
|
100
99
|
)
|
reflex/utils/decorator.py
CHANGED
reflex/utils/exec.py
CHANGED
reflex/utils/format.py
CHANGED
|
@@ -6,7 +6,7 @@ import inspect
|
|
|
6
6
|
import json
|
|
7
7
|
import os
|
|
8
8
|
import re
|
|
9
|
-
from typing import TYPE_CHECKING, Any
|
|
9
|
+
from typing import TYPE_CHECKING, Any
|
|
10
10
|
|
|
11
11
|
from reflex import constants
|
|
12
12
|
from reflex.constants.state import FRONTEND_EVENT_STATE
|
|
@@ -369,7 +369,7 @@ def format_match(
|
|
|
369
369
|
|
|
370
370
|
|
|
371
371
|
def format_prop(
|
|
372
|
-
prop:
|
|
372
|
+
prop: Var | EventChain | ComponentStyle | str,
|
|
373
373
|
) -> int | float | str:
|
|
374
374
|
"""Format a prop.
|
|
375
375
|
|
reflex/utils/imports.py
CHANGED
|
@@ -4,7 +4,7 @@ from __future__ import annotations
|
|
|
4
4
|
|
|
5
5
|
import dataclasses
|
|
6
6
|
from collections import defaultdict
|
|
7
|
-
from
|
|
7
|
+
from collections.abc import Mapping, Sequence
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
def merge_imports(
|
|
@@ -18,7 +18,7 @@ def merge_imports(
|
|
|
18
18
|
Returns:
|
|
19
19
|
The merged import dicts.
|
|
20
20
|
"""
|
|
21
|
-
all_imports:
|
|
21
|
+
all_imports: defaultdict[str, list[ImportVar]] = defaultdict(list)
|
|
22
22
|
for import_dict in imports:
|
|
23
23
|
for lib, fields in (
|
|
24
24
|
import_dict if isinstance(import_dict, tuple) else import_dict.items()
|
|
@@ -31,10 +31,8 @@ def merge_imports(
|
|
|
31
31
|
)
|
|
32
32
|
if isinstance(fields, (list, tuple, set)):
|
|
33
33
|
all_imports[lib].extend(
|
|
34
|
-
(
|
|
35
|
-
|
|
36
|
-
for field in fields
|
|
37
|
-
)
|
|
34
|
+
ImportVar(field) if isinstance(field, str) else field
|
|
35
|
+
for field in fields
|
|
38
36
|
)
|
|
39
37
|
else:
|
|
40
38
|
all_imports[lib].append(
|
|
@@ -135,8 +133,8 @@ class ImportVar:
|
|
|
135
133
|
return self.tag or ""
|
|
136
134
|
|
|
137
135
|
|
|
138
|
-
ImportTypes =
|
|
139
|
-
ImmutableImportTypes =
|
|
136
|
+
ImportTypes = str | ImportVar | list[str | ImportVar] | list[ImportVar]
|
|
137
|
+
ImmutableImportTypes = str | ImportVar | Sequence[str | ImportVar]
|
|
140
138
|
ImportDict = dict[str, ImportTypes]
|
|
141
139
|
ImmutableImportDict = Mapping[str, ImmutableImportTypes]
|
|
142
140
|
ParsedImportDict = dict[str, list[ImportVar]]
|
reflex/utils/misc.py
CHANGED
reflex/utils/net.py
CHANGED
reflex/utils/prerequisites.py
CHANGED
|
@@ -20,10 +20,11 @@ import tempfile
|
|
|
20
20
|
import time
|
|
21
21
|
import typing
|
|
22
22
|
import zipfile
|
|
23
|
+
from collections.abc import Callable, Sequence
|
|
23
24
|
from datetime import datetime
|
|
24
25
|
from pathlib import Path
|
|
25
26
|
from types import ModuleType
|
|
26
|
-
from typing import
|
|
27
|
+
from typing import NamedTuple
|
|
27
28
|
from urllib.parse import urlparse
|
|
28
29
|
|
|
29
30
|
import httpx
|
|
@@ -38,6 +39,7 @@ from reflex import constants, model
|
|
|
38
39
|
from reflex.compiler import templates
|
|
39
40
|
from reflex.config import Config, environment, get_config
|
|
40
41
|
from reflex.utils import console, net, path_ops, processes
|
|
42
|
+
from reflex.utils.decorator import once
|
|
41
43
|
from reflex.utils.exceptions import (
|
|
42
44
|
GeneratedCodeHasNoFunctionDefsError,
|
|
43
45
|
SystemPackageMissingError,
|
|
@@ -987,6 +989,7 @@ def initialize_web_directory():
|
|
|
987
989
|
init_reflex_json(project_hash=project_hash)
|
|
988
990
|
|
|
989
991
|
|
|
992
|
+
@once
|
|
990
993
|
def _turbopack_flag() -> str:
|
|
991
994
|
return " --turbopack" if environment.REFLEX_USE_TURBOPACK.get() else ""
|
|
992
995
|
|
|
@@ -994,9 +997,13 @@ def _turbopack_flag() -> str:
|
|
|
994
997
|
def _compile_package_json():
|
|
995
998
|
return templates.PACKAGE_JSON.render(
|
|
996
999
|
scripts={
|
|
997
|
-
"dev": constants.PackageJson.Commands.DEV
|
|
998
|
-
"export": constants.PackageJson.Commands.EXPORT
|
|
999
|
-
|
|
1000
|
+
"dev": constants.PackageJson.Commands.DEV.format(flags=_turbopack_flag()),
|
|
1001
|
+
"export": constants.PackageJson.Commands.EXPORT.format(
|
|
1002
|
+
flags=_turbopack_flag()
|
|
1003
|
+
),
|
|
1004
|
+
"export_sitemap": constants.PackageJson.Commands.EXPORT_SITEMAP.format(
|
|
1005
|
+
flags=_turbopack_flag()
|
|
1006
|
+
),
|
|
1000
1007
|
"prod": constants.PackageJson.Commands.PROD,
|
|
1001
1008
|
},
|
|
1002
1009
|
dependencies=constants.PackageJson.DEPENDENCIES,
|
|
@@ -2042,7 +2049,7 @@ def _retrieve_cpu_info() -> CpuInfo | None:
|
|
|
2042
2049
|
)
|
|
2043
2050
|
|
|
2044
2051
|
|
|
2045
|
-
@functools.
|
|
2052
|
+
@functools.cache
|
|
2046
2053
|
def get_cpu_info() -> CpuInfo | None:
|
|
2047
2054
|
"""Get the CPU info of the underlining host.
|
|
2048
2055
|
|
reflex/utils/processes.py
CHANGED
|
@@ -8,9 +8,10 @@ import importlib.metadata
|
|
|
8
8
|
import os
|
|
9
9
|
import signal
|
|
10
10
|
import subprocess
|
|
11
|
+
from collections.abc import Callable, Generator, Sequence
|
|
11
12
|
from concurrent import futures
|
|
12
13
|
from pathlib import Path
|
|
13
|
-
from typing import Any,
|
|
14
|
+
from typing import Any, Literal, overload
|
|
14
15
|
|
|
15
16
|
import psutil
|
|
16
17
|
import typer
|
|
@@ -261,7 +262,7 @@ def run_concurrently_context(
|
|
|
261
262
|
executor.shutdown(wait=False)
|
|
262
263
|
|
|
263
264
|
|
|
264
|
-
def run_concurrently(*fns: Callable |
|
|
265
|
+
def run_concurrently(*fns: Callable | tuple) -> None:
|
|
265
266
|
"""Run functions concurrently in a thread pool.
|
|
266
267
|
|
|
267
268
|
Args:
|
|
@@ -277,7 +278,7 @@ def stream_logs(
|
|
|
277
278
|
progress: Progress | None = None,
|
|
278
279
|
suppress_errors: bool = False,
|
|
279
280
|
analytics_enabled: bool = False,
|
|
280
|
-
prior_logs:
|
|
281
|
+
prior_logs: tuple[tuple[str, ...], ...] = (),
|
|
281
282
|
):
|
|
282
283
|
"""Stream the logs for a process.
|
|
283
284
|
|
|
@@ -371,7 +372,7 @@ def show_status(
|
|
|
371
372
|
process: subprocess.Popen,
|
|
372
373
|
suppress_errors: bool = False,
|
|
373
374
|
analytics_enabled: bool = False,
|
|
374
|
-
prior_logs:
|
|
375
|
+
prior_logs: tuple[tuple[str, ...], ...] = (),
|
|
375
376
|
) -> list[str]:
|
|
376
377
|
"""Show the status of a process.
|
|
377
378
|
|
|
@@ -451,7 +452,7 @@ def run_process_with_fallbacks(
|
|
|
451
452
|
show_status_message: str,
|
|
452
453
|
fallbacks: str | Sequence[str] | Sequence[Sequence[str]] | None = None,
|
|
453
454
|
analytics_enabled: bool = False,
|
|
454
|
-
prior_logs:
|
|
455
|
+
prior_logs: tuple[tuple[str, ...], ...] = (),
|
|
455
456
|
**kwargs,
|
|
456
457
|
):
|
|
457
458
|
"""Run subprocess and retry using fallback command if initial command fails.
|
reflex/utils/pyi_generator.py
CHANGED
|
@@ -11,6 +11,7 @@ import logging
|
|
|
11
11
|
import re
|
|
12
12
|
import subprocess
|
|
13
13
|
import typing
|
|
14
|
+
from collections.abc import Callable, Iterable, Sequence
|
|
14
15
|
from fileinput import FileInput
|
|
15
16
|
from hashlib import md5
|
|
16
17
|
from inspect import getfullargspec
|
|
@@ -18,7 +19,7 @@ from itertools import chain
|
|
|
18
19
|
from multiprocessing import Pool, cpu_count
|
|
19
20
|
from pathlib import Path
|
|
20
21
|
from types import ModuleType, SimpleNamespace, UnionType
|
|
21
|
-
from typing import Any,
|
|
22
|
+
from typing import Any, get_args, get_origin
|
|
22
23
|
|
|
23
24
|
from reflex.components.component import Component
|
|
24
25
|
from reflex.utils import types as rx_types
|
|
@@ -167,7 +168,7 @@ def _get_type_hint(
|
|
|
167
168
|
|
|
168
169
|
if args:
|
|
169
170
|
inner_container_type_args = (
|
|
170
|
-
sorted(
|
|
171
|
+
sorted(repr(arg) for arg in args)
|
|
171
172
|
if rx_types.is_literal(value)
|
|
172
173
|
else [
|
|
173
174
|
_get_type_hint(arg, type_hint_globals, is_optional=False)
|
|
@@ -246,7 +247,7 @@ def _generate_imports(
|
|
|
246
247
|
]
|
|
247
248
|
|
|
248
249
|
|
|
249
|
-
def _generate_docstrings(clzs: list[
|
|
250
|
+
def _generate_docstrings(clzs: list[type[Component]], props: list[str]) -> str:
|
|
250
251
|
"""Generate the docstrings for the create method.
|
|
251
252
|
|
|
252
253
|
Args:
|
|
@@ -335,7 +336,7 @@ def _extract_func_kwargs_as_ast_nodes(
|
|
|
335
336
|
|
|
336
337
|
def _extract_class_props_as_ast_nodes(
|
|
337
338
|
func: Callable,
|
|
338
|
-
clzs: list[
|
|
339
|
+
clzs: list[type],
|
|
339
340
|
type_hint_globals: dict[str, Any],
|
|
340
341
|
extract_real_default: bool = False,
|
|
341
342
|
) -> list[tuple[ast.arg, ast.Constant | None]]:
|
|
@@ -769,7 +770,7 @@ class StubGenerator(ast.NodeTransformer):
|
|
|
769
770
|
"""A node transformer that will generate the stubs for a given module."""
|
|
770
771
|
|
|
771
772
|
def __init__(
|
|
772
|
-
self, module: ModuleType, classes: dict[str,
|
|
773
|
+
self, module: ModuleType, classes: dict[str, type[Component | SimpleNamespace]]
|
|
773
774
|
):
|
|
774
775
|
"""Initialize the stub generator.
|
|
775
776
|
|
reflex/utils/serializers.py
CHANGED
|
@@ -8,20 +8,11 @@ import functools
|
|
|
8
8
|
import inspect
|
|
9
9
|
import json
|
|
10
10
|
import warnings
|
|
11
|
+
from collections.abc import Callable, Sequence
|
|
11
12
|
from datetime import date, datetime, time, timedelta
|
|
12
13
|
from enum import Enum
|
|
13
14
|
from pathlib import Path
|
|
14
|
-
from typing import
|
|
15
|
-
Any,
|
|
16
|
-
Callable,
|
|
17
|
-
Literal,
|
|
18
|
-
Sequence,
|
|
19
|
-
Type,
|
|
20
|
-
TypeVar,
|
|
21
|
-
Union,
|
|
22
|
-
get_type_hints,
|
|
23
|
-
overload,
|
|
24
|
-
)
|
|
15
|
+
from typing import Any, Literal, TypeVar, get_type_hints, overload
|
|
25
16
|
from uuid import UUID
|
|
26
17
|
|
|
27
18
|
from pydantic import BaseModel as BaseModelV2
|
|
@@ -33,14 +24,14 @@ from reflex.utils import console, types
|
|
|
33
24
|
|
|
34
25
|
# Mapping from type to a serializer.
|
|
35
26
|
# The serializer should convert the type to a JSON object.
|
|
36
|
-
SerializedType =
|
|
27
|
+
SerializedType = str | bool | int | float | list | dict | None
|
|
37
28
|
|
|
38
29
|
|
|
39
30
|
Serializer = Callable[[Any], SerializedType]
|
|
40
31
|
|
|
41
32
|
|
|
42
|
-
SERIALIZERS: dict[
|
|
43
|
-
SERIALIZER_TYPES: dict[
|
|
33
|
+
SERIALIZERS: dict[type, Serializer] = {}
|
|
34
|
+
SERIALIZER_TYPES: dict[type, type] = {}
|
|
44
35
|
|
|
45
36
|
SERIALIZED_FUNCTION = TypeVar("SERIALIZED_FUNCTION", bound=Serializer)
|
|
46
37
|
|
|
@@ -48,7 +39,7 @@ SERIALIZED_FUNCTION = TypeVar("SERIALIZED_FUNCTION", bound=Serializer)
|
|
|
48
39
|
@overload
|
|
49
40
|
def serializer(
|
|
50
41
|
fn: None = None,
|
|
51
|
-
to:
|
|
42
|
+
to: type[SerializedType] | None = None,
|
|
52
43
|
overwrite: bool | None = None,
|
|
53
44
|
) -> Callable[[SERIALIZED_FUNCTION], SERIALIZED_FUNCTION]: ...
|
|
54
45
|
|
|
@@ -56,7 +47,7 @@ def serializer(
|
|
|
56
47
|
@overload
|
|
57
48
|
def serializer(
|
|
58
49
|
fn: SERIALIZED_FUNCTION,
|
|
59
|
-
to:
|
|
50
|
+
to: type[SerializedType] | None = None,
|
|
60
51
|
overwrite: bool | None = None,
|
|
61
52
|
) -> SERIALIZED_FUNCTION: ...
|
|
62
53
|
|
|
@@ -146,10 +137,7 @@ def serialize(value: Any) -> SerializedType | None: ...
|
|
|
146
137
|
|
|
147
138
|
def serialize(
|
|
148
139
|
value: Any, get_type: bool = False
|
|
149
|
-
) ->
|
|
150
|
-
SerializedType | None,
|
|
151
|
-
tuple[SerializedType | None, types.GenericType | None],
|
|
152
|
-
]:
|
|
140
|
+
) -> SerializedType | None | tuple[SerializedType | None, types.GenericType | None]:
|
|
153
141
|
"""Serialize the value to a JSON string.
|
|
154
142
|
|
|
155
143
|
Args:
|
|
@@ -182,7 +170,7 @@ def serialize(
|
|
|
182
170
|
|
|
183
171
|
|
|
184
172
|
@functools.lru_cache
|
|
185
|
-
def get_serializer(type_:
|
|
173
|
+
def get_serializer(type_: type) -> Serializer | None:
|
|
186
174
|
"""Get the serializer for the type.
|
|
187
175
|
|
|
188
176
|
Args:
|
|
@@ -206,7 +194,7 @@ def get_serializer(type_: Type) -> Serializer | None:
|
|
|
206
194
|
|
|
207
195
|
|
|
208
196
|
@functools.lru_cache
|
|
209
|
-
def get_serializer_type(type_:
|
|
197
|
+
def get_serializer_type(type_: type) -> type | None:
|
|
210
198
|
"""Get the converted type for the type after serializing.
|
|
211
199
|
|
|
212
200
|
Args:
|
|
@@ -229,7 +217,7 @@ def get_serializer_type(type_: Type) -> Type | None:
|
|
|
229
217
|
return None
|
|
230
218
|
|
|
231
219
|
|
|
232
|
-
def has_serializer(type_:
|
|
220
|
+
def has_serializer(type_: type, into_type: type | None = None) -> bool:
|
|
233
221
|
"""Check if there is a serializer for the type.
|
|
234
222
|
|
|
235
223
|
Args:
|
|
@@ -245,7 +233,7 @@ def has_serializer(type_: Type, into_type: Type | None = None) -> bool:
|
|
|
245
233
|
)
|
|
246
234
|
|
|
247
235
|
|
|
248
|
-
def can_serialize(type_:
|
|
236
|
+
def can_serialize(type_: type, into_type: type | None = None) -> bool:
|
|
249
237
|
"""Check if there is a serializer for the type.
|
|
250
238
|
|
|
251
239
|
Args:
|
|
@@ -347,7 +335,7 @@ def serialize_sequence(value: Sequence) -> list:
|
|
|
347
335
|
|
|
348
336
|
|
|
349
337
|
@serializer(to=str)
|
|
350
|
-
def serialize_datetime(dt:
|
|
338
|
+
def serialize_datetime(dt: date | datetime | time | timedelta) -> str:
|
|
351
339
|
"""Serialize a datetime to a JSON string.
|
|
352
340
|
|
|
353
341
|
Args:
|