refactor - ruff broke the imports..

This commit is contained in:
Benedikt Bartscher 2024-10-24 23:53:05 +02:00
parent a7ffab9488
commit 1499282f43
No known key found for this signature in database
18 changed files with 201 additions and 128 deletions

View File

@ -85,7 +85,7 @@ from reflex.state import (
code_uses_state_contexts, code_uses_state_contexts,
) )
from reflex.utils import codespaces, console, exceptions, format, prerequisites, types from reflex.utils import codespaces, console, exceptions, format, prerequisites, types
from reflex.utils.exec import is_prod_mode, is_testing_env, should_skip_compile from reflex.utils.exec import is_prod_mode, is_testing_env
from reflex.utils.imports import ImportVar from reflex.utils.imports import ImportVar
# Define custom types. # Define custom types.
@ -718,7 +718,7 @@ class App(MiddlewareMixin, LifespanMixin, Base):
Whether the app should be compiled. Whether the app should be compiled.
""" """
# Check the environment variable. # Check the environment variable.
if should_skip_compile(): if environment.REFLEX_SKIP_COMPILE.get:
return False return False
nocompile = prerequisites.get_web_dir() / constants.NOCOMPILE_FILE nocompile = prerequisites.get_web_dir() / constants.NOCOMPILE_FILE
@ -957,7 +957,7 @@ class App(MiddlewareMixin, LifespanMixin, Base):
executor = None executor = None
if ( if (
platform.system() in ("Linux", "Darwin") platform.system() in ("Linux", "Darwin")
and (number_of_processes := environment.REFLEX_COMPILE_PROCESSES) and (number_of_processes := environment.REFLEX_COMPILE_PROCESSES.get)
is not None is not None
): ):
executor = concurrent.futures.ProcessPoolExecutor( executor = concurrent.futures.ProcessPoolExecutor(
@ -966,7 +966,7 @@ class App(MiddlewareMixin, LifespanMixin, Base):
) )
else: else:
executor = concurrent.futures.ThreadPoolExecutor( executor = concurrent.futures.ThreadPoolExecutor(
max_workers=environment.REFLEX_COMPILE_THREADS max_workers=environment.REFLEX_COMPILE_THREADS.get
) )
with executor: with executor:

View File

@ -526,7 +526,7 @@ def remove_tailwind_from_postcss() -> tuple[str, str]:
def purge_web_pages_dir(): def purge_web_pages_dir():
"""Empty out .web/pages directory.""" """Empty out .web/pages directory."""
if not is_prod_mode() and environment.REFLEX_PERSIST_WEB_DIR: if not is_prod_mode() and environment.REFLEX_PERSIST_WEB_DIR.get:
# Skip purging the web directory in dev mode if REFLEX_PERSIST_WEB_DIR is set. # Skip purging the web directory in dev mode if REFLEX_PERSIST_WEB_DIR is set.
return return

View File

@ -125,7 +125,7 @@ def get_upload_dir() -> Path:
""" """
Upload.is_used = True Upload.is_used = True
uploaded_files_dir = environment.REFLEX_UPLOADED_FILES_DIR uploaded_files_dir = environment.REFLEX_UPLOADED_FILES_DIR.get
uploaded_files_dir.mkdir(parents=True, exist_ok=True) uploaded_files_dir.mkdir(parents=True, exist_ok=True)
return uploaded_files_dir return uploaded_files_dir

View File

@ -8,7 +8,17 @@ 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 (
TYPE_CHECKING,
Any,
Dict,
Generic,
List,
Optional,
Set,
TypeVar,
get_args,
)
from typing_extensions import get_type_hints from typing_extensions import get_type_hints
@ -259,86 +269,178 @@ def interpret_env_var_value(
) )
@dataclasses.dataclass(init=False) T = TypeVar("T")
class EnvVar(Generic[T]):
"""Environment variable."""
name: str
default: Any
type_: T
def __init__(self, name: str, default: Any, type_: T) -> None:
"""Initialize the environment variable.
Args:
name: The environment variable name.
default: The default value.
type_: The type of the value.
"""
self.name = name
self.default = default
self.type_ = type_
def getenv(self) -> Any:
"""Get the environment variable from os.environ.
Returns:
The environment variable value.
"""
return os.getenv(self.name, None)
@property
def get(self) -> T:
"""Get the interpreted environment variable value.
Returns:
The interpreted value.
"""
env_value = self.getenv()
if env_value is not None:
return interpret_env_var_value(env_value, self.type_, self.name)
return self.default
def set(self, value: T) -> None:
"""Set the environment variable.
Args:
value: The value to set.
"""
if value is None:
_ = os.environ.pop(self.name, None)
else:
os.environ[self.name] = str(value)
class env_var: # type: ignore
"""Descriptor for environment variables."""
name: str
default: Any
def __init__(self, default: Any):
"""Initialize the descriptor.
Args:
default: The default value.
"""
self.default = default
def __set_name__(self, owner, name):
"""Set the name of the descriptor.
Args:
owner: The owner class.
name: The name of the descriptor.
"""
self.name = name
def __get__(self, instance, owner):
"""Get the EnvVar instance.
Args:
instance: The instance.
owner: The owner class.
"""
type_ = get_args(get_type_hints(owner)[self.name])[0]
return EnvVar[type_](name=self.name, default=self.default, type_=type_)
if TYPE_CHECKING:
def env_var(default) -> EnvVar:
"""Typing helper for the env_var descriptor."""
return default
class EnvironmentVariables: class EnvironmentVariables:
"""Environment variables class to instantiate environment variables.""" """Environment variables class to instantiate environment variables."""
# Whether to use npm over bun to install frontend packages. # Whether to use npm over bun to install frontend packages.
REFLEX_USE_NPM: bool = False REFLEX_USE_NPM: EnvVar[bool] = env_var(False)
# The npm registry to use. # The npm registry to use.
NPM_CONFIG_REGISTRY: Optional[str] = None NPM_CONFIG_REGISTRY: EnvVar[Optional[str]] = env_var(None)
# Whether to use Granian for the backend. Otherwise, use Uvicorn. # Whether to use Granian for the backend. Otherwise, use Uvicorn.
REFLEX_USE_GRANIAN: bool = False REFLEX_USE_GRANIAN: EnvVar[bool] = env_var(False)
# The username to use for authentication on python package repository. Username and password must both be provided. # The username to use for authentication on python package repository. Username and password must both be provided.
TWINE_USERNAME: Optional[str] = None TWINE_USERNAME: EnvVar[Optional[str]] = env_var(None)
# The password to use for authentication on python package repository. Username and password must both be provided. # The password to use for authentication on python package repository. Username and password must both be provided.
TWINE_PASSWORD: Optional[str] = None TWINE_PASSWORD: EnvVar[Optional[str]] = env_var(None)
# Whether to use the system installed bun. If set to false, bun will be bundled with the app. # Whether to use the system installed bun. If set to false, bun will be bundled with the app.
REFLEX_USE_SYSTEM_BUN: bool = False REFLEX_USE_SYSTEM_BUN: EnvVar[bool] = env_var(False)
# Whether to use the system installed node and npm. If set to false, node and npm will be bundled with the app. # Whether to use the system installed node and npm. If set to false, node and npm will be bundled with the app.
REFLEX_USE_SYSTEM_NODE: bool = False REFLEX_USE_SYSTEM_NODE: EnvVar[bool] = env_var(False)
# The working directory for the next.js commands. # The working directory for the next.js commands.
REFLEX_WEB_WORKDIR: Path = Path(constants.Dirs.WEB) REFLEX_WEB_WORKDIR: EnvVar[Path] = env_var(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: EnvVar[Path] = env_var(Path(constants.ALEMBIC_CONFIG))
# Disable SSL verification for HTTPX requests. # Disable SSL verification for HTTPX requests.
SSL_NO_VERIFY: bool = False SSL_NO_VERIFY: EnvVar[bool] = env_var(False)
# The directory to store uploaded files. # The directory to store uploaded files.
REFLEX_UPLOADED_FILES_DIR: Path = Path(constants.Dirs.UPLOADED_FILES) REFLEX_UPLOADED_FILES_DIR: EnvVar[Path] = env_var(
Path(constants.Dirs.UPLOADED_FILES)
# Whether to use seperate processes to compile the frontend and how many. If not set, defaults to thread executor.
REFLEX_COMPILE_PROCESSES: Optional[int] = None
# Whether to use seperate threads to compile the frontend and how many. Defaults to `min(32, os.cpu_count() + 4)`.
REFLEX_COMPILE_THREADS: Optional[int] = None
# The directory to store reflex dependencies.
REFLEX_DIR: Path = Path(constants.Reflex.DIR)
# Whether to print the SQL queries if the log level is INFO or lower.
SQLALCHEMY_ECHO: bool = False
# Whether to ignore the redis config error. Some redis servers only allow out-of-band configuration.
REFLEX_IGNORE_REDIS_CONFIG_ERROR: bool = False
# Whether to skip purging the web directory in dev mode.
REFLEX_PERSIST_WEB_DIR: bool = False
# The reflex.build frontend host.
REFLEX_BUILD_FRONTEND: str = constants.Templates.REFLEX_BUILD_FRONTEND
# The reflex.build backend host.
REFLEX_BUILD_BACKEND: str = constants.Templates.REFLEX_BUILD_BACKEND
def __init__(self):
"""Initialize the environment variables."""
type_hints = get_type_hints(type(self))
for field in dataclasses.fields(self):
raw_value = os.getenv(field.name, None)
field.type = type_hints.get(field.name) or field.type
value = (
interpret_env_var_value(raw_value, field.type, field.name)
if raw_value is not None
else get_default_value_for_field(field)
) )
setattr(self, field.name, value) # Whether to use separate processes to compile the frontend and how many. If not set, defaults to thread executor.
REFLEX_COMPILE_PROCESSES: EnvVar[Optional[int]] = env_var(None)
# Whether to use separate threads to compile the frontend and how many. Defaults to `min(32, os.cpu_count() + 4)`.
REFLEX_COMPILE_THREADS: EnvVar[Optional[int]] = env_var(None)
environment = EnvironmentVariables() # The directory to store reflex dependencies.
REFLEX_DIR: EnvVar[Path] = env_var(Path(constants.Reflex.DIR))
# Whether to print the SQL queries if the log level is INFO or lower.
SQLALCHEMY_ECHO: EnvVar[bool] = env_var(False)
# Whether to ignore the redis config error. Some redis servers only allow out-of-band configuration.
REFLEX_IGNORE_REDIS_CONFIG_ERROR: EnvVar[bool] = env_var(False)
# Whether to skip purging the web directory in dev mode.
REFLEX_PERSIST_WEB_DIR: EnvVar[bool] = env_var(False)
# The reflex.build frontend host.
REFLEX_BUILD_FRONTEND: EnvVar[str] = env_var(
constants.Templates.REFLEX_BUILD_FRONTEND
)
# The reflex.build backend host.
REFLEX_BUILD_BACKEND: EnvVar[str] = env_var(
constants.Templates.REFLEX_BUILD_BACKEND
)
# If this env var is set to "yes", App.compile will be a no-op
REFLEX_SKIP_COMPILE: EnvVar[bool] = env_var(False)
# This env var stores the execution mode of the app
REFLEX_ENV_MODE: EnvVar[constants.Env] = env_var(constants.Env.DEV)
# Whether to run the backend only. Exclusive with REFLEX_FRONTEND_ONLY.
REFLEX_BACKEND_ONLY: EnvVar[bool] = env_var(False)
# Whether to run the frontend only. Exclusive with REFLEX_BACKEND_ONLY.
REFLEX_FRONTEND_ONLY: EnvVar[bool] = env_var(False)
class Config(Base): class Config(Base):

View File

@ -2,9 +2,6 @@
from .base import ( from .base import (
COOKIES, COOKIES,
ENV_BACKEND_ONLY_ENV_VAR,
ENV_FRONTEND_ONLY_ENV_VAR,
ENV_MODE_ENV_VAR,
IS_WINDOWS, IS_WINDOWS,
LOCAL_STORAGE, LOCAL_STORAGE,
POLLING_MAX_HTTP_BUFFER_SIZE, POLLING_MAX_HTTP_BUFFER_SIZE,
@ -13,7 +10,6 @@ from .base import (
REFLEX_VAR_OPENING_TAG, REFLEX_VAR_OPENING_TAG,
RELOAD_CONFIG, RELOAD_CONFIG,
SESSION_STORAGE, SESSION_STORAGE,
SKIP_COMPILE_ENV_VAR,
ColorMode, ColorMode,
Dirs, Dirs,
Env, Env,
@ -116,7 +112,6 @@ __ALL__ = [
ROUTER_DATA_INCLUDE, ROUTER_DATA_INCLUDE,
ROUTE_NOT_FOUND, ROUTE_NOT_FOUND,
SETTER_PREFIX, SETTER_PREFIX,
SKIP_COMPILE_ENV_VAR,
SocketEvent, SocketEvent,
StateManagerMode, StateManagerMode,
Tailwind, Tailwind,

View File

@ -112,7 +112,7 @@ class Templates(SimpleNamespace):
from reflex.config import environment from reflex.config import environment
return ( return (
environment.REFLEX_BUILD_FRONTEND environment.REFLEX_BUILD_FRONTEND.get
+ "/gen?reflex_init_token={reflex_init_token}" + "/gen?reflex_init_token={reflex_init_token}"
) )
@ -126,7 +126,7 @@ class Templates(SimpleNamespace):
""" """
from reflex.config import environment from reflex.config import environment
return environment.REFLEX_BUILD_BACKEND + "/api/init/{reflex_init_token}" return environment.REFLEX_BUILD_BACKEND.get + "/api/init/{reflex_init_token}"
@classproperty @classproperty
@classmethod @classmethod
@ -139,7 +139,8 @@ class Templates(SimpleNamespace):
from reflex.config import environment from reflex.config import environment
return ( return (
environment.REFLEX_BUILD_BACKEND + "/api/gen/{generation_hash}/refactored" environment.REFLEX_BUILD_BACKEND.get
+ "/api/gen/{generation_hash}/refactored"
) )
class Dirs(SimpleNamespace): class Dirs(SimpleNamespace):
@ -239,15 +240,6 @@ COOKIES = "cookies"
LOCAL_STORAGE = "local_storage" LOCAL_STORAGE = "local_storage"
SESSION_STORAGE = "session_storage" SESSION_STORAGE = "session_storage"
# If this env var is set to "yes", App.compile will be a no-op
SKIP_COMPILE_ENV_VAR = "__REFLEX_SKIP_COMPILE"
# This env var stores the execution mode of the app
ENV_MODE_ENV_VAR = "REFLEX_ENV_MODE"
ENV_BACKEND_ONLY_ENV_VAR = "REFLEX_BACKEND_ONLY"
ENV_FRONTEND_ONLY_ENV_VAR = "REFLEX_FRONTEND_ONLY"
# Testing variables. # Testing variables.
# Testing os env set by pytest when running a test case. # Testing os env set by pytest when running a test case.
PYTEST_CURRENT_TEST = "PYTEST_CURRENT_TEST" PYTEST_CURRENT_TEST = "PYTEST_CURRENT_TEST"

View File

@ -63,7 +63,7 @@ class Bun(SimpleNamespace):
""" """
from reflex.config import environment from reflex.config import environment
return environment.REFLEX_DIR / "bun" return environment.REFLEX_DIR.get / "bun"
@classproperty @classproperty
@classmethod @classmethod
@ -100,7 +100,7 @@ class Fnm(SimpleNamespace):
""" """
from reflex.config import environment from reflex.config import environment
return environment.REFLEX_DIR / "fnm" return environment.REFLEX_DIR.get / "fnm"
@classproperty @classproperty
@classmethod @classmethod

View File

@ -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", 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( username: Optional[str] = typer.Option(
environment.TWINE_USERNAME, environment.TWINE_USERNAME.name,
"-u", "-u",
"--username", "--username",
show_default="TWINE_USERNAME environment variable value if set", 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.", help="The username to use for authentication on python package repository. Username and password must both be provided.",
), ),
password: Optional[str] = typer.Option( password: Optional[str] = typer.Option(
environment.TWINE_PASSWORD, environment.TWINE_PASSWORD.name,
"-p", "-p",
"--password", "--password",
show_default="TWINE_PASSWORD environment variable value if set", show_default="TWINE_PASSWORD environment variable value if set",

View File

@ -38,12 +38,12 @@ def get_engine(url: str | None = None) -> sqlalchemy.engine.Engine:
url = url or conf.db_url url = url or conf.db_url
if url is None: if url is None:
raise ValueError("No database url configured") raise ValueError("No database url configured")
if environment.ALEMBIC_CONFIG.exists(): if environment.ALEMBIC_CONFIG.get.exists():
console.warn( console.warn(
"Database is not initialized, run [bold]reflex db init[/bold] first." "Database is not initialized, run [bold]reflex db init[/bold] first."
) )
# Print the SQL queries if the log level is INFO or lower. # Print the SQL queries if the log level is INFO or lower.
echo_db_query = environment.SQLALCHEMY_ECHO echo_db_query = environment.SQLALCHEMY_ECHO.get
# Needed for the admin dash on sqlite. # Needed for the admin dash on sqlite.
connect_args = {"check_same_thread": False} if url.startswith("sqlite") else {} connect_args = {"check_same_thread": False} if url.startswith("sqlite") else {}
return sqlmodel.create_engine(url, echo=echo_db_query, connect_args=connect_args) 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: Returns:
tuple of (config, script_directory) tuple of (config, script_directory)
""" """
config = alembic.config.Config(environment.ALEMBIC_CONFIG) config = alembic.config.Config(environment.ALEMBIC_CONFIG.get)
return config, alembic.script.ScriptDirectory( return config, alembic.script.ScriptDirectory(
config.get_main_option("script_location", default="version"), config.get_main_option("script_location", default="version"),
) )
@ -266,8 +266,8 @@ class Model(Base, sqlmodel.SQLModel): # pyright: ignore [reportGeneralTypeIssue
def alembic_init(cls): def alembic_init(cls):
"""Initialize alembic for the project.""" """Initialize alembic for the project."""
alembic.command.init( alembic.command.init(
config=alembic.config.Config(environment.ALEMBIC_CONFIG), config=alembic.config.Config(environment.ALEMBIC_CONFIG.get),
directory=str(environment.ALEMBIC_CONFIG.parent / "alembic"), directory=str(environment.ALEMBIC_CONFIG.get.parent / "alembic"),
) )
@classmethod @classmethod
@ -287,7 +287,7 @@ class Model(Base, sqlmodel.SQLModel): # pyright: ignore [reportGeneralTypeIssue
Returns: Returns:
True when changes have been detected. True when changes have been detected.
""" """
if not environment.ALEMBIC_CONFIG.exists(): if not environment.ALEMBIC_CONFIG.get.exists():
return False return False
config, script_directory = cls._alembic_config() config, script_directory = cls._alembic_config()
@ -388,7 +388,7 @@ class Model(Base, sqlmodel.SQLModel): # pyright: ignore [reportGeneralTypeIssue
True - indicating the process was successful. True - indicating the process was successful.
None - indicating the process was skipped. None - indicating the process was skipped.
""" """
if not environment.ALEMBIC_CONFIG.exists(): if not environment.ALEMBIC_CONFIG.get.exists():
return return
with cls.get_db_engine().connect() as connection: with cls.get_db_engine().connect() as connection:

View File

@ -160,7 +160,7 @@ def _run(
console.set_log_level(loglevel) console.set_log_level(loglevel)
# Set env mode in the environment # Set env mode in the environment
os.environ[constants.ENV_MODE_ENV_VAR] = env.value environment.REFLEX_ENV_MODE.set(env)
# Show system info # Show system info
exec.output_system_info() exec.output_system_info()
@ -277,13 +277,13 @@ def run(
False, False,
"--frontend-only", "--frontend-only",
help="Execute only frontend.", help="Execute only frontend.",
envvar=constants.ENV_FRONTEND_ONLY_ENV_VAR, envvar=environment.REFLEX_FRONTEND_ONLY.name,
), ),
backend: bool = typer.Option( backend: bool = typer.Option(
False, False,
"--backend-only", "--backend-only",
help="Execute only backend.", help="Execute only backend.",
envvar=constants.ENV_BACKEND_ONLY_ENV_VAR, envvar=environment.REFLEX_BACKEND_ONLY.name,
), ),
frontend_port: str = typer.Option( frontend_port: str = typer.Option(
config.frontend_port, help="Specify a different frontend port." config.frontend_port, help="Specify a different frontend port."
@ -302,8 +302,8 @@ def run(
if frontend and backend: if frontend and backend:
console.error("Cannot use both --frontend-only and --backend-only options.") console.error("Cannot use both --frontend-only and --backend-only options.")
raise typer.Exit(1) raise typer.Exit(1)
os.environ[constants.ENV_BACKEND_ONLY_ENV_VAR] = str(backend).lower() environment.REFLEX_BACKEND_ONLY.set(backend)
os.environ[constants.ENV_FRONTEND_ONLY_ENV_VAR] = str(frontend).lower() environment.REFLEX_FRONTEND_ONLY.set(frontend)
_run(env, frontend, backend, frontend_port, backend_port, backend_host, loglevel) _run(env, frontend, backend, frontend_port, backend_port, backend_host, loglevel)
@ -405,7 +405,7 @@ script_cli = typer.Typer()
def _skip_compile(): def _skip_compile():
"""Skip the compile step.""" """Skip the compile step."""
os.environ[constants.SKIP_COMPILE_ENV_VAR] = "yes" environment.REFLEX_SKIP_COMPILE.set(True)
@db_cli.command(name="init") @db_cli.command(name="init")
@ -420,7 +420,7 @@ def db_init():
return return
# Check the alembic config. # Check the alembic config.
if environment.ALEMBIC_CONFIG.exists(): if environment.ALEMBIC_CONFIG.get.exists():
console.error( console.error(
"Database is already initialized. Use " "Database is already initialized. Use "
"[bold]reflex db makemigrations[/bold] to create schema change " "[bold]reflex db makemigrations[/bold] to create schema change "

View File

@ -3327,7 +3327,7 @@ class StateManagerRedis(StateManager):
) )
except ResponseError: except ResponseError:
# Some redis servers only allow out-of-band configuration, so ignore errors here. # Some redis servers only allow out-of-band configuration, so ignore errors here.
if not environment.REFLEX_IGNORE_REDIS_CONFIG_ERROR: if not environment.REFLEX_IGNORE_REDIS_CONFIG_ERROR.get:
raise raise
async with self.redis.pubsub() as pubsub: async with self.redis.pubsub() as pubsub:
await pubsub.psubscribe(lock_key_channel) await pubsub.psubscribe(lock_key_channel)

View File

@ -250,7 +250,9 @@ class AppHarness:
def _initialize_app(self): def _initialize_app(self):
# disable telemetry reporting for tests # disable telemetry reporting for tests
os.environ["TELEMETRY_ENABLED"] = "false" from reflex.config import environment
environment.TELEMETRY_ENABLED = False
self.app_path.mkdir(parents=True, exist_ok=True) self.app_path.mkdir(parents=True, exist_ok=True)
if self.app_source is not None: if self.app_source is not None:
app_globals = self._get_globals_from_signature(self.app_source) app_globals = self._get_globals_from_signature(self.app_source)
@ -942,9 +944,11 @@ class AppHarnessProd(AppHarness):
raise RuntimeError("Frontend did not start") raise RuntimeError("Frontend did not start")
def _start_backend(self): def _start_backend(self):
from reflex.config import environment
if self.app_instance is None: if self.app_instance is None:
raise RuntimeError("App was not initialized.") raise RuntimeError("App was not initialized.")
os.environ[reflex.constants.SKIP_COMPILE_ENV_VAR] = "yes" environment.REFLEX_SKIP_COMPILE.set(True)
self.backend = uvicorn.Server( self.backend = uvicorn.Server(
uvicorn.Config( uvicorn.Config(
app=self.app_instance, app=self.app_instance,
@ -958,10 +962,12 @@ class AppHarnessProd(AppHarness):
self.backend_thread.start() self.backend_thread.start()
def _poll_for_servers(self, timeout: TimeoutType = None) -> socket.socket: def _poll_for_servers(self, timeout: TimeoutType = None) -> socket.socket:
from reflex.config import environment
try: try:
return super()._poll_for_servers(timeout) return super()._poll_for_servers(timeout)
finally: finally:
os.environ.pop(reflex.constants.SKIP_COMPILE_ENV_VAR, None) environment.REFLEX_SKIP_COMPILE.set(False)
def stop(self): def stop(self):
"""Stop the frontend python webserver.""" """Stop the frontend python webserver."""

View File

@ -184,7 +184,7 @@ def should_use_granian():
Returns: Returns:
True if Granian should be used. True if Granian should be used.
""" """
return environment.REFLEX_USE_GRANIAN return environment.REFLEX_USE_GRANIAN.get
def get_app_module(): def get_app_module():
@ -369,7 +369,9 @@ def run_uvicorn_backend_prod(host, port, loglevel):
command, command,
run=True, run=True,
show_logs=True, show_logs=True,
env={constants.SKIP_COMPILE_ENV_VAR: "yes"}, # skip compile for prod backend env={
environment.REFLEX_SKIP_COMPILE.name: "yes"
}, # skip compile for prod backend
) )
@ -405,7 +407,7 @@ def run_granian_backend_prod(host, port, loglevel):
run=True, run=True,
show_logs=True, show_logs=True,
env={ env={
constants.SKIP_COMPILE_ENV_VAR: "yes" environment.REFLEX_SKIP_COMPILE.name: "yes"
}, # skip compile for prod backend }, # skip compile for prod backend
) )
except ImportError: except ImportError:
@ -490,34 +492,8 @@ def is_prod_mode() -> bool:
True if the app is running in production mode or False if running in dev mode. True if the app is running in production mode or False if running in dev mode.
""" """
current_mode = os.environ.get( current_mode = os.environ.get(
constants.ENV_MODE_ENV_VAR, environment.REFLEX_ENV_MODE.get,
constants.Env.DEV.value, constants.Env.DEV.value,
) )
current_mode = environment.REFLEX_ENV_MODE.get
return current_mode == constants.Env.PROD.value return current_mode == constants.Env.PROD.value
def is_frontend_only() -> bool:
"""Check if the app is running in frontend-only mode.
Returns:
True if the app is running in frontend-only mode.
"""
return os.environ.get(constants.ENV_FRONTEND_ONLY_ENV_VAR, "").lower() == "true"
def is_backend_only() -> bool:
"""Check if the app is running in backend-only mode.
Returns:
True if the app is running in backend-only mode.
"""
return os.environ.get(constants.ENV_BACKEND_ONLY_ENV_VAR, "").lower() == "true"
def should_skip_compile() -> bool:
"""Whether the app should skip compile.
Returns:
True if the app should skip compile.
"""
return os.environ.get(constants.SKIP_COMPILE_ENV_VAR) == "yes"

View File

@ -136,7 +136,7 @@ def use_system_node() -> bool:
Returns: Returns:
Whether the system node should be used. Whether the system node should be used.
""" """
return environment.REFLEX_USE_SYSTEM_NODE return environment.REFLEX_USE_SYSTEM_NODE.get
def use_system_bun() -> bool: def use_system_bun() -> bool:
@ -145,7 +145,7 @@ def use_system_bun() -> bool:
Returns: Returns:
Whether the system bun should be used. Whether the system bun should be used.
""" """
return environment.REFLEX_USE_SYSTEM_BUN return environment.REFLEX_USE_SYSTEM_BUN.get
def get_node_bin_path() -> Path | None: def get_node_bin_path() -> Path | None:

View File

@ -69,7 +69,7 @@ def get_web_dir() -> Path:
Returns: Returns:
The working directory. The working directory.
""" """
return environment.REFLEX_WEB_WORKDIR return environment.REFLEX_WEB_WORKDIR.get
def _python_version_check(): def _python_version_check():
@ -249,7 +249,7 @@ def windows_npm_escape_hatch() -> bool:
Returns: Returns:
If the user has set REFLEX_USE_NPM. If the user has set REFLEX_USE_NPM.
""" """
return environment.REFLEX_USE_NPM return environment.REFLEX_USE_NPM.get
def get_app(reload: bool = False) -> ModuleType: def get_app(reload: bool = False) -> ModuleType:
@ -991,7 +991,7 @@ def needs_reinit(frontend: bool = True) -> bool:
return False return False
# Make sure the .reflex directory exists. # Make sure the .reflex directory exists.
if not environment.REFLEX_DIR.exists(): if not environment.REFLEX_DIR.get.exists():
return True return True
# Make sure the .web directory exists in frontend mode. # Make sure the .web directory exists in frontend mode.
@ -1096,7 +1096,7 @@ def ensure_reflex_installation_id() -> Optional[int]:
""" """
try: try:
initialize_reflex_user_directory() initialize_reflex_user_directory()
installation_id_file = environment.REFLEX_DIR / "installation_id" installation_id_file = environment.REFLEX_DIR.get / "installation_id"
installation_id = None installation_id = None
if installation_id_file.exists(): if installation_id_file.exists():
@ -1121,7 +1121,7 @@ def ensure_reflex_installation_id() -> Optional[int]:
def initialize_reflex_user_directory(): def initialize_reflex_user_directory():
"""Initialize the reflex user directory.""" """Initialize the reflex user directory."""
# Create the reflex directory. # Create the reflex directory.
path_ops.mkdir(environment.REFLEX_DIR) path_ops.mkdir(environment.REFLEX_DIR.get)
def initialize_frontend_dependencies(): def initialize_frontend_dependencies():
@ -1144,7 +1144,7 @@ def check_db_initialized() -> bool:
Returns: Returns:
True if alembic is initialized (or if database is not used). True if alembic is initialized (or if database is not used).
""" """
if get_config().db_url is not None and not environment.ALEMBIC_CONFIG.exists(): if get_config().db_url is not None and not environment.ALEMBIC_CONFIG.get.exists():
console.error( console.error(
"Database is not initialized. Run [bold]reflex db init[/bold] first." "Database is not initialized. Run [bold]reflex db init[/bold] first."
) )
@ -1154,7 +1154,7 @@ def check_db_initialized() -> bool:
def check_schema_up_to_date(): def check_schema_up_to_date():
"""Check if the sqlmodel metadata matches the current database schema.""" """Check if the sqlmodel metadata matches the current database schema."""
if get_config().db_url is None or not environment.ALEMBIC_CONFIG.exists(): if get_config().db_url is None or not environment.ALEMBIC_CONFIG.get.exists():
return return
with model.Model.get_db_engine().connect() as connection: with model.Model.get_db_engine().connect() as connection:
try: try:

View File

@ -55,4 +55,4 @@ def _get_npm_registry() -> str:
Returns: Returns:
str: str:
""" """
return environment.NPM_CONFIG_REGISTRY or get_best_registry() return environment.NPM_CONFIG_REGISTRY.get or get_best_registry()

View File

@ -20,7 +20,6 @@ import psutil
from reflex import constants from reflex import constants
from reflex.utils import console from reflex.utils import console
from reflex.utils.exec import should_skip_compile
from reflex.utils.prerequisites import ensure_reflex_installation_id, get_project_hash from reflex.utils.prerequisites import ensure_reflex_installation_id, get_project_hash
POSTHOG_API_URL: str = "https://app.posthog.com/capture/" POSTHOG_API_URL: str = "https://app.posthog.com/capture/"
@ -94,7 +93,9 @@ def _raise_on_missing_project_hash() -> bool:
False when compilation should be skipped (i.e. no .web directory is required). False when compilation should be skipped (i.e. no .web directory is required).
Otherwise return True. Otherwise return True.
""" """
return not should_skip_compile() from reflex.config import environment
return not environment.REFLEX_SKIP_COMPILE
def _prepare_event(event: str, **kwargs) -> dict: def _prepare_event(event: str, **kwargs) -> dict:

View File

@ -209,7 +209,7 @@ def test_replace_defaults(
def reflex_dir_constant(): def reflex_dir_constant():
return environment.REFLEX_DIR return environment.REFLEX_DIR.get
def test_reflex_dir_env_var(monkeypatch, tmp_path): def test_reflex_dir_env_var(monkeypatch, tmp_path):
@ -222,5 +222,6 @@ def test_reflex_dir_env_var(monkeypatch, tmp_path):
monkeypatch.setenv("REFLEX_DIR", str(tmp_path)) monkeypatch.setenv("REFLEX_DIR", str(tmp_path))
mp_ctx = multiprocessing.get_context(method="spawn") mp_ctx = multiprocessing.get_context(method="spawn")
assert reflex_dir_constant() == tmp_path
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