implement default_factory for EnvVar, improve env_var typing
also migrate environment to be a class singleton to prevent unintended chaos with default factories
This commit is contained in:
parent
db2b5b0320
commit
d32604713c
@ -67,7 +67,7 @@ from reflex.components.core.client_side_routing import (
|
||||
)
|
||||
from reflex.components.core.upload import Upload, get_upload_dir
|
||||
from reflex.components.radix import themes
|
||||
from reflex.config import environment, get_config
|
||||
from reflex.config import EnvironmentVariables, get_config
|
||||
from reflex.event import (
|
||||
Event,
|
||||
EventHandler,
|
||||
@ -506,7 +506,10 @@ class App(MiddlewareMixin, LifespanMixin):
|
||||
# Check if the route given is valid
|
||||
verify_route_validity(route)
|
||||
|
||||
if route in self.unevaluated_pages and environment.RELOAD_CONFIG.is_set():
|
||||
if (
|
||||
route in self.unevaluated_pages
|
||||
and EnvironmentVariables.RELOAD_CONFIG.is_set()
|
||||
):
|
||||
# when the app is reloaded(typically for app harness tests), we should maintain
|
||||
# the latest render function of a route.This applies typically to decorated pages
|
||||
# since they are only added when app._compile is called.
|
||||
@ -723,7 +726,7 @@ class App(MiddlewareMixin, LifespanMixin):
|
||||
Whether the app should be compiled.
|
||||
"""
|
||||
# Check the environment variable.
|
||||
if environment.REFLEX_SKIP_COMPILE.get():
|
||||
if EnvironmentVariables.REFLEX_SKIP_COMPILE.get():
|
||||
return False
|
||||
|
||||
nocompile = prerequisites.get_web_dir() / constants.NOCOMPILE_FILE
|
||||
@ -946,7 +949,10 @@ class App(MiddlewareMixin, LifespanMixin):
|
||||
executor = None
|
||||
if (
|
||||
platform.system() in ("Linux", "Darwin")
|
||||
and (number_of_processes := environment.REFLEX_COMPILE_PROCESSES.get())
|
||||
and (
|
||||
number_of_processes
|
||||
:= EnvironmentVariables.REFLEX_COMPILE_PROCESSES.get()
|
||||
)
|
||||
is not None
|
||||
):
|
||||
executor = concurrent.futures.ProcessPoolExecutor(
|
||||
@ -955,7 +961,7 @@ class App(MiddlewareMixin, LifespanMixin):
|
||||
)
|
||||
else:
|
||||
executor = concurrent.futures.ThreadPoolExecutor(
|
||||
max_workers=environment.REFLEX_COMPILE_THREADS.get()
|
||||
max_workers=EnvironmentVariables.REFLEX_COMPILE_THREADS.get()
|
||||
)
|
||||
|
||||
for route, component in zip(self.pages, page_components):
|
||||
|
@ -16,7 +16,7 @@ from reflex.components.component import (
|
||||
CustomComponent,
|
||||
StatefulComponent,
|
||||
)
|
||||
from reflex.config import environment, get_config
|
||||
from reflex.config import EnvironmentVariables, get_config
|
||||
from reflex.state import BaseState
|
||||
from reflex.style import SYSTEM_COLOR_MODE
|
||||
from reflex.utils.exec import is_prod_mode
|
||||
@ -527,7 +527,7 @@ def remove_tailwind_from_postcss() -> tuple[str, str]:
|
||||
|
||||
def purge_web_pages_dir():
|
||||
"""Empty out .web/pages directory."""
|
||||
if not is_prod_mode() and environment.REFLEX_PERSIST_WEB_DIR.get():
|
||||
if not is_prod_mode() and EnvironmentVariables.REFLEX_PERSIST_WEB_DIR.get():
|
||||
# Skip purging the web directory in dev mode if REFLEX_PERSIST_WEB_DIR is set.
|
||||
return
|
||||
|
||||
|
@ -13,7 +13,7 @@ from reflex.components.component import (
|
||||
)
|
||||
from reflex.components.el.elements.forms import Input
|
||||
from reflex.components.radix.themes.layout.box import Box
|
||||
from reflex.config import environment
|
||||
from reflex.config import EnvironmentVariables
|
||||
from reflex.constants import Dirs
|
||||
from reflex.constants.compiler import Hooks, Imports
|
||||
from reflex.event import (
|
||||
@ -132,7 +132,7 @@ def get_upload_dir() -> Path:
|
||||
"""
|
||||
Upload.is_used = True
|
||||
|
||||
uploaded_files_dir = environment.REFLEX_UPLOADED_FILES_DIR.get()
|
||||
uploaded_files_dir = EnvironmentVariables.REFLEX_UPLOADED_FILES_DIR.get()
|
||||
uploaded_files_dir.mkdir(parents=True, exist_ok=True)
|
||||
return uploaded_files_dir
|
||||
|
||||
|
@ -13,6 +13,7 @@ from pathlib import Path
|
||||
from typing import (
|
||||
TYPE_CHECKING,
|
||||
Any,
|
||||
Callable,
|
||||
Dict,
|
||||
Generic,
|
||||
List,
|
||||
@ -312,26 +313,47 @@ def interpret_env_var_value(
|
||||
|
||||
T = TypeVar("T")
|
||||
|
||||
ENV_VAR_DEFAULT_FACTORY = Callable[[], T]
|
||||
|
||||
|
||||
class EnvVar(Generic[T]):
|
||||
"""Environment variable."""
|
||||
|
||||
name: str
|
||||
default: Any
|
||||
default_factory: Optional[ENV_VAR_DEFAULT_FACTORY]
|
||||
type_: T
|
||||
|
||||
def __init__(self, name: str, default: Any, type_: T) -> None:
|
||||
def __init__(
|
||||
self,
|
||||
name: str,
|
||||
default: Any,
|
||||
default_factory: Optional[ENV_VAR_DEFAULT_FACTORY],
|
||||
type_: T,
|
||||
) -> None:
|
||||
"""Initialize the environment variable.
|
||||
|
||||
Args:
|
||||
name: The environment variable name.
|
||||
default: The default value.
|
||||
default_factory: The default factory.
|
||||
type_: The type of the value.
|
||||
"""
|
||||
self.name = name
|
||||
self.default = default
|
||||
self.default_factory = default_factory
|
||||
self.type_ = type_
|
||||
|
||||
def get_default(self) -> T:
|
||||
"""Get the default value.
|
||||
|
||||
Returns:
|
||||
The default value.
|
||||
"""
|
||||
if self.default_factory is not None:
|
||||
return self.default_factory()
|
||||
return self.default
|
||||
|
||||
def interpret(self, value: str) -> T:
|
||||
"""Interpret the environment variable value.
|
||||
|
||||
@ -371,7 +393,7 @@ class EnvVar(Generic[T]):
|
||||
env_value = self.getenv()
|
||||
if env_value is not None:
|
||||
return env_value
|
||||
return self.default
|
||||
return self.get_default()
|
||||
|
||||
def set(self, value: T | None) -> None:
|
||||
"""Set the environment variable. None unsets the variable.
|
||||
@ -392,16 +414,24 @@ class env_var: # type: ignore
|
||||
|
||||
name: str
|
||||
default: Any
|
||||
default_factory: Optional[ENV_VAR_DEFAULT_FACTORY]
|
||||
internal: bool = False
|
||||
|
||||
def __init__(self, default: Any, internal: bool = False) -> None:
|
||||
def __init__(
|
||||
self,
|
||||
default: Any = None,
|
||||
default_factory: Optional[ENV_VAR_DEFAULT_FACTORY] = None,
|
||||
internal: bool = False,
|
||||
) -> None:
|
||||
"""Initialize the descriptor.
|
||||
|
||||
Args:
|
||||
default: The default value.
|
||||
default_factory: The default factory.
|
||||
internal: Whether the environment variable is reflex internal.
|
||||
"""
|
||||
self.default = default
|
||||
self.default_factory = default_factory
|
||||
self.internal = internal
|
||||
|
||||
def __set_name__(self, owner, name):
|
||||
@ -427,22 +457,30 @@ class env_var: # type: ignore
|
||||
env_name = self.name
|
||||
if self.internal:
|
||||
env_name = f"__{env_name}"
|
||||
return EnvVar(name=env_name, default=self.default, type_=type_)
|
||||
return EnvVar(
|
||||
name=env_name,
|
||||
default=self.default,
|
||||
type_=type_,
|
||||
default_factory=self.default_factory,
|
||||
)
|
||||
|
||||
if TYPE_CHECKING:
|
||||
|
||||
if TYPE_CHECKING:
|
||||
def __new__(
|
||||
cls,
|
||||
default: Optional[T] = None,
|
||||
default_factory: Optional[ENV_VAR_DEFAULT_FACTORY[T]] = None,
|
||||
internal: bool = False,
|
||||
) -> EnvVar[T]:
|
||||
"""Create a new EnvVar instance.
|
||||
|
||||
def env_var(default, internal=False) -> EnvVar:
|
||||
"""Typing helper for the env_var descriptor.
|
||||
|
||||
Args:
|
||||
default: The default value.
|
||||
internal: Whether the environment variable is reflex internal.
|
||||
|
||||
Returns:
|
||||
The EnvVar instance.
|
||||
"""
|
||||
return default
|
||||
Args:
|
||||
cls: The class.
|
||||
default: The default value.
|
||||
default_factory: The default factory.
|
||||
internal: Whether the environment variable is reflex internal.
|
||||
"""
|
||||
...
|
||||
|
||||
|
||||
class PathExistsFlag:
|
||||
@ -455,6 +493,16 @@ ExistingPath = Annotated[Path, PathExistsFlag]
|
||||
class EnvironmentVariables:
|
||||
"""Environment variables class to instantiate environment variables."""
|
||||
|
||||
def __init__(self):
|
||||
"""Initialize the environment variables.
|
||||
|
||||
Raises:
|
||||
NotImplementedError: Always.
|
||||
"""
|
||||
raise NotImplementedError(
|
||||
f"{type(self).__name__} is a class singleton and not meant to be instantiated."
|
||||
)
|
||||
|
||||
# Whether to use npm over bun to install frontend packages.
|
||||
REFLEX_USE_NPM: EnvVar[bool] = env_var(False)
|
||||
|
||||
@ -545,11 +593,13 @@ class EnvironmentVariables:
|
||||
# Where to save screenshots when tests fail.
|
||||
SCREENSHOT_DIR: EnvVar[Optional[Path]] = env_var(None)
|
||||
|
||||
# Whether to minify state names.
|
||||
REFLEX_MINIFY_STATES: EnvVar[Optional[bool]] = env_var(False)
|
||||
|
||||
|
||||
environment = EnvironmentVariables()
|
||||
# Whether to minify state names. Default to true in prod mode and false otherwise.
|
||||
REFLEX_MINIFY_STATES: EnvVar[Optional[bool]] = env_var(
|
||||
default_factory=lambda: (
|
||||
EnvironmentVariables.REFLEX_ENV_MODE.get() == constants.Env.PROD
|
||||
)
|
||||
or False
|
||||
)
|
||||
|
||||
|
||||
class Config(Base):
|
||||
|
@ -109,10 +109,10 @@ class Templates(SimpleNamespace):
|
||||
Returns:
|
||||
The URL to redirect to reflex.build.
|
||||
"""
|
||||
from reflex.config import environment
|
||||
from reflex.config import EnvironmentVariables
|
||||
|
||||
return (
|
||||
environment.REFLEX_BUILD_FRONTEND.get()
|
||||
EnvironmentVariables.REFLEX_BUILD_FRONTEND.get()
|
||||
+ "/gen?reflex_init_token={reflex_init_token}"
|
||||
)
|
||||
|
||||
@ -124,9 +124,12 @@ class Templates(SimpleNamespace):
|
||||
Returns:
|
||||
The URL to poll waiting for the user to select a generation.
|
||||
"""
|
||||
from reflex.config import environment
|
||||
from reflex.config import EnvironmentVariables
|
||||
|
||||
return environment.REFLEX_BUILD_BACKEND.get() + "/api/init/{reflex_init_token}"
|
||||
return (
|
||||
EnvironmentVariables.REFLEX_BUILD_BACKEND.get()
|
||||
+ "/api/init/{reflex_init_token}"
|
||||
)
|
||||
|
||||
@classproperty
|
||||
@classmethod
|
||||
@ -136,10 +139,10 @@ class Templates(SimpleNamespace):
|
||||
Returns:
|
||||
The URL to fetch the generation's reflex code.
|
||||
"""
|
||||
from reflex.config import environment
|
||||
from reflex.config import EnvironmentVariables
|
||||
|
||||
return (
|
||||
environment.REFLEX_BUILD_BACKEND.get()
|
||||
EnvironmentVariables.REFLEX_BUILD_BACKEND.get()
|
||||
+ "/api/gen/{generation_hash}/refactored"
|
||||
)
|
||||
|
||||
|
@ -5,7 +5,7 @@ from enum import Enum
|
||||
from types import SimpleNamespace
|
||||
|
||||
from reflex.base import Base
|
||||
from reflex.constants import Dirs, Env
|
||||
from reflex.constants import Dirs
|
||||
from reflex.utils.imports import ImportVar
|
||||
|
||||
# The prefix used to create setters for state vars.
|
||||
@ -14,9 +14,6 @@ SETTER_PREFIX = "set_"
|
||||
# The file used to specify no compilation.
|
||||
NOCOMPILE_FILE = "nocompile"
|
||||
|
||||
# The env var to toggle minification of states.
|
||||
ENV_MINIFY_STATES = "REFLEX_MINIFY_STATES"
|
||||
|
||||
|
||||
class Ext(SimpleNamespace):
|
||||
"""Extension used in Reflex."""
|
||||
@ -33,22 +30,6 @@ class Ext(SimpleNamespace):
|
||||
EXE = ".exe"
|
||||
|
||||
|
||||
def minify_states() -> bool:
|
||||
"""Whether to minify states.
|
||||
|
||||
Returns:
|
||||
True if states should be minified.
|
||||
"""
|
||||
from reflex.config import environment
|
||||
|
||||
env = environment.REFLEX_MINIFY_STATES.get()
|
||||
if env is not None:
|
||||
return env
|
||||
|
||||
# minify states in prod by default
|
||||
return environment.REFLEX_ENV_MODE.get() == Env.PROD
|
||||
|
||||
|
||||
class CompileVars(SimpleNamespace):
|
||||
"""The variables used during compilation."""
|
||||
|
||||
@ -81,15 +62,6 @@ class CompileVars(SimpleNamespace):
|
||||
# The name of the function for converting a dict to an event.
|
||||
TO_EVENT = "Event"
|
||||
|
||||
@classmethod
|
||||
def MINIFY_STATES(cls) -> bool:
|
||||
"""Whether to minify states.
|
||||
|
||||
Returns:
|
||||
True if states should be minified.
|
||||
"""
|
||||
return minify_states()
|
||||
|
||||
|
||||
class PageNames(SimpleNamespace):
|
||||
"""The name of basic pages deployed in NextJS."""
|
||||
|
@ -61,9 +61,9 @@ class Bun(SimpleNamespace):
|
||||
Returns:
|
||||
The directory to store the bun.
|
||||
"""
|
||||
from reflex.config import environment
|
||||
from reflex.config import EnvironmentVariables
|
||||
|
||||
return environment.REFLEX_DIR.get() / "bun"
|
||||
return EnvironmentVariables.REFLEX_DIR.get() / "bun"
|
||||
|
||||
@classproperty
|
||||
@classmethod
|
||||
@ -98,9 +98,9 @@ class Fnm(SimpleNamespace):
|
||||
Returns:
|
||||
The directory to store fnm.
|
||||
"""
|
||||
from reflex.config import environment
|
||||
from reflex.config import EnvironmentVariables
|
||||
|
||||
return environment.REFLEX_DIR.get() / "fnm"
|
||||
return EnvironmentVariables.REFLEX_DIR.get() / "fnm"
|
||||
|
||||
@classproperty
|
||||
@classmethod
|
||||
|
@ -17,7 +17,7 @@ import typer
|
||||
from tomlkit.exceptions import TOMLKitError
|
||||
|
||||
from reflex import constants
|
||||
from reflex.config import environment, get_config
|
||||
from reflex.config import EnvironmentVariables, get_config
|
||||
from reflex.constants import CustomComponents
|
||||
from reflex.utils import console
|
||||
|
||||
@ -609,14 +609,14 @@ def publish(
|
||||
help="The API token to use for authentication on python package repository. If token is provided, no username/password should be provided at the same time",
|
||||
),
|
||||
username: Optional[str] = typer.Option(
|
||||
environment.TWINE_USERNAME.get(),
|
||||
EnvironmentVariables.TWINE_USERNAME.get(),
|
||||
"-u",
|
||||
"--username",
|
||||
show_default="TWINE_USERNAME environment variable value if set",
|
||||
help="The username to use for authentication on python package repository. Username and password must both be provided.",
|
||||
),
|
||||
password: Optional[str] = typer.Option(
|
||||
environment.TWINE_PASSWORD.get(),
|
||||
EnvironmentVariables.TWINE_PASSWORD.get(),
|
||||
"-p",
|
||||
"--password",
|
||||
show_default="TWINE_PASSWORD environment variable value if set",
|
||||
|
@ -17,7 +17,7 @@ import sqlalchemy.exc
|
||||
import sqlalchemy.orm
|
||||
|
||||
from reflex.base import Base
|
||||
from reflex.config import environment, get_config
|
||||
from reflex.config import EnvironmentVariables, get_config
|
||||
from reflex.utils import console
|
||||
from reflex.utils.compat import sqlmodel, sqlmodel_field_has_primary_key
|
||||
|
||||
@ -38,12 +38,12 @@ def get_engine(url: str | None = None) -> sqlalchemy.engine.Engine:
|
||||
url = url or conf.db_url
|
||||
if url is None:
|
||||
raise ValueError("No database url configured")
|
||||
if not environment.ALEMBIC_CONFIG.get().exists():
|
||||
if not EnvironmentVariables.ALEMBIC_CONFIG.get().exists():
|
||||
console.warn(
|
||||
"Database is not initialized, run [bold]reflex db init[/bold] first."
|
||||
)
|
||||
# Print the SQL queries if the log level is INFO or lower.
|
||||
echo_db_query = environment.SQLALCHEMY_ECHO.get()
|
||||
echo_db_query = EnvironmentVariables.SQLALCHEMY_ECHO.get()
|
||||
# Needed for the admin dash on sqlite.
|
||||
connect_args = {"check_same_thread": False} if url.startswith("sqlite") else {}
|
||||
return sqlmodel.create_engine(url, echo=echo_db_query, connect_args=connect_args)
|
||||
@ -231,7 +231,7 @@ class Model(Base, sqlmodel.SQLModel): # pyright: ignore [reportGeneralTypeIssue
|
||||
Returns:
|
||||
tuple of (config, script_directory)
|
||||
"""
|
||||
config = alembic.config.Config(environment.ALEMBIC_CONFIG.get())
|
||||
config = alembic.config.Config(EnvironmentVariables.ALEMBIC_CONFIG.get())
|
||||
return config, alembic.script.ScriptDirectory(
|
||||
config.get_main_option("script_location", default="version"),
|
||||
)
|
||||
@ -266,8 +266,8 @@ class Model(Base, sqlmodel.SQLModel): # pyright: ignore [reportGeneralTypeIssue
|
||||
def alembic_init(cls):
|
||||
"""Initialize alembic for the project."""
|
||||
alembic.command.init(
|
||||
config=alembic.config.Config(environment.ALEMBIC_CONFIG.get()),
|
||||
directory=str(environment.ALEMBIC_CONFIG.get().parent / "alembic"),
|
||||
config=alembic.config.Config(EnvironmentVariables.ALEMBIC_CONFIG.get()),
|
||||
directory=str(EnvironmentVariables.ALEMBIC_CONFIG.get().parent / "alembic"),
|
||||
)
|
||||
|
||||
@classmethod
|
||||
@ -287,7 +287,7 @@ class Model(Base, sqlmodel.SQLModel): # pyright: ignore [reportGeneralTypeIssue
|
||||
Returns:
|
||||
True when changes have been detected.
|
||||
"""
|
||||
if not environment.ALEMBIC_CONFIG.get().exists():
|
||||
if not EnvironmentVariables.ALEMBIC_CONFIG.get().exists():
|
||||
return False
|
||||
|
||||
config, script_directory = cls._alembic_config()
|
||||
@ -388,7 +388,7 @@ class Model(Base, sqlmodel.SQLModel): # pyright: ignore [reportGeneralTypeIssue
|
||||
True - indicating the process was successful.
|
||||
None - indicating the process was skipped.
|
||||
"""
|
||||
if not environment.ALEMBIC_CONFIG.get().exists():
|
||||
if not EnvironmentVariables.ALEMBIC_CONFIG.get().exists():
|
||||
return
|
||||
|
||||
with cls.get_db_engine().connect() as connection:
|
||||
|
@ -13,7 +13,7 @@ from reflex_cli.deployments import deployments_cli
|
||||
from reflex_cli.utils import dependency
|
||||
|
||||
from reflex import constants
|
||||
from reflex.config import environment, get_config
|
||||
from reflex.config import EnvironmentVariables, get_config
|
||||
from reflex.custom_components.custom_components import custom_components_cli
|
||||
from reflex.state import reset_disk_state_manager
|
||||
from reflex.utils import console, redir, telemetry
|
||||
@ -160,7 +160,7 @@ def _run(
|
||||
console.set_log_level(loglevel)
|
||||
|
||||
# Set env mode in the environment
|
||||
environment.REFLEX_ENV_MODE.set(env)
|
||||
EnvironmentVariables.REFLEX_ENV_MODE.set(env)
|
||||
|
||||
# Show system info
|
||||
exec.output_system_info()
|
||||
@ -277,13 +277,13 @@ def run(
|
||||
False,
|
||||
"--frontend-only",
|
||||
help="Execute only frontend.",
|
||||
envvar=environment.REFLEX_FRONTEND_ONLY.name,
|
||||
envvar=EnvironmentVariables.REFLEX_FRONTEND_ONLY.name,
|
||||
),
|
||||
backend: bool = typer.Option(
|
||||
False,
|
||||
"--backend-only",
|
||||
help="Execute only backend.",
|
||||
envvar=environment.REFLEX_BACKEND_ONLY.name,
|
||||
envvar=EnvironmentVariables.REFLEX_BACKEND_ONLY.name,
|
||||
),
|
||||
frontend_port: str = typer.Option(
|
||||
config.frontend_port, help="Specify a different frontend port."
|
||||
@ -302,8 +302,8 @@ def run(
|
||||
if frontend and backend:
|
||||
console.error("Cannot use both --frontend-only and --backend-only options.")
|
||||
raise typer.Exit(1)
|
||||
environment.REFLEX_BACKEND_ONLY.set(backend)
|
||||
environment.REFLEX_FRONTEND_ONLY.set(frontend)
|
||||
EnvironmentVariables.REFLEX_BACKEND_ONLY.set(backend)
|
||||
EnvironmentVariables.REFLEX_FRONTEND_ONLY.set(frontend)
|
||||
|
||||
_run(env, frontend, backend, frontend_port, backend_port, backend_host, loglevel)
|
||||
|
||||
@ -405,7 +405,7 @@ script_cli = typer.Typer()
|
||||
|
||||
def _skip_compile():
|
||||
"""Skip the compile step."""
|
||||
environment.REFLEX_SKIP_COMPILE.set(True)
|
||||
EnvironmentVariables.REFLEX_SKIP_COMPILE.set(True)
|
||||
|
||||
|
||||
@db_cli.command(name="init")
|
||||
@ -420,7 +420,7 @@ def db_init():
|
||||
return
|
||||
|
||||
# Check the alembic config.
|
||||
if environment.ALEMBIC_CONFIG.get().exists():
|
||||
if EnvironmentVariables.ALEMBIC_CONFIG.get().exists():
|
||||
console.error(
|
||||
"Database is already initialized. Use "
|
||||
"[bold]reflex db makemigrations[/bold] to create schema change "
|
||||
|
@ -69,7 +69,7 @@ from redis.exceptions import ResponseError
|
||||
import reflex.istate.dynamic
|
||||
from reflex import constants
|
||||
from reflex.base import Base
|
||||
from reflex.config import environment
|
||||
from reflex.config import EnvironmentVariables
|
||||
from reflex.event import (
|
||||
BACKGROUND_TASK_MARKER,
|
||||
Event,
|
||||
@ -932,7 +932,7 @@ class BaseState(Base, ABC, extra=pydantic.Extra.allow):
|
||||
"""
|
||||
module = cls.__module__.replace(".", "___")
|
||||
state_name = format.to_snake_case(f"{module}___{cls.__name__}")
|
||||
if constants.compiler.CompileVars.MINIFY_STATES():
|
||||
if EnvironmentVariables.REFLEX_MINIFY_STATES.get():
|
||||
return get_minified_state_name(state_name)
|
||||
return state_name
|
||||
|
||||
@ -3435,7 +3435,7 @@ class StateManagerRedis(StateManager):
|
||||
)
|
||||
except ResponseError:
|
||||
# Some redis servers only allow out-of-band configuration, so ignore errors here.
|
||||
if not environment.REFLEX_IGNORE_REDIS_CONFIG_ERROR.get():
|
||||
if not EnvironmentVariables.REFLEX_IGNORE_REDIS_CONFIG_ERROR.get():
|
||||
raise
|
||||
async with self.redis.pubsub() as pubsub:
|
||||
await pubsub.psubscribe(lock_key_channel)
|
||||
|
@ -44,7 +44,7 @@ import reflex.utils.format
|
||||
import reflex.utils.prerequisites
|
||||
import reflex.utils.processes
|
||||
from reflex.components.component import StatefulComponent
|
||||
from reflex.config import environment
|
||||
from reflex.config import EnvironmentVariables
|
||||
from reflex.state import (
|
||||
BaseState,
|
||||
State,
|
||||
@ -199,7 +199,7 @@ class AppHarness:
|
||||
state_name = reflex.utils.format.to_snake_case(
|
||||
f"{self.app_name}___{self.app_name}___" + state_cls_name
|
||||
)
|
||||
if reflex.constants.CompileVars.MINIFY_STATES():
|
||||
if EnvironmentVariables.REFLEX_MINIFY_STATES.get():
|
||||
return minified_state_names.get(state_name, state_name)
|
||||
return state_name
|
||||
|
||||
@ -626,10 +626,10 @@ class AppHarness:
|
||||
if self.frontend_url is None:
|
||||
raise RuntimeError("Frontend is not running.")
|
||||
want_headless = False
|
||||
if environment.APP_HARNESS_HEADLESS.get():
|
||||
if EnvironmentVariables.APP_HARNESS_HEADLESS.get():
|
||||
want_headless = True
|
||||
if driver_clz is None:
|
||||
requested_driver = environment.APP_HARNESS_DRIVER.get()
|
||||
requested_driver = EnvironmentVariables.APP_HARNESS_DRIVER.get()
|
||||
driver_clz = getattr(webdriver, requested_driver)
|
||||
if driver_options is None:
|
||||
driver_options = getattr(webdriver, f"{requested_driver}Options")()
|
||||
@ -651,7 +651,7 @@ class AppHarness:
|
||||
driver_options.add_argument("headless")
|
||||
if driver_options is None:
|
||||
raise RuntimeError(f"Could not determine options for {driver_clz}")
|
||||
if args := environment.APP_HARNESS_DRIVER_ARGS.get():
|
||||
if args := EnvironmentVariables.APP_HARNESS_DRIVER_ARGS.get():
|
||||
for arg in args.split(","):
|
||||
driver_options.add_argument(arg)
|
||||
if driver_option_args is not None:
|
||||
@ -958,7 +958,7 @@ class AppHarnessProd(AppHarness):
|
||||
def _start_backend(self):
|
||||
if self.app_instance is None:
|
||||
raise RuntimeError("App was not initialized.")
|
||||
environment.REFLEX_SKIP_COMPILE.set(True)
|
||||
EnvironmentVariables.REFLEX_SKIP_COMPILE.set(True)
|
||||
self.backend = uvicorn.Server(
|
||||
uvicorn.Config(
|
||||
app=self.app_instance,
|
||||
@ -976,7 +976,7 @@ class AppHarnessProd(AppHarness):
|
||||
try:
|
||||
return super()._poll_for_servers(timeout)
|
||||
finally:
|
||||
environment.REFLEX_SKIP_COMPILE.set(None)
|
||||
EnvironmentVariables.REFLEX_SKIP_COMPILE.set(None)
|
||||
|
||||
@override
|
||||
def start(self) -> AppHarnessProd:
|
||||
@ -985,7 +985,7 @@ class AppHarnessProd(AppHarness):
|
||||
Returns:
|
||||
self
|
||||
"""
|
||||
environment.REFLEX_ENV_MODE.set(reflex.constants.base.Env.PROD)
|
||||
EnvironmentVariables.REFLEX_ENV_MODE.set(reflex.constants.base.Env.PROD)
|
||||
_ = super().start()
|
||||
return self
|
||||
|
||||
@ -997,4 +997,4 @@ class AppHarnessProd(AppHarness):
|
||||
self.frontend_server.shutdown()
|
||||
if self.frontend_thread is not None:
|
||||
self.frontend_thread.join()
|
||||
environment.REFLEX_ENV_MODE.set(None)
|
||||
EnvironmentVariables.REFLEX_ENV_MODE.set(None)
|
||||
|
@ -15,7 +15,7 @@ from urllib.parse import urljoin
|
||||
import psutil
|
||||
|
||||
from reflex import constants
|
||||
from reflex.config import environment, get_config
|
||||
from reflex.config import EnvironmentVariables, get_config
|
||||
from reflex.constants.base import LogLevel
|
||||
from reflex.utils import console, path_ops
|
||||
from reflex.utils.prerequisites import get_web_dir
|
||||
@ -184,7 +184,7 @@ def should_use_granian():
|
||||
Returns:
|
||||
True if Granian should be used.
|
||||
"""
|
||||
return environment.REFLEX_USE_GRANIAN.get()
|
||||
return EnvironmentVariables.REFLEX_USE_GRANIAN.get()
|
||||
|
||||
|
||||
def get_app_module():
|
||||
@ -370,7 +370,7 @@ def run_uvicorn_backend_prod(host, port, loglevel):
|
||||
run=True,
|
||||
show_logs=True,
|
||||
env={
|
||||
environment.REFLEX_SKIP_COMPILE.name: "true"
|
||||
EnvironmentVariables.REFLEX_SKIP_COMPILE.name: "true"
|
||||
}, # skip compile for prod backend
|
||||
)
|
||||
|
||||
@ -407,7 +407,7 @@ def run_granian_backend_prod(host, port, loglevel):
|
||||
run=True,
|
||||
show_logs=True,
|
||||
env={
|
||||
environment.REFLEX_SKIP_COMPILE.name: "true"
|
||||
EnvironmentVariables.REFLEX_SKIP_COMPILE.name: "true"
|
||||
}, # skip compile for prod backend
|
||||
)
|
||||
except ImportError:
|
||||
@ -493,7 +493,7 @@ def is_prod_mode() -> bool:
|
||||
Returns:
|
||||
True if the app is running in production mode or False if running in dev mode.
|
||||
"""
|
||||
current_mode = environment.REFLEX_ENV_MODE.get()
|
||||
current_mode = EnvironmentVariables.REFLEX_ENV_MODE.get()
|
||||
return current_mode == constants.Env.PROD
|
||||
|
||||
|
||||
@ -509,7 +509,7 @@ def is_frontend_only() -> bool:
|
||||
deprecation_version="0.6.5",
|
||||
removal_version="0.7.0",
|
||||
)
|
||||
return environment.REFLEX_FRONTEND_ONLY.get()
|
||||
return EnvironmentVariables.REFLEX_FRONTEND_ONLY.get()
|
||||
|
||||
|
||||
def is_backend_only() -> bool:
|
||||
@ -524,7 +524,7 @@ def is_backend_only() -> bool:
|
||||
deprecation_version="0.6.5",
|
||||
removal_version="0.7.0",
|
||||
)
|
||||
return environment.REFLEX_BACKEND_ONLY.get()
|
||||
return EnvironmentVariables.REFLEX_BACKEND_ONLY.get()
|
||||
|
||||
|
||||
def should_skip_compile() -> bool:
|
||||
@ -539,4 +539,4 @@ def should_skip_compile() -> bool:
|
||||
deprecation_version="0.6.5",
|
||||
removal_version="0.7.0",
|
||||
)
|
||||
return environment.REFLEX_SKIP_COMPILE.get()
|
||||
return EnvironmentVariables.REFLEX_SKIP_COMPILE.get()
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
import httpx
|
||||
|
||||
from ..config import environment
|
||||
from ..config import EnvironmentVariables
|
||||
from . import console
|
||||
|
||||
|
||||
@ -12,7 +12,7 @@ def _httpx_verify_kwarg() -> bool:
|
||||
Returns:
|
||||
True if SSL verification is enabled, False otherwise
|
||||
"""
|
||||
return not environment.SSL_NO_VERIFY.get()
|
||||
return not EnvironmentVariables.SSL_NO_VERIFY.get()
|
||||
|
||||
|
||||
def get(url: str, **kwargs) -> httpx.Response:
|
||||
|
@ -9,7 +9,7 @@ import shutil
|
||||
from pathlib import Path
|
||||
|
||||
from reflex import constants
|
||||
from reflex.config import environment
|
||||
from reflex.config import EnvironmentVariables
|
||||
|
||||
# Shorthand for join.
|
||||
join = os.linesep.join
|
||||
@ -136,7 +136,7 @@ def use_system_node() -> bool:
|
||||
Returns:
|
||||
Whether the system node should be used.
|
||||
"""
|
||||
return environment.REFLEX_USE_SYSTEM_NODE.get()
|
||||
return EnvironmentVariables.REFLEX_USE_SYSTEM_NODE.get()
|
||||
|
||||
|
||||
def use_system_bun() -> bool:
|
||||
@ -145,7 +145,7 @@ def use_system_bun() -> bool:
|
||||
Returns:
|
||||
Whether the system bun should be used.
|
||||
"""
|
||||
return environment.REFLEX_USE_SYSTEM_BUN.get()
|
||||
return EnvironmentVariables.REFLEX_USE_SYSTEM_BUN.get()
|
||||
|
||||
|
||||
def get_node_bin_path() -> Path | None:
|
||||
|
@ -33,7 +33,7 @@ from redis.asyncio import Redis
|
||||
|
||||
from reflex import constants, model
|
||||
from reflex.compiler import templates
|
||||
from reflex.config import Config, environment, get_config
|
||||
from reflex.config import Config, EnvironmentVariables, get_config
|
||||
from reflex.utils import console, net, path_ops, processes
|
||||
from reflex.utils.exceptions import GeneratedCodeHasNoFunctionDefs
|
||||
from reflex.utils.format import format_library_name
|
||||
@ -69,7 +69,7 @@ def get_web_dir() -> Path:
|
||||
Returns:
|
||||
The working directory.
|
||||
"""
|
||||
return environment.REFLEX_WEB_WORKDIR.get()
|
||||
return EnvironmentVariables.REFLEX_WEB_WORKDIR.get()
|
||||
|
||||
|
||||
def _python_version_check():
|
||||
@ -260,7 +260,7 @@ def windows_npm_escape_hatch() -> bool:
|
||||
Returns:
|
||||
If the user has set REFLEX_USE_NPM.
|
||||
"""
|
||||
return environment.REFLEX_USE_NPM.get()
|
||||
return EnvironmentVariables.REFLEX_USE_NPM.get()
|
||||
|
||||
|
||||
def get_app(reload: bool = False) -> ModuleType:
|
||||
@ -278,7 +278,7 @@ def get_app(reload: bool = False) -> ModuleType:
|
||||
from reflex.utils import telemetry
|
||||
|
||||
try:
|
||||
environment.RELOAD_CONFIG.set(reload)
|
||||
EnvironmentVariables.RELOAD_CONFIG.set(reload)
|
||||
config = get_config()
|
||||
if not config.app_name:
|
||||
raise RuntimeError(
|
||||
@ -1019,7 +1019,7 @@ def needs_reinit(frontend: bool = True) -> bool:
|
||||
return False
|
||||
|
||||
# Make sure the .reflex directory exists.
|
||||
if not environment.REFLEX_DIR.get().exists():
|
||||
if not EnvironmentVariables.REFLEX_DIR.get().exists():
|
||||
return True
|
||||
|
||||
# Make sure the .web directory exists in frontend mode.
|
||||
@ -1124,7 +1124,7 @@ def ensure_reflex_installation_id() -> Optional[int]:
|
||||
"""
|
||||
try:
|
||||
initialize_reflex_user_directory()
|
||||
installation_id_file = environment.REFLEX_DIR.get() / "installation_id"
|
||||
installation_id_file = EnvironmentVariables.REFLEX_DIR.get() / "installation_id"
|
||||
|
||||
installation_id = None
|
||||
if installation_id_file.exists():
|
||||
@ -1149,7 +1149,7 @@ def ensure_reflex_installation_id() -> Optional[int]:
|
||||
def initialize_reflex_user_directory():
|
||||
"""Initialize the reflex user directory."""
|
||||
# Create the reflex directory.
|
||||
path_ops.mkdir(environment.REFLEX_DIR.get())
|
||||
path_ops.mkdir(EnvironmentVariables.REFLEX_DIR.get())
|
||||
|
||||
|
||||
def initialize_frontend_dependencies():
|
||||
@ -1174,7 +1174,7 @@ def check_db_initialized() -> bool:
|
||||
"""
|
||||
if (
|
||||
get_config().db_url is not None
|
||||
and not environment.ALEMBIC_CONFIG.get().exists()
|
||||
and not EnvironmentVariables.ALEMBIC_CONFIG.get().exists()
|
||||
):
|
||||
console.error(
|
||||
"Database is not initialized. Run [bold]reflex db init[/bold] first."
|
||||
@ -1185,7 +1185,10 @@ def check_db_initialized() -> bool:
|
||||
|
||||
def check_schema_up_to_date():
|
||||
"""Check if the sqlmodel metadata matches the current database schema."""
|
||||
if get_config().db_url is None or not environment.ALEMBIC_CONFIG.get().exists():
|
||||
if (
|
||||
get_config().db_url is None
|
||||
or not EnvironmentVariables.ALEMBIC_CONFIG.get().exists()
|
||||
):
|
||||
return
|
||||
with model.Model.get_db_engine().connect() as connection:
|
||||
try:
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
import httpx
|
||||
|
||||
from reflex.config import environment
|
||||
from reflex.config import EnvironmentVariables
|
||||
from reflex.utils import console, net
|
||||
|
||||
|
||||
@ -55,4 +55,4 @@ def _get_npm_registry() -> str:
|
||||
Returns:
|
||||
str:
|
||||
"""
|
||||
return environment.NPM_CONFIG_REGISTRY.get() or get_best_registry()
|
||||
return EnvironmentVariables.NPM_CONFIG_REGISTRY.get() or get_best_registry()
|
||||
|
@ -8,7 +8,7 @@ import multiprocessing
|
||||
import platform
|
||||
import warnings
|
||||
|
||||
from reflex.config import environment
|
||||
from reflex.config import EnvironmentVariables
|
||||
|
||||
try:
|
||||
from datetime import UTC, datetime
|
||||
@ -95,7 +95,7 @@ def _raise_on_missing_project_hash() -> bool:
|
||||
False when compilation should be skipped (i.e. no .web directory is required).
|
||||
Otherwise return True.
|
||||
"""
|
||||
return not environment.REFLEX_SKIP_COMPILE.get()
|
||||
return not EnvironmentVariables.REFLEX_SKIP_COMPILE.get()
|
||||
|
||||
|
||||
def _prepare_event(event: str, **kwargs) -> dict:
|
||||
|
@ -8,7 +8,7 @@ from typing import Generator, Type
|
||||
import pytest
|
||||
|
||||
import reflex.constants
|
||||
from reflex.config import environment
|
||||
from reflex.config import EnvironmentVariables
|
||||
from reflex.testing import AppHarness, AppHarnessProd
|
||||
|
||||
DISPLAY = None
|
||||
@ -24,7 +24,10 @@ def xvfb():
|
||||
Yields:
|
||||
the pyvirtualdisplay object that the browser will be open on
|
||||
"""
|
||||
if os.environ.get("GITHUB_ACTIONS") and not environment.APP_HARNESS_HEADLESS.get():
|
||||
if (
|
||||
os.environ.get("GITHUB_ACTIONS")
|
||||
and not EnvironmentVariables.APP_HARNESS_HEADLESS.get()
|
||||
):
|
||||
from pyvirtualdisplay.smartdisplay import ( # pyright: ignore [reportMissingImports]
|
||||
SmartDisplay,
|
||||
)
|
||||
@ -45,7 +48,7 @@ def pytest_exception_interact(node, call, report):
|
||||
call: The pytest call describing when/where the test was invoked.
|
||||
report: The pytest log report object.
|
||||
"""
|
||||
screenshot_dir = environment.SCREENSHOT_DIR.get()
|
||||
screenshot_dir = EnvironmentVariables.SCREENSHOT_DIR.get()
|
||||
if DISPLAY is None or screenshot_dir is None:
|
||||
return
|
||||
|
||||
@ -89,7 +92,7 @@ def app_harness_env(
|
||||
"""
|
||||
harness: Type[AppHarness] = request.param
|
||||
if issubclass(harness, AppHarnessProd):
|
||||
environment.REFLEX_ENV_MODE.set(reflex.constants.Env.PROD)
|
||||
EnvironmentVariables.REFLEX_ENV_MODE.set(reflex.constants.Env.PROD)
|
||||
yield harness
|
||||
if issubclass(harness, AppHarnessProd):
|
||||
environment.REFLEX_ENV_MODE.set(None)
|
||||
EnvironmentVariables.REFLEX_ENV_MODE.set(None)
|
||||
|
@ -2,7 +2,6 @@
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
from functools import partial
|
||||
from typing import Generator, Optional, Type
|
||||
|
||||
@ -10,7 +9,7 @@ import pytest
|
||||
from selenium.webdriver.common.by import By
|
||||
from selenium.webdriver.remote.webdriver import WebDriver
|
||||
|
||||
from reflex.constants.compiler import ENV_MINIFY_STATES
|
||||
from reflex.config import EnvironmentVariables
|
||||
from reflex.testing import AppHarness, AppHarnessProd
|
||||
|
||||
|
||||
@ -63,13 +62,9 @@ def minify_state_env(
|
||||
minify_states: whether to minify state names
|
||||
"""
|
||||
minify_states: Optional[bool] = request.param
|
||||
if minify_states is None:
|
||||
_ = os.environ.pop(ENV_MINIFY_STATES, None)
|
||||
else:
|
||||
os.environ[ENV_MINIFY_STATES] = str(minify_states).lower()
|
||||
EnvironmentVariables.REFLEX_MINIFY_STATES.set(minify_states)
|
||||
yield minify_states
|
||||
if minify_states is not None:
|
||||
os.environ.pop(ENV_MINIFY_STATES, None)
|
||||
EnvironmentVariables.REFLEX_MINIFY_STATES.set(None)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
|
@ -8,9 +8,9 @@ import pytest
|
||||
import reflex as rx
|
||||
import reflex.config
|
||||
from reflex.config import (
|
||||
EnvironmentVariables,
|
||||
EnvVar,
|
||||
env_var,
|
||||
environment,
|
||||
interpret_boolean_env,
|
||||
interpret_enum_env,
|
||||
interpret_int_env,
|
||||
@ -216,7 +216,7 @@ def test_replace_defaults(
|
||||
|
||||
|
||||
def reflex_dir_constant() -> Path:
|
||||
return environment.REFLEX_DIR.get()
|
||||
return EnvironmentVariables.REFLEX_DIR.get()
|
||||
|
||||
|
||||
def test_reflex_dir_env_var(monkeypatch: pytest.MonkeyPatch, tmp_path: Path) -> None:
|
||||
@ -253,6 +253,11 @@ def test_env_var():
|
||||
INTERNAL: EnvVar[str] = env_var("default", internal=True)
|
||||
BOOLEAN: EnvVar[bool] = env_var(False)
|
||||
|
||||
# default_factory with other env_var as fallback
|
||||
BLUBB_OR_BLA: EnvVar[str] = env_var(
|
||||
default_factory=lambda: TestEnv.BLUBB.getenv() or "bla"
|
||||
)
|
||||
|
||||
assert TestEnv.BLUBB.get() == "default"
|
||||
assert TestEnv.BLUBB.name == "BLUBB"
|
||||
TestEnv.BLUBB.set("new")
|
||||
@ -280,3 +285,15 @@ def test_env_var():
|
||||
assert TestEnv.BOOLEAN.get() is False
|
||||
TestEnv.BOOLEAN.set(None)
|
||||
assert "BOOLEAN" not in os.environ
|
||||
|
||||
assert TestEnv.BLUBB_OR_BLA.get() == "bla"
|
||||
TestEnv.BLUBB.set("new")
|
||||
assert TestEnv.BLUBB_OR_BLA.get() == "new"
|
||||
TestEnv.BLUBB.set(None)
|
||||
assert TestEnv.BLUBB_OR_BLA.get() == "bla"
|
||||
TestEnv.BLUBB_OR_BLA.set("test")
|
||||
assert TestEnv.BLUBB_OR_BLA.get() == "test"
|
||||
TestEnv.BLUBB.set("other")
|
||||
assert TestEnv.BLUBB_OR_BLA.get() == "test"
|
||||
TestEnv.BLUBB_OR_BLA.set(None)
|
||||
TestEnv.BLUBB.set(None)
|
||||
|
@ -10,7 +10,7 @@ from packaging import version
|
||||
|
||||
from reflex import constants
|
||||
from reflex.base import Base
|
||||
from reflex.config import environment
|
||||
from reflex.config import EnvironmentVariables
|
||||
from reflex.event import EventHandler
|
||||
from reflex.state import BaseState
|
||||
from reflex.utils import (
|
||||
@ -598,7 +598,7 @@ def test_style_prop_with_event_handler_value(callable):
|
||||
|
||||
def test_is_prod_mode() -> None:
|
||||
"""Test that the prod mode is correctly determined."""
|
||||
environment.REFLEX_ENV_MODE.set(constants.Env.PROD)
|
||||
EnvironmentVariables.REFLEX_ENV_MODE.set(constants.Env.PROD)
|
||||
assert utils_exec.is_prod_mode()
|
||||
environment.REFLEX_ENV_MODE.set(None)
|
||||
EnvironmentVariables.REFLEX_ENV_MODE.set(None)
|
||||
assert not utils_exec.is_prod_mode()
|
||||
|
Loading…
Reference in New Issue
Block a user