Compare commits
7 Commits
main
...
release/re
Author | SHA1 | Date | |
---|---|---|---|
![]() |
e471dc199a | ||
![]() |
00e0c44b84 | ||
![]() |
6be3a819b7 | ||
![]() |
2e100e38d9 | ||
![]() |
cdbe7f820b | ||
![]() |
5a5be8162b | ||
![]() |
85cae46ed3 |
@ -1,6 +1,6 @@
|
|||||||
[tool.poetry]
|
[tool.poetry]
|
||||||
name = "reflex"
|
name = "reflex"
|
||||||
version = "0.6.4dev1"
|
version = "0.6.4"
|
||||||
description = "Web apps in pure Python."
|
description = "Web apps in pure Python."
|
||||||
license = "Apache-2.0"
|
license = "Apache-2.0"
|
||||||
authors = [
|
authors = [
|
||||||
@ -104,4 +104,4 @@ lint.pydocstyle.convention = "google"
|
|||||||
|
|
||||||
[tool.pytest.ini_options]
|
[tool.pytest.ini_options]
|
||||||
asyncio_default_fixture_loop_scope = "function"
|
asyncio_default_fixture_loop_scope = "function"
|
||||||
asyncio_mode = "auto"
|
asyncio_mode = "auto"
|
||||||
|
@ -645,7 +645,7 @@ class Component(BaseComponent, ABC):
|
|||||||
# Look for component specific triggers,
|
# Look for component specific triggers,
|
||||||
# e.g. variable declared as EventHandler types.
|
# e.g. variable declared as EventHandler types.
|
||||||
for field in self.get_fields().values():
|
for field in self.get_fields().values():
|
||||||
if types._issubclass(field.type_, EventHandler):
|
if types._issubclass(field.outer_type_, EventHandler):
|
||||||
args_spec = None
|
args_spec = None
|
||||||
annotation = field.annotation
|
annotation = field.annotation
|
||||||
if (metadata := getattr(annotation, "__metadata__", None)) is not None:
|
if (metadata := getattr(annotation, "__metadata__", None)) is not None:
|
||||||
|
@ -3,14 +3,16 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import dataclasses
|
import dataclasses
|
||||||
|
import enum
|
||||||
import importlib
|
import importlib
|
||||||
|
import inspect
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
import urllib.parse
|
import urllib.parse
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Any, Dict, List, Optional, Set
|
from typing import Any, Dict, List, Optional, Set
|
||||||
|
|
||||||
from typing_extensions import get_type_hints
|
from typing_extensions import Annotated, get_type_hints
|
||||||
|
|
||||||
from reflex.utils.exceptions import ConfigError, EnvironmentVarValueError
|
from reflex.utils.exceptions import ConfigError, EnvironmentVarValueError
|
||||||
from reflex.utils.types import GenericType, is_union, value_inside_optional
|
from reflex.utils.types import GenericType, is_union, value_inside_optional
|
||||||
@ -202,8 +204,8 @@ def interpret_int_env(value: str, field_name: str) -> int:
|
|||||||
) from ve
|
) from ve
|
||||||
|
|
||||||
|
|
||||||
def interpret_path_env(value: str, field_name: str) -> Path:
|
def interpret_existing_path_env(value: str, field_name: str) -> ExistingPath:
|
||||||
"""Interpret a path environment variable value.
|
"""Interpret a path environment variable value as an existing path.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
value: The environment variable value.
|
value: The environment variable value.
|
||||||
@ -221,6 +223,41 @@ def interpret_path_env(value: str, field_name: str) -> Path:
|
|||||||
return path
|
return path
|
||||||
|
|
||||||
|
|
||||||
|
def interpret_path_env(value: str, field_name: str) -> Path:
|
||||||
|
"""Interpret a path environment variable value.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
value: The environment variable value.
|
||||||
|
field_name: The field name.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
The interpreted value.
|
||||||
|
"""
|
||||||
|
return Path(value)
|
||||||
|
|
||||||
|
|
||||||
|
def interpret_enum_env(value: str, field_type: GenericType, field_name: str) -> Any:
|
||||||
|
"""Interpret an enum environment variable value.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
value: The environment variable value.
|
||||||
|
field_type: The field type.
|
||||||
|
field_name: The field name.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
The interpreted value.
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
EnvironmentVarValueError: If the value is invalid.
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
return field_type(value)
|
||||||
|
except ValueError as ve:
|
||||||
|
raise EnvironmentVarValueError(
|
||||||
|
f"Invalid enum value: {value} for {field_name}"
|
||||||
|
) from ve
|
||||||
|
|
||||||
|
|
||||||
def interpret_env_var_value(
|
def interpret_env_var_value(
|
||||||
value: str, field_type: GenericType, field_name: str
|
value: str, field_type: GenericType, field_name: str
|
||||||
) -> Any:
|
) -> Any:
|
||||||
@ -252,6 +289,10 @@ def interpret_env_var_value(
|
|||||||
return interpret_int_env(value, field_name)
|
return interpret_int_env(value, field_name)
|
||||||
elif field_type is Path:
|
elif field_type is Path:
|
||||||
return interpret_path_env(value, field_name)
|
return interpret_path_env(value, field_name)
|
||||||
|
elif field_type is ExistingPath:
|
||||||
|
return interpret_existing_path_env(value, field_name)
|
||||||
|
elif inspect.isclass(field_type) and issubclass(field_type, enum.Enum):
|
||||||
|
return interpret_enum_env(value, field_type, field_name)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
raise ValueError(
|
raise ValueError(
|
||||||
@ -259,6 +300,13 @@ def interpret_env_var_value(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class PathExistsFlag:
|
||||||
|
"""Flag to indicate that a path must exist."""
|
||||||
|
|
||||||
|
|
||||||
|
ExistingPath = Annotated[Path, PathExistsFlag]
|
||||||
|
|
||||||
|
|
||||||
@dataclasses.dataclass(init=False)
|
@dataclasses.dataclass(init=False)
|
||||||
class EnvironmentVariables:
|
class EnvironmentVariables:
|
||||||
"""Environment variables class to instantiate environment variables."""
|
"""Environment variables class to instantiate environment variables."""
|
||||||
@ -288,7 +336,7 @@ class EnvironmentVariables:
|
|||||||
REFLEX_WEB_WORKDIR: Path = Path(constants.Dirs.WEB)
|
REFLEX_WEB_WORKDIR: Path = Path(constants.Dirs.WEB)
|
||||||
|
|
||||||
# Path to the alembic config file
|
# Path to the alembic config file
|
||||||
ALEMBIC_CONFIG: Path = Path(constants.ALEMBIC_CONFIG)
|
ALEMBIC_CONFIG: ExistingPath = Path(constants.ALEMBIC_CONFIG)
|
||||||
|
|
||||||
# Disable SSL verification for HTTPX requests.
|
# Disable SSL verification for HTTPX requests.
|
||||||
SSL_NO_VERIFY: bool = False
|
SSL_NO_VERIFY: bool = False
|
||||||
@ -401,7 +449,7 @@ class Config(Base):
|
|||||||
telemetry_enabled: bool = True
|
telemetry_enabled: bool = True
|
||||||
|
|
||||||
# The bun path
|
# The bun path
|
||||||
bun_path: Path = constants.Bun.DEFAULT_PATH
|
bun_path: ExistingPath = constants.Bun.DEFAULT_PATH
|
||||||
|
|
||||||
# List of origins that are allowed to connect to the backend API.
|
# List of origins that are allowed to connect to the backend API.
|
||||||
cors_allowed_origins: List[str] = ["*"]
|
cors_allowed_origins: List[str] = ["*"]
|
||||||
@ -525,7 +573,7 @@ class Config(Base):
|
|||||||
)
|
)
|
||||||
|
|
||||||
# Interpret the value.
|
# Interpret the value.
|
||||||
value = interpret_env_var_value(env_var, field.type_, field.name)
|
value = interpret_env_var_value(env_var, field.outer_type_, field.name)
|
||||||
|
|
||||||
# Set the value.
|
# Set the value.
|
||||||
updated_values[key] = value
|
updated_values[key] = value
|
||||||
|
@ -1489,6 +1489,11 @@ if sys.version_info >= (3, 10):
|
|||||||
"""
|
"""
|
||||||
return self
|
return self
|
||||||
|
|
||||||
|
@overload
|
||||||
|
def __call__(
|
||||||
|
self: EventCallback[Q, T],
|
||||||
|
) -> EventCallback[Q, T]: ...
|
||||||
|
|
||||||
@overload
|
@overload
|
||||||
def __call__(
|
def __call__(
|
||||||
self: EventCallback[Concatenate[V, Q], T], value: V | Var[V]
|
self: EventCallback[Concatenate[V, Q], T], value: V | Var[V]
|
||||||
|
@ -7,8 +7,13 @@ import pytest
|
|||||||
|
|
||||||
import reflex as rx
|
import reflex as rx
|
||||||
import reflex.config
|
import reflex.config
|
||||||
from reflex.config import environment
|
from reflex.config import (
|
||||||
from reflex.constants import Endpoint
|
environment,
|
||||||
|
interpret_boolean_env,
|
||||||
|
interpret_enum_env,
|
||||||
|
interpret_int_env,
|
||||||
|
)
|
||||||
|
from reflex.constants import Endpoint, Env
|
||||||
|
|
||||||
|
|
||||||
def test_requires_app_name():
|
def test_requires_app_name():
|
||||||
@ -208,11 +213,11 @@ def test_replace_defaults(
|
|||||||
assert getattr(c, key) == value
|
assert getattr(c, key) == value
|
||||||
|
|
||||||
|
|
||||||
def reflex_dir_constant():
|
def reflex_dir_constant() -> Path:
|
||||||
return environment.REFLEX_DIR
|
return environment.REFLEX_DIR
|
||||||
|
|
||||||
|
|
||||||
def test_reflex_dir_env_var(monkeypatch, tmp_path):
|
def test_reflex_dir_env_var(monkeypatch: pytest.MonkeyPatch, tmp_path: Path) -> None:
|
||||||
"""Test that the REFLEX_DIR environment variable is used to set the Reflex.DIR constant.
|
"""Test that the REFLEX_DIR environment variable is used to set the Reflex.DIR constant.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@ -224,3 +229,16 @@ def test_reflex_dir_env_var(monkeypatch, tmp_path):
|
|||||||
mp_ctx = multiprocessing.get_context(method="spawn")
|
mp_ctx = multiprocessing.get_context(method="spawn")
|
||||||
with mp_ctx.Pool(processes=1) as pool:
|
with mp_ctx.Pool(processes=1) as pool:
|
||||||
assert pool.apply(reflex_dir_constant) == tmp_path
|
assert pool.apply(reflex_dir_constant) == tmp_path
|
||||||
|
|
||||||
|
|
||||||
|
def test_interpret_enum_env() -> None:
|
||||||
|
assert interpret_enum_env(Env.PROD.value, Env, "REFLEX_ENV") == Env.PROD
|
||||||
|
|
||||||
|
|
||||||
|
def test_interpret_int_env() -> None:
|
||||||
|
assert interpret_int_env("3001", "FRONTEND_PORT") == 3001
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("value, expected", [("true", True), ("false", False)])
|
||||||
|
def test_interpret_bool_env(value: str, expected: bool) -> None:
|
||||||
|
assert interpret_boolean_env(value, "TELEMETRY_ENABLED") == expected
|
||||||
|
Loading…
Reference in New Issue
Block a user