reflex 0.7.0a4__py3-none-any.whl → 0.7.1a1__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/components/reflex/radix_themes_color_mode_provider.js +3 -1
- reflex/__init__.py +1 -0
- reflex/__init__.pyi +1 -0
- reflex/app.py +251 -68
- reflex/base.py +4 -10
- reflex/compiler/compiler.py +46 -12
- reflex/compiler/templates.py +1 -2
- reflex/compiler/utils.py +23 -14
- reflex/components/base/bare.py +109 -16
- reflex/components/component.py +179 -124
- reflex/components/core/__init__.py +1 -0
- reflex/components/core/__init__.pyi +1 -0
- reflex/components/core/auto_scroll.py +111 -0
- reflex/components/core/auto_scroll.pyi +284 -0
- reflex/components/core/banner.py +35 -5
- reflex/components/core/banner.pyi +398 -36
- reflex/components/core/breakpoints.py +1 -1
- reflex/components/core/cond.py +0 -8
- reflex/components/core/foreach.py +12 -2
- reflex/components/core/html.pyi +200 -19
- reflex/components/core/match.py +4 -4
- reflex/components/core/sticky.py +4 -30
- reflex/components/core/sticky.pyi +874 -90
- reflex/components/core/upload.py +3 -5
- reflex/components/core/upload.pyi +2 -4
- reflex/components/datadisplay/code.py +36 -10
- reflex/components/datadisplay/code.pyi +1 -1
- reflex/components/datadisplay/dataeditor.py +1 -3
- reflex/components/datadisplay/dataeditor.pyi +1 -3
- reflex/components/el/elements/base.py +95 -17
- reflex/components/el/elements/base.pyi +278 -19
- reflex/components/el/elements/forms.py +124 -102
- reflex/components/el/elements/forms.pyi +2787 -365
- reflex/components/el/elements/inline.py +24 -15
- reflex/components/el/elements/inline.pyi +5655 -546
- reflex/components/el/elements/media.py +79 -95
- reflex/components/el/elements/media.pyi +5167 -565
- reflex/components/el/elements/metadata.py +19 -17
- reflex/components/el/elements/metadata.pyi +841 -89
- reflex/components/el/elements/other.py +3 -5
- reflex/components/el/elements/other.pyi +1404 -137
- reflex/components/el/elements/scripts.py +10 -13
- reflex/components/el/elements/scripts.pyi +634 -65
- reflex/components/el/elements/sectioning.pyi +3001 -286
- reflex/components/el/elements/tables.py +14 -35
- reflex/components/el/elements/tables.pyi +2029 -218
- reflex/components/el/elements/typography.py +10 -13
- reflex/components/el/elements/typography.pyi +3014 -297
- reflex/components/lucide/icon.py +22 -6
- reflex/components/markdown/markdown.py +30 -10
- reflex/components/markdown/markdown.pyi +3 -2
- reflex/components/plotly/plotly.py +1 -3
- reflex/components/plotly/plotly.pyi +1 -3
- reflex/components/radix/primitives/form.pyi +624 -93
- reflex/components/radix/themes/color_mode.py +1 -1
- reflex/components/radix/themes/color_mode.pyi +213 -31
- reflex/components/radix/themes/components/alert_dialog.pyi +199 -18
- reflex/components/radix/themes/components/badge.pyi +199 -18
- reflex/components/radix/themes/components/button.pyi +213 -31
- reflex/components/radix/themes/components/callout.pyi +1000 -95
- reflex/components/radix/themes/components/card.pyi +199 -18
- reflex/components/radix/themes/components/context_menu.py +79 -1
- reflex/components/radix/themes/components/context_menu.pyi +320 -1
- reflex/components/radix/themes/components/dialog.pyi +199 -18
- reflex/components/radix/themes/components/hover_card.pyi +199 -18
- reflex/components/radix/themes/components/icon_button.pyi +213 -31
- reflex/components/radix/themes/components/inset.pyi +199 -18
- reflex/components/radix/themes/components/popover.pyi +199 -18
- reflex/components/radix/themes/components/table.pyi +1437 -154
- reflex/components/radix/themes/components/text_area.py +2 -2
- reflex/components/radix/themes/components/text_area.pyi +201 -20
- reflex/components/radix/themes/components/text_field.py +1 -1
- reflex/components/radix/themes/components/text_field.pyi +444 -88
- reflex/components/radix/themes/layout/box.pyi +200 -19
- reflex/components/radix/themes/layout/center.pyi +199 -18
- reflex/components/radix/themes/layout/container.pyi +199 -18
- reflex/components/radix/themes/layout/flex.pyi +199 -18
- reflex/components/radix/themes/layout/grid.pyi +199 -18
- reflex/components/radix/themes/layout/list.pyi +604 -57
- reflex/components/radix/themes/layout/section.pyi +199 -18
- reflex/components/radix/themes/layout/spacer.pyi +199 -18
- reflex/components/radix/themes/layout/stack.pyi +597 -54
- reflex/components/radix/themes/typography/blockquote.pyi +200 -19
- reflex/components/radix/themes/typography/code.pyi +199 -18
- reflex/components/radix/themes/typography/heading.pyi +199 -18
- reflex/components/radix/themes/typography/link.pyi +238 -28
- reflex/components/radix/themes/typography/text.pyi +1394 -127
- reflex/components/react_player/react_player.py +1 -1
- reflex/components/react_player/react_player.pyi +1 -3
- reflex/components/sonner/toast.py +19 -1
- reflex/components/sonner/toast.pyi +10 -1
- reflex/components/tags/iter_tag.py +4 -0
- reflex/components/tags/tag.py +3 -3
- reflex/config.py +187 -28
- reflex/constants/__init__.py +2 -0
- reflex/constants/base.py +6 -0
- reflex/constants/compiler.py +9 -0
- reflex/constants/event.py +1 -0
- reflex/constants/installer.py +4 -5
- reflex/constants/utils.py +1 -3
- reflex/event.py +7 -16
- reflex/experimental/layout.pyi +597 -54
- reflex/py.typed +0 -0
- reflex/reflex.py +44 -48
- reflex/state.py +49 -44
- reflex/style.py +6 -4
- reflex/testing.py +2 -0
- reflex/utils/build.py +12 -0
- reflex/utils/console.py +4 -0
- reflex/utils/decorator.py +25 -0
- reflex/utils/exec.py +92 -34
- reflex/utils/format.py +35 -6
- reflex/utils/path_ops.py +32 -1
- reflex/utils/prerequisites.py +54 -10
- reflex/utils/processes.py +12 -13
- reflex/utils/serializers.py +20 -43
- reflex/utils/telemetry.py +4 -15
- reflex/utils/types.py +36 -66
- reflex/vars/base.py +53 -76
- reflex/vars/function.py +17 -5
- reflex/vars/number.py +1 -1
- reflex/vars/sequence.py +80 -4
- {reflex-0.7.0a4.dist-info → reflex-0.7.1a1.dist-info}/METADATA +4 -5
- {reflex-0.7.0a4.dist-info → reflex-0.7.1a1.dist-info}/RECORD +127 -123
- {reflex-0.7.0a4.dist-info → reflex-0.7.1a1.dist-info}/LICENSE +0 -0
- {reflex-0.7.0a4.dist-info → reflex-0.7.1a1.dist-info}/WHEEL +0 -0
- {reflex-0.7.0a4.dist-info → reflex-0.7.1a1.dist-info}/entry_points.txt +0 -0
|
@@ -3,9 +3,7 @@
|
|
|
3
3
|
# ------------------- DO NOT EDIT ----------------------
|
|
4
4
|
# This file was generated by `reflex/utils/pyi_generator.py`!
|
|
5
5
|
# ------------------------------------------------------
|
|
6
|
-
from typing import Any, Dict, Optional, Union, overload
|
|
7
|
-
|
|
8
|
-
from typing_extensions import TypedDict
|
|
6
|
+
from typing import Any, Dict, Optional, TypedDict, Union, overload
|
|
9
7
|
|
|
10
8
|
from reflex.components.component import NoSSRComponent
|
|
11
9
|
from reflex.event import EventType
|
|
@@ -8,6 +8,7 @@ from reflex.base import Base
|
|
|
8
8
|
from reflex.components.component import Component, ComponentNamespace
|
|
9
9
|
from reflex.components.lucide.icon import Icon
|
|
10
10
|
from reflex.components.props import NoExtrasAllowedProps, PropsBase
|
|
11
|
+
from reflex.constants.base import Dirs
|
|
11
12
|
from reflex.event import EventSpec, run_script
|
|
12
13
|
from reflex.style import Style, resolved_color_mode
|
|
13
14
|
from reflex.utils import format
|
|
@@ -27,7 +28,10 @@ LiteralPosition = Literal[
|
|
|
27
28
|
"bottom-right",
|
|
28
29
|
]
|
|
29
30
|
|
|
30
|
-
toast_ref = Var(
|
|
31
|
+
toast_ref = Var(
|
|
32
|
+
_js_expr="refs['__toast']",
|
|
33
|
+
_var_data=VarData(imports={f"$/{Dirs.STATE_PATH}": [ImportVar(tag="refs")]}),
|
|
34
|
+
)
|
|
31
35
|
|
|
32
36
|
|
|
33
37
|
class ToastAction(Base):
|
|
@@ -327,6 +331,19 @@ class Toaster(Component):
|
|
|
327
331
|
"""
|
|
328
332
|
return Toaster.send_toast(message, level="success", **kwargs)
|
|
329
333
|
|
|
334
|
+
@staticmethod
|
|
335
|
+
def toast_loading(message: str | Var = "", **kwargs: Any):
|
|
336
|
+
"""Display a loading toast message.
|
|
337
|
+
|
|
338
|
+
Args:
|
|
339
|
+
message: The message to display.
|
|
340
|
+
**kwargs: Additional toast props.
|
|
341
|
+
|
|
342
|
+
Returns:
|
|
343
|
+
The toast event.
|
|
344
|
+
"""
|
|
345
|
+
return Toaster.send_toast(message, level="loading", **kwargs)
|
|
346
|
+
|
|
330
347
|
@staticmethod
|
|
331
348
|
def toast_dismiss(id: Var | str | None = None):
|
|
332
349
|
"""Dismiss a toast.
|
|
@@ -378,6 +395,7 @@ class ToastNamespace(ComponentNamespace):
|
|
|
378
395
|
warning = staticmethod(Toaster.toast_warning)
|
|
379
396
|
error = staticmethod(Toaster.toast_error)
|
|
380
397
|
success = staticmethod(Toaster.toast_success)
|
|
398
|
+
loading = staticmethod(Toaster.toast_loading)
|
|
381
399
|
dismiss = staticmethod(Toaster.toast_dismiss)
|
|
382
400
|
__call__ = staticmethod(Toaster.send_toast)
|
|
383
401
|
|
|
@@ -9,9 +9,12 @@ from reflex.base import Base
|
|
|
9
9
|
from reflex.components.component import Component, ComponentNamespace
|
|
10
10
|
from reflex.components.lucide.icon import Icon
|
|
11
11
|
from reflex.components.props import NoExtrasAllowedProps, PropsBase
|
|
12
|
+
from reflex.constants.base import Dirs
|
|
12
13
|
from reflex.event import EventSpec, EventType
|
|
13
14
|
from reflex.style import Style
|
|
15
|
+
from reflex.utils.imports import ImportVar
|
|
14
16
|
from reflex.utils.serializers import serializer
|
|
17
|
+
from reflex.vars import VarData
|
|
15
18
|
from reflex.vars.base import Var
|
|
16
19
|
|
|
17
20
|
LiteralPosition = Literal[
|
|
@@ -22,7 +25,10 @@ LiteralPosition = Literal[
|
|
|
22
25
|
"bottom-center",
|
|
23
26
|
"bottom-right",
|
|
24
27
|
]
|
|
25
|
-
toast_ref = Var(
|
|
28
|
+
toast_ref = Var(
|
|
29
|
+
_js_expr="refs['__toast']",
|
|
30
|
+
_var_data=VarData(imports={f"$/{Dirs.STATE_PATH}": [ImportVar(tag="refs")]}),
|
|
31
|
+
)
|
|
26
32
|
|
|
27
33
|
class ToastAction(Base):
|
|
28
34
|
label: str
|
|
@@ -70,6 +76,8 @@ class Toaster(Component):
|
|
|
70
76
|
@staticmethod
|
|
71
77
|
def toast_success(message: str | Var = "", **kwargs: Any): ...
|
|
72
78
|
@staticmethod
|
|
79
|
+
def toast_loading(message: str | Var = "", **kwargs: Any): ...
|
|
80
|
+
@staticmethod
|
|
73
81
|
def toast_dismiss(id: Var | str | None = None): ...
|
|
74
82
|
@overload
|
|
75
83
|
@classmethod
|
|
@@ -172,6 +180,7 @@ class ToastNamespace(ComponentNamespace):
|
|
|
172
180
|
warning = staticmethod(Toaster.toast_warning)
|
|
173
181
|
error = staticmethod(Toaster.toast_error)
|
|
174
182
|
success = staticmethod(Toaster.toast_success)
|
|
183
|
+
loading = staticmethod(Toaster.toast_loading)
|
|
175
184
|
dismiss = staticmethod(Toaster.toast_dismiss)
|
|
176
185
|
|
|
177
186
|
@staticmethod
|
|
@@ -134,6 +134,10 @@ class IterTag(Tag):
|
|
|
134
134
|
if isinstance(component, (Foreach, Cond)):
|
|
135
135
|
component = Fragment.create(component)
|
|
136
136
|
|
|
137
|
+
# If the component is a tuple, unpack and wrap it in a fragment.
|
|
138
|
+
if isinstance(component, tuple):
|
|
139
|
+
component = Fragment.create(*component)
|
|
140
|
+
|
|
137
141
|
# Set the component key.
|
|
138
142
|
if component.key is None:
|
|
139
143
|
component.key = index
|
reflex/components/tags/tag.py
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
5
|
import dataclasses
|
|
6
|
-
from typing import Any, Dict, List, Optional, Sequence
|
|
6
|
+
from typing import Any, Dict, List, Mapping, Optional, Sequence
|
|
7
7
|
|
|
8
8
|
from reflex.event import EventChain
|
|
9
9
|
from reflex.utils import format, types
|
|
@@ -101,9 +101,9 @@ class Tag:
|
|
|
101
101
|
"""
|
|
102
102
|
self.props.update(
|
|
103
103
|
{
|
|
104
|
-
format.to_camel_case(name,
|
|
104
|
+
format.to_camel_case(name, treat_hyphens_as_underscores=False): (
|
|
105
105
|
prop
|
|
106
|
-
if types._isinstance(prop,
|
|
106
|
+
if types._isinstance(prop, (EventChain, Mapping))
|
|
107
107
|
else LiteralVar.create(prop)
|
|
108
108
|
) # rx.color is always a string
|
|
109
109
|
for name, prop in kwargs.items()
|
reflex/config.py
CHANGED
|
@@ -2,20 +2,26 @@
|
|
|
2
2
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
|
+
import concurrent.futures
|
|
5
6
|
import dataclasses
|
|
6
7
|
import enum
|
|
7
8
|
import importlib
|
|
8
9
|
import inspect
|
|
10
|
+
import multiprocessing
|
|
9
11
|
import os
|
|
12
|
+
import platform
|
|
10
13
|
import sys
|
|
11
14
|
import threading
|
|
12
15
|
import urllib.parse
|
|
16
|
+
from functools import lru_cache
|
|
13
17
|
from importlib.util import find_spec
|
|
14
18
|
from pathlib import Path
|
|
15
19
|
from types import ModuleType
|
|
16
20
|
from typing import (
|
|
17
21
|
TYPE_CHECKING,
|
|
22
|
+
Annotated,
|
|
18
23
|
Any,
|
|
24
|
+
Callable,
|
|
19
25
|
Dict,
|
|
20
26
|
Generic,
|
|
21
27
|
List,
|
|
@@ -23,23 +29,23 @@ from typing import (
|
|
|
23
29
|
Set,
|
|
24
30
|
TypeVar,
|
|
25
31
|
get_args,
|
|
32
|
+
get_origin,
|
|
33
|
+
get_type_hints,
|
|
26
34
|
)
|
|
27
35
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
from reflex.utils.exceptions import ConfigError, EnvironmentVarValueError
|
|
31
|
-
from reflex.utils.types import GenericType, is_union, value_inside_optional
|
|
32
|
-
|
|
33
|
-
try:
|
|
34
|
-
import pydantic.v1 as pydantic
|
|
35
|
-
except ModuleNotFoundError:
|
|
36
|
-
import pydantic
|
|
37
|
-
|
|
36
|
+
import pydantic.v1 as pydantic
|
|
38
37
|
from reflex_cli.constants.hosting import Hosting
|
|
39
38
|
|
|
40
39
|
from reflex import constants
|
|
41
40
|
from reflex.base import Base
|
|
42
41
|
from reflex.utils import console
|
|
42
|
+
from reflex.utils.exceptions import ConfigError, EnvironmentVarValueError
|
|
43
|
+
from reflex.utils.types import GenericType, is_union, value_inside_optional
|
|
44
|
+
|
|
45
|
+
try:
|
|
46
|
+
from dotenv import load_dotenv # pyright: ignore [reportMissingImports]
|
|
47
|
+
except ImportError:
|
|
48
|
+
load_dotenv = None
|
|
43
49
|
|
|
44
50
|
|
|
45
51
|
class DBConfig(Base):
|
|
@@ -304,6 +310,15 @@ def interpret_env_var_value(
|
|
|
304
310
|
return interpret_path_env(value, field_name)
|
|
305
311
|
elif field_type is ExistingPath:
|
|
306
312
|
return interpret_existing_path_env(value, field_name)
|
|
313
|
+
elif get_origin(field_type) is list:
|
|
314
|
+
return [
|
|
315
|
+
interpret_env_var_value(
|
|
316
|
+
v,
|
|
317
|
+
get_args(field_type)[0],
|
|
318
|
+
f"{field_name}[{i}]",
|
|
319
|
+
)
|
|
320
|
+
for i, v in enumerate(value.split(":"))
|
|
321
|
+
]
|
|
307
322
|
elif inspect.isclass(field_type) and issubclass(field_type, enum.Enum):
|
|
308
323
|
return interpret_enum_env(value, field_type, field_name)
|
|
309
324
|
|
|
@@ -387,7 +402,24 @@ class EnvVar(Generic[T]):
|
|
|
387
402
|
else:
|
|
388
403
|
if isinstance(value, enum.Enum):
|
|
389
404
|
value = value.value
|
|
390
|
-
|
|
405
|
+
if isinstance(value, list):
|
|
406
|
+
str_value = ":".join(str(v) for v in value)
|
|
407
|
+
else:
|
|
408
|
+
str_value = str(value)
|
|
409
|
+
os.environ[self.name] = str_value
|
|
410
|
+
|
|
411
|
+
|
|
412
|
+
@lru_cache()
|
|
413
|
+
def get_type_hints_environment(cls: type) -> dict[str, Any]:
|
|
414
|
+
"""Get the type hints for the environment variables.
|
|
415
|
+
|
|
416
|
+
Args:
|
|
417
|
+
cls: The class.
|
|
418
|
+
|
|
419
|
+
Returns:
|
|
420
|
+
The type hints.
|
|
421
|
+
"""
|
|
422
|
+
return get_type_hints(cls)
|
|
391
423
|
|
|
392
424
|
|
|
393
425
|
class env_var: # noqa: N801 # pyright: ignore [reportRedeclaration]
|
|
@@ -416,7 +448,9 @@ class env_var: # noqa: N801 # pyright: ignore [reportRedeclaration]
|
|
|
416
448
|
"""
|
|
417
449
|
self.name = name
|
|
418
450
|
|
|
419
|
-
def __get__(
|
|
451
|
+
def __get__(
|
|
452
|
+
self, instance: EnvironmentVariables, owner: type[EnvironmentVariables]
|
|
453
|
+
):
|
|
420
454
|
"""Get the EnvVar instance.
|
|
421
455
|
|
|
422
456
|
Args:
|
|
@@ -426,7 +460,7 @@ class env_var: # noqa: N801 # pyright: ignore [reportRedeclaration]
|
|
|
426
460
|
Returns:
|
|
427
461
|
The EnvVar instance.
|
|
428
462
|
"""
|
|
429
|
-
type_ = get_args(
|
|
463
|
+
type_ = get_args(get_type_hints_environment(owner)[self.name])[0]
|
|
430
464
|
env_name = self.name
|
|
431
465
|
if self.internal:
|
|
432
466
|
env_name = f"__{env_name}"
|
|
@@ -463,9 +497,103 @@ class PerformanceMode(enum.Enum):
|
|
|
463
497
|
OFF = "off"
|
|
464
498
|
|
|
465
499
|
|
|
500
|
+
class ExecutorType(enum.Enum):
|
|
501
|
+
"""Executor for compiling the frontend."""
|
|
502
|
+
|
|
503
|
+
THREAD = "thread"
|
|
504
|
+
PROCESS = "process"
|
|
505
|
+
MAIN_THREAD = "main_thread"
|
|
506
|
+
|
|
507
|
+
@classmethod
|
|
508
|
+
def get_executor_from_environment(cls):
|
|
509
|
+
"""Get the executor based on the environment variables.
|
|
510
|
+
|
|
511
|
+
Returns:
|
|
512
|
+
The executor.
|
|
513
|
+
"""
|
|
514
|
+
executor_type = environment.REFLEX_COMPILE_EXECUTOR.get()
|
|
515
|
+
|
|
516
|
+
reflex_compile_processes = environment.REFLEX_COMPILE_PROCESSES.get()
|
|
517
|
+
reflex_compile_threads = environment.REFLEX_COMPILE_THREADS.get()
|
|
518
|
+
# By default, use the main thread. Unless the user has specified a different executor.
|
|
519
|
+
# Using a process pool is much faster, but not supported on all platforms. It's gated behind a flag.
|
|
520
|
+
if executor_type is None:
|
|
521
|
+
if (
|
|
522
|
+
platform.system() not in ("Linux", "Darwin")
|
|
523
|
+
and reflex_compile_processes is not None
|
|
524
|
+
):
|
|
525
|
+
console.warn("Multiprocessing is only supported on Linux and MacOS.")
|
|
526
|
+
|
|
527
|
+
if (
|
|
528
|
+
platform.system() in ("Linux", "Darwin")
|
|
529
|
+
and reflex_compile_processes is not None
|
|
530
|
+
):
|
|
531
|
+
if reflex_compile_processes == 0:
|
|
532
|
+
console.warn(
|
|
533
|
+
"Number of processes must be greater than 0. If you want to use the default number of processes, set REFLEX_COMPILE_EXECUTOR to 'process'. Defaulting to None."
|
|
534
|
+
)
|
|
535
|
+
reflex_compile_processes = None
|
|
536
|
+
elif reflex_compile_processes < 0:
|
|
537
|
+
console.warn(
|
|
538
|
+
"Number of processes must be greater than 0. Defaulting to None."
|
|
539
|
+
)
|
|
540
|
+
reflex_compile_processes = None
|
|
541
|
+
executor_type = ExecutorType.PROCESS
|
|
542
|
+
elif reflex_compile_threads is not None:
|
|
543
|
+
if reflex_compile_threads == 0:
|
|
544
|
+
console.warn(
|
|
545
|
+
"Number of threads must be greater than 0. If you want to use the default number of threads, set REFLEX_COMPILE_EXECUTOR to 'thread'. Defaulting to None."
|
|
546
|
+
)
|
|
547
|
+
reflex_compile_threads = None
|
|
548
|
+
elif reflex_compile_threads < 0:
|
|
549
|
+
console.warn(
|
|
550
|
+
"Number of threads must be greater than 0. Defaulting to None."
|
|
551
|
+
)
|
|
552
|
+
reflex_compile_threads = None
|
|
553
|
+
executor_type = ExecutorType.THREAD
|
|
554
|
+
else:
|
|
555
|
+
executor_type = ExecutorType.MAIN_THREAD
|
|
556
|
+
|
|
557
|
+
match executor_type:
|
|
558
|
+
case ExecutorType.PROCESS:
|
|
559
|
+
executor = concurrent.futures.ProcessPoolExecutor(
|
|
560
|
+
max_workers=reflex_compile_processes,
|
|
561
|
+
mp_context=multiprocessing.get_context("fork"),
|
|
562
|
+
)
|
|
563
|
+
case ExecutorType.THREAD:
|
|
564
|
+
executor = concurrent.futures.ThreadPoolExecutor(
|
|
565
|
+
max_workers=reflex_compile_threads
|
|
566
|
+
)
|
|
567
|
+
case ExecutorType.MAIN_THREAD:
|
|
568
|
+
FUTURE_RESULT_TYPE = TypeVar("FUTURE_RESULT_TYPE")
|
|
569
|
+
|
|
570
|
+
class MainThreadExecutor:
|
|
571
|
+
def __enter__(self):
|
|
572
|
+
return self
|
|
573
|
+
|
|
574
|
+
def __exit__(self, *args):
|
|
575
|
+
pass
|
|
576
|
+
|
|
577
|
+
def submit(
|
|
578
|
+
self, fn: Callable[..., FUTURE_RESULT_TYPE], *args, **kwargs
|
|
579
|
+
) -> concurrent.futures.Future[FUTURE_RESULT_TYPE]:
|
|
580
|
+
future_job = concurrent.futures.Future()
|
|
581
|
+
future_job.set_result(fn(*args, **kwargs))
|
|
582
|
+
return future_job
|
|
583
|
+
|
|
584
|
+
executor = MainThreadExecutor()
|
|
585
|
+
|
|
586
|
+
return executor
|
|
587
|
+
|
|
588
|
+
|
|
466
589
|
class EnvironmentVariables:
|
|
467
590
|
"""Environment variables class to instantiate environment variables."""
|
|
468
591
|
|
|
592
|
+
# Indicate the current command that was invoked in the reflex CLI.
|
|
593
|
+
REFLEX_COMPILE_CONTEXT: EnvVar[constants.CompileContext] = env_var(
|
|
594
|
+
constants.CompileContext.UNDEFINED, internal=True
|
|
595
|
+
)
|
|
596
|
+
|
|
469
597
|
# Whether to use npm over bun to install frontend packages.
|
|
470
598
|
REFLEX_USE_NPM: EnvVar[bool] = env_var(False)
|
|
471
599
|
|
|
@@ -504,6 +632,8 @@ class EnvironmentVariables:
|
|
|
504
632
|
Path(constants.Dirs.UPLOADED_FILES)
|
|
505
633
|
)
|
|
506
634
|
|
|
635
|
+
REFLEX_COMPILE_EXECUTOR: EnvVar[Optional[ExecutorType]] = env_var(None)
|
|
636
|
+
|
|
507
637
|
# Whether to use separate processes to compile the frontend and how many. If not set, defaults to thread executor.
|
|
508
638
|
REFLEX_COMPILE_PROCESSES: EnvVar[Optional[int]] = env_var(None)
|
|
509
639
|
|
|
@@ -511,7 +641,7 @@ class EnvironmentVariables:
|
|
|
511
641
|
REFLEX_COMPILE_THREADS: EnvVar[Optional[int]] = env_var(None)
|
|
512
642
|
|
|
513
643
|
# The directory to store reflex dependencies.
|
|
514
|
-
REFLEX_DIR: EnvVar[Path] = env_var(
|
|
644
|
+
REFLEX_DIR: EnvVar[Path] = env_var(constants.Reflex.DIR)
|
|
515
645
|
|
|
516
646
|
# Whether to print the SQL queries if the log level is INFO or lower.
|
|
517
647
|
SQLALCHEMY_ECHO: EnvVar[bool] = env_var(False)
|
|
@@ -544,6 +674,12 @@ class EnvironmentVariables:
|
|
|
544
674
|
# Whether to run the frontend only. Exclusive with REFLEX_BACKEND_ONLY.
|
|
545
675
|
REFLEX_FRONTEND_ONLY: EnvVar[bool] = env_var(False)
|
|
546
676
|
|
|
677
|
+
# The port to run the frontend on.
|
|
678
|
+
REFLEX_FRONTEND_PORT: EnvVar[int | None] = env_var(None)
|
|
679
|
+
|
|
680
|
+
# The port to run the backend on.
|
|
681
|
+
REFLEX_BACKEND_PORT: EnvVar[int | None] = env_var(None)
|
|
682
|
+
|
|
547
683
|
# Reflex internal env to reload the config.
|
|
548
684
|
RELOAD_CONFIG: EnvVar[bool] = env_var(False, internal=True)
|
|
549
685
|
|
|
@@ -563,7 +699,7 @@ class EnvironmentVariables:
|
|
|
563
699
|
REFLEX_CHECK_LATEST_VERSION: EnvVar[bool] = env_var(True)
|
|
564
700
|
|
|
565
701
|
# In which performance mode to run the app.
|
|
566
|
-
REFLEX_PERF_MODE: EnvVar[
|
|
702
|
+
REFLEX_PERF_MODE: EnvVar[PerformanceMode] = env_var(PerformanceMode.WARN)
|
|
567
703
|
|
|
568
704
|
# The maximum size of the reflex state in kilobytes.
|
|
569
705
|
REFLEX_STATE_SIZE_LIMIT: EnvVar[int] = env_var(1000)
|
|
@@ -571,6 +707,21 @@ class EnvironmentVariables:
|
|
|
571
707
|
# Whether to use the turbopack bundler.
|
|
572
708
|
REFLEX_USE_TURBOPACK: EnvVar[bool] = env_var(True)
|
|
573
709
|
|
|
710
|
+
# Additional paths to include in the hot reload. Separated by a colon.
|
|
711
|
+
REFLEX_HOT_RELOAD_INCLUDE_PATHS: EnvVar[List[Path]] = env_var([])
|
|
712
|
+
|
|
713
|
+
# Paths to exclude from the hot reload. Takes precedence over include paths. Separated by a colon.
|
|
714
|
+
REFLEX_HOT_RELOAD_EXCLUDE_PATHS: EnvVar[List[Path]] = env_var([])
|
|
715
|
+
|
|
716
|
+
# Enables different behavior for when the backend would do a cold start if it was inactive.
|
|
717
|
+
REFLEX_DOES_BACKEND_COLD_START: EnvVar[bool] = env_var(False)
|
|
718
|
+
|
|
719
|
+
# The timeout for the backend to do a cold start in seconds.
|
|
720
|
+
REFLEX_BACKEND_COLD_START_TIMEOUT: EnvVar[int] = env_var(10)
|
|
721
|
+
|
|
722
|
+
# Used by flexgen to enumerate the pages.
|
|
723
|
+
REFLEX_ADD_ALL_ROUTES_ENDPOINT: EnvVar[bool] = env_var(False)
|
|
724
|
+
|
|
574
725
|
|
|
575
726
|
environment = EnvironmentVariables()
|
|
576
727
|
|
|
@@ -604,6 +755,7 @@ class Config(Base):
|
|
|
604
755
|
"""Pydantic config for the config."""
|
|
605
756
|
|
|
606
757
|
validate_assignment = True
|
|
758
|
+
use_enum_values = False
|
|
607
759
|
|
|
608
760
|
# The name of the app (should match the name of the app directory).
|
|
609
761
|
app_name: str
|
|
@@ -615,19 +767,21 @@ class Config(Base):
|
|
|
615
767
|
loglevel: constants.LogLevel = constants.LogLevel.DEFAULT
|
|
616
768
|
|
|
617
769
|
# The port to run the frontend on. NOTE: When running in dev mode, the next available port will be used if this is taken.
|
|
618
|
-
frontend_port: int =
|
|
770
|
+
frontend_port: int | None = None
|
|
619
771
|
|
|
620
772
|
# The path to run the frontend on. For example, "/app" will run the frontend on http://localhost:3000/app
|
|
621
773
|
frontend_path: str = ""
|
|
622
774
|
|
|
623
775
|
# The port to run the backend on. NOTE: When running in dev mode, the next available port will be used if this is taken.
|
|
624
|
-
backend_port: int =
|
|
776
|
+
backend_port: int | None = None
|
|
625
777
|
|
|
626
778
|
# The backend url the frontend will connect to. This must be updated if the backend is hosted elsewhere, or in production.
|
|
627
|
-
api_url: str = f"http://localhost:{
|
|
779
|
+
api_url: str = f"http://localhost:{constants.DefaultPorts.BACKEND_PORT}"
|
|
628
780
|
|
|
629
781
|
# The url the frontend will be hosted on.
|
|
630
|
-
deploy_url: Optional[str] =
|
|
782
|
+
deploy_url: Optional[str] = (
|
|
783
|
+
f"http://localhost:{constants.DefaultPorts.FRONTEND_PORT}"
|
|
784
|
+
)
|
|
631
785
|
|
|
632
786
|
# The url the backend will be hosted on.
|
|
633
787
|
backend_host: str = "0.0.0.0"
|
|
@@ -679,7 +833,7 @@ class Config(Base):
|
|
|
679
833
|
# Number of gunicorn workers from user
|
|
680
834
|
gunicorn_workers: Optional[int] = None
|
|
681
835
|
|
|
682
|
-
# Number of requests before a worker is restarted
|
|
836
|
+
# Number of requests before a worker is restarted; set to 0 to disable
|
|
683
837
|
gunicorn_max_requests: int = 100
|
|
684
838
|
|
|
685
839
|
# Variance limit for max requests; gunicorn only
|
|
@@ -704,11 +858,14 @@ class Config(Base):
|
|
|
704
858
|
env_file: Optional[str] = None
|
|
705
859
|
|
|
706
860
|
# Whether to display the sticky "Built with Reflex" badge on all pages.
|
|
707
|
-
show_built_with_reflex: bool =
|
|
861
|
+
show_built_with_reflex: Optional[bool] = None
|
|
708
862
|
|
|
709
863
|
# Whether the app is running in the reflex cloud environment.
|
|
710
864
|
is_reflex_cloud: bool = False
|
|
711
865
|
|
|
866
|
+
# Extra overlay function to run after the app is built. Formatted such that `from path_0.path_1... import path[-1]`, and calling it with no arguments would work. For example, "reflex.components.moment.momnet".
|
|
867
|
+
extra_overlay_function: Optional[str] = None
|
|
868
|
+
|
|
712
869
|
def __init__(self, *args, **kwargs):
|
|
713
870
|
"""Initialize the config values.
|
|
714
871
|
|
|
@@ -731,6 +888,9 @@ class Config(Base):
|
|
|
731
888
|
self._non_default_attributes.update(kwargs)
|
|
732
889
|
self._replace_defaults(**kwargs)
|
|
733
890
|
|
|
891
|
+
# Set the log level for this process
|
|
892
|
+
console.set_log_level(self.loglevel)
|
|
893
|
+
|
|
734
894
|
if (
|
|
735
895
|
self.state_manager_mode == constants.StateManagerMode.REDIS
|
|
736
896
|
and not self.redis_url
|
|
@@ -770,16 +930,15 @@ class Config(Base):
|
|
|
770
930
|
Returns:
|
|
771
931
|
The updated config values.
|
|
772
932
|
"""
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
# load env file if exists
|
|
778
|
-
load_dotenv(self.env_file, override=True)
|
|
779
|
-
except ImportError:
|
|
933
|
+
env_file = self.env_file or os.environ.get("ENV_FILE", None)
|
|
934
|
+
if env_file:
|
|
935
|
+
if load_dotenv is None:
|
|
780
936
|
console.error(
|
|
781
937
|
"""The `python-dotenv` package is required to load environment variables from a file. Run `pip install "python-dotenv>=1.0.1"`."""
|
|
782
938
|
)
|
|
939
|
+
else:
|
|
940
|
+
# load env file if exists
|
|
941
|
+
load_dotenv(env_file, override=True)
|
|
783
942
|
|
|
784
943
|
updated_values = {}
|
|
785
944
|
# Iterate over the fields.
|
reflex/constants/__init__.py
CHANGED
|
@@ -25,6 +25,7 @@ from .base import (
|
|
|
25
25
|
from .compiler import (
|
|
26
26
|
NOCOMPILE_FILE,
|
|
27
27
|
SETTER_PREFIX,
|
|
28
|
+
CompileContext,
|
|
28
29
|
CompileVars,
|
|
29
30
|
ComponentName,
|
|
30
31
|
Ext,
|
|
@@ -65,6 +66,7 @@ __ALL__ = [
|
|
|
65
66
|
ColorMode,
|
|
66
67
|
Config,
|
|
67
68
|
COOKIES,
|
|
69
|
+
CompileContext,
|
|
68
70
|
ComponentName,
|
|
69
71
|
CustomComponents,
|
|
70
72
|
DefaultPage,
|
reflex/constants/base.py
CHANGED
|
@@ -53,6 +53,12 @@ class Dirs(SimpleNamespace):
|
|
|
53
53
|
POSTCSS_JS = "postcss.config.js"
|
|
54
54
|
# The name of the states directory.
|
|
55
55
|
STATES = ".states"
|
|
56
|
+
# Where compilation artifacts for the backend are stored.
|
|
57
|
+
BACKEND = "backend"
|
|
58
|
+
# JSON-encoded list of page routes that need to be evaluated on the backend.
|
|
59
|
+
STATEFUL_PAGES = "stateful_pages.json"
|
|
60
|
+
# Marker file indicating that upload component was used in the frontend.
|
|
61
|
+
UPLOAD_IS_USED = "upload_is_used"
|
|
56
62
|
|
|
57
63
|
|
|
58
64
|
class Reflex(SimpleNamespace):
|
reflex/constants/compiler.py
CHANGED
|
@@ -111,6 +111,15 @@ class ComponentName(Enum):
|
|
|
111
111
|
return self.value.lower() + Ext.ZIP
|
|
112
112
|
|
|
113
113
|
|
|
114
|
+
class CompileContext(str, Enum):
|
|
115
|
+
"""The context in which the compiler is running."""
|
|
116
|
+
|
|
117
|
+
RUN = "run"
|
|
118
|
+
EXPORT = "export"
|
|
119
|
+
DEPLOY = "deploy"
|
|
120
|
+
UNDEFINED = "undefined"
|
|
121
|
+
|
|
122
|
+
|
|
114
123
|
class Imports(SimpleNamespace):
|
|
115
124
|
"""Common sets of import vars."""
|
|
116
125
|
|
reflex/constants/event.py
CHANGED
reflex/constants/installer.py
CHANGED
|
@@ -178,16 +178,15 @@ class PackageJson(SimpleNamespace):
|
|
|
178
178
|
PATH = "package.json"
|
|
179
179
|
|
|
180
180
|
DEPENDENCIES = {
|
|
181
|
-
"@babel/standalone": "7.26.6",
|
|
182
181
|
"@emotion/react": "11.14.0",
|
|
183
182
|
"axios": "1.7.9",
|
|
184
183
|
"json5": "2.2.3",
|
|
185
|
-
"next": "15.1.
|
|
184
|
+
"next": "15.1.7",
|
|
186
185
|
"next-sitemap": "4.2.3",
|
|
187
186
|
"next-themes": "0.4.4",
|
|
188
|
-
"react": "
|
|
189
|
-
"react-dom": "
|
|
190
|
-
"react-focus-lock": "2.13.
|
|
187
|
+
"react": "19.0.0",
|
|
188
|
+
"react-dom": "19.0.0",
|
|
189
|
+
"react-focus-lock": "2.13.6",
|
|
191
190
|
"socket.io-client": "4.8.1",
|
|
192
191
|
"universal-cookie": "7.2.2",
|
|
193
192
|
}
|
reflex/constants/utils.py
CHANGED
reflex/event.py
CHANGED
|
@@ -10,32 +10,28 @@ from base64 import b64encode
|
|
|
10
10
|
from functools import partial
|
|
11
11
|
from typing import (
|
|
12
12
|
TYPE_CHECKING,
|
|
13
|
+
Annotated,
|
|
13
14
|
Any,
|
|
14
15
|
Callable,
|
|
15
16
|
Dict,
|
|
16
17
|
Generic,
|
|
17
18
|
List,
|
|
18
19
|
Optional,
|
|
20
|
+
Protocol,
|
|
19
21
|
Sequence,
|
|
20
22
|
Tuple,
|
|
21
23
|
Type,
|
|
22
|
-
Union,
|
|
23
|
-
get_type_hints,
|
|
24
|
-
overload,
|
|
25
|
-
)
|
|
26
|
-
|
|
27
|
-
from typing_extensions import (
|
|
28
|
-
Protocol,
|
|
29
|
-
Self,
|
|
30
|
-
TypeAliasType,
|
|
31
24
|
TypedDict,
|
|
32
25
|
TypeVar,
|
|
33
|
-
|
|
34
|
-
Unpack,
|
|
26
|
+
Union,
|
|
35
27
|
get_args,
|
|
36
28
|
get_origin,
|
|
29
|
+
get_type_hints,
|
|
30
|
+
overload,
|
|
37
31
|
)
|
|
38
32
|
|
|
33
|
+
from typing_extensions import Self, TypeAliasType, TypeVarTuple, Unpack
|
|
34
|
+
|
|
39
35
|
from reflex import constants
|
|
40
36
|
from reflex.constants.compiler import CompileVars, Hooks, Imports
|
|
41
37
|
from reflex.constants.state import FRONTEND_EVENT_STATE
|
|
@@ -59,11 +55,6 @@ from reflex.vars.function import (
|
|
|
59
55
|
)
|
|
60
56
|
from reflex.vars.object import ObjectVar
|
|
61
57
|
|
|
62
|
-
try:
|
|
63
|
-
from typing import Annotated
|
|
64
|
-
except ImportError:
|
|
65
|
-
from typing_extensions import Annotated
|
|
66
|
-
|
|
67
58
|
|
|
68
59
|
@dataclasses.dataclass(
|
|
69
60
|
init=True,
|