reflex 0.7.14a3__py3-none-any.whl → 0.7.14a5__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/app.py +2 -1
- reflex/assets.py +1 -1
- reflex/compiler/compiler.py +2 -1
- reflex/components/base/bare.py +17 -5
- reflex/components/component.py +30 -6
- reflex/components/core/banner.py +1 -1
- reflex/components/core/upload.py +1 -1
- reflex/config.py +16 -608
- reflex/constants/base.py +3 -3
- reflex/constants/installer.py +1 -1
- reflex/environment.py +606 -0
- reflex/istate/manager.py +2 -1
- reflex/model.py +2 -1
- reflex/reflex.py +2 -1
- reflex/state.py +1 -1
- reflex/testing.py +3 -1
- reflex/utils/console.py +2 -2
- reflex/utils/exec.py +2 -1
- reflex/utils/export.py +2 -1
- reflex/utils/net.py +2 -2
- reflex/utils/path_ops.py +2 -1
- reflex/utils/prerequisites.py +2 -1
- reflex/utils/processes.py +1 -1
- reflex/utils/registry.py +1 -1
- reflex/utils/telemetry.py +1 -1
- {reflex-0.7.14a3.dist-info → reflex-0.7.14a5.dist-info}/METADATA +1 -1
- {reflex-0.7.14a3.dist-info → reflex-0.7.14a5.dist-info}/RECORD +30 -29
- {reflex-0.7.14a3.dist-info → reflex-0.7.14a5.dist-info}/WHEEL +0 -0
- {reflex-0.7.14a3.dist-info → reflex-0.7.14a5.dist-info}/entry_points.txt +0 -0
- {reflex-0.7.14a3.dist-info → reflex-0.7.14a5.dist-info}/licenses/LICENSE +0 -0
reflex/config.py
CHANGED
|
@@ -2,48 +2,30 @@
|
|
|
2
2
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
|
-
import concurrent.futures
|
|
6
|
-
import dataclasses
|
|
7
|
-
import enum
|
|
8
5
|
import importlib
|
|
9
|
-
import inspect
|
|
10
|
-
import multiprocessing
|
|
11
6
|
import os
|
|
12
|
-
import platform
|
|
13
7
|
import sys
|
|
14
8
|
import threading
|
|
15
9
|
import urllib.parse
|
|
16
|
-
from collections.abc import Callable
|
|
17
|
-
from functools import lru_cache
|
|
18
10
|
from importlib.util import find_spec
|
|
19
11
|
from pathlib import Path
|
|
20
12
|
from types import ModuleType
|
|
21
|
-
from typing import
|
|
22
|
-
TYPE_CHECKING,
|
|
23
|
-
Annotated,
|
|
24
|
-
Any,
|
|
25
|
-
ClassVar,
|
|
26
|
-
Generic,
|
|
27
|
-
TypeVar,
|
|
28
|
-
get_args,
|
|
29
|
-
get_origin,
|
|
30
|
-
get_type_hints,
|
|
31
|
-
)
|
|
13
|
+
from typing import Any, ClassVar
|
|
32
14
|
|
|
33
15
|
import pydantic.v1 as pydantic
|
|
34
16
|
|
|
35
17
|
from reflex import constants
|
|
36
18
|
from reflex.base import Base
|
|
37
19
|
from reflex.constants.base import LogLevel
|
|
20
|
+
from reflex.environment import EnvironmentVariables as EnvironmentVariables
|
|
21
|
+
from reflex.environment import EnvVar as EnvVar
|
|
22
|
+
from reflex.environment import ExistingPath, interpret_env_var_value
|
|
23
|
+
from reflex.environment import env_var as env_var
|
|
24
|
+
from reflex.environment import environment as environment
|
|
38
25
|
from reflex.plugins import Plugin, TailwindV3Plugin, TailwindV4Plugin
|
|
39
26
|
from reflex.utils import console
|
|
40
|
-
from reflex.utils.exceptions import ConfigError
|
|
41
|
-
from reflex.utils.types import
|
|
42
|
-
GenericType,
|
|
43
|
-
is_union,
|
|
44
|
-
true_type_for_pydantic_field,
|
|
45
|
-
value_inside_optional,
|
|
46
|
-
)
|
|
27
|
+
from reflex.utils.exceptions import ConfigError
|
|
28
|
+
from reflex.utils.types import true_type_for_pydantic_field
|
|
47
29
|
|
|
48
30
|
try:
|
|
49
31
|
from dotenv import load_dotenv
|
|
@@ -200,582 +182,6 @@ class DBConfig(Base):
|
|
|
200
182
|
return f"{self.engine}://{path}/{self.database}"
|
|
201
183
|
|
|
202
184
|
|
|
203
|
-
def get_default_value_for_field(field: dataclasses.Field) -> Any:
|
|
204
|
-
"""Get the default value for a field.
|
|
205
|
-
|
|
206
|
-
Args:
|
|
207
|
-
field: The field.
|
|
208
|
-
|
|
209
|
-
Returns:
|
|
210
|
-
The default value.
|
|
211
|
-
|
|
212
|
-
Raises:
|
|
213
|
-
ValueError: If no default value is found.
|
|
214
|
-
"""
|
|
215
|
-
if field.default != dataclasses.MISSING:
|
|
216
|
-
return field.default
|
|
217
|
-
if field.default_factory != dataclasses.MISSING:
|
|
218
|
-
return field.default_factory()
|
|
219
|
-
msg = f"Missing value for environment variable {field.name} and no default value found"
|
|
220
|
-
raise ValueError(msg)
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
# TODO: Change all interpret_.* signatures to value: str, field: dataclasses.Field once we migrate rx.Config to dataclasses
|
|
224
|
-
def interpret_boolean_env(value: str, field_name: str) -> bool:
|
|
225
|
-
"""Interpret a boolean environment variable value.
|
|
226
|
-
|
|
227
|
-
Args:
|
|
228
|
-
value: The environment variable value.
|
|
229
|
-
field_name: The field name.
|
|
230
|
-
|
|
231
|
-
Returns:
|
|
232
|
-
The interpreted value.
|
|
233
|
-
|
|
234
|
-
Raises:
|
|
235
|
-
EnvironmentVarValueError: If the value is invalid.
|
|
236
|
-
"""
|
|
237
|
-
true_values = ["true", "1", "yes", "y"]
|
|
238
|
-
false_values = ["false", "0", "no", "n"]
|
|
239
|
-
|
|
240
|
-
if value.lower() in true_values:
|
|
241
|
-
return True
|
|
242
|
-
if value.lower() in false_values:
|
|
243
|
-
return False
|
|
244
|
-
msg = f"Invalid boolean value: {value} for {field_name}"
|
|
245
|
-
raise EnvironmentVarValueError(msg)
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
def interpret_int_env(value: str, field_name: str) -> int:
|
|
249
|
-
"""Interpret an integer environment variable value.
|
|
250
|
-
|
|
251
|
-
Args:
|
|
252
|
-
value: The environment variable value.
|
|
253
|
-
field_name: The field name.
|
|
254
|
-
|
|
255
|
-
Returns:
|
|
256
|
-
The interpreted value.
|
|
257
|
-
|
|
258
|
-
Raises:
|
|
259
|
-
EnvironmentVarValueError: If the value is invalid.
|
|
260
|
-
"""
|
|
261
|
-
try:
|
|
262
|
-
return int(value)
|
|
263
|
-
except ValueError as ve:
|
|
264
|
-
msg = f"Invalid integer value: {value} for {field_name}"
|
|
265
|
-
raise EnvironmentVarValueError(msg) from ve
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
def interpret_existing_path_env(value: str, field_name: str) -> ExistingPath:
|
|
269
|
-
"""Interpret a path environment variable value as an existing path.
|
|
270
|
-
|
|
271
|
-
Args:
|
|
272
|
-
value: The environment variable value.
|
|
273
|
-
field_name: The field name.
|
|
274
|
-
|
|
275
|
-
Returns:
|
|
276
|
-
The interpreted value.
|
|
277
|
-
|
|
278
|
-
Raises:
|
|
279
|
-
EnvironmentVarValueError: If the path does not exist.
|
|
280
|
-
"""
|
|
281
|
-
path = Path(value)
|
|
282
|
-
if not path.exists():
|
|
283
|
-
msg = f"Path does not exist: {path} for {field_name}"
|
|
284
|
-
raise EnvironmentVarValueError(msg)
|
|
285
|
-
return path
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
def interpret_path_env(value: str, field_name: str) -> Path:
|
|
289
|
-
"""Interpret a path environment variable value.
|
|
290
|
-
|
|
291
|
-
Args:
|
|
292
|
-
value: The environment variable value.
|
|
293
|
-
field_name: The field name.
|
|
294
|
-
|
|
295
|
-
Returns:
|
|
296
|
-
The interpreted value.
|
|
297
|
-
"""
|
|
298
|
-
return Path(value)
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
def interpret_enum_env(value: str, field_type: GenericType, field_name: str) -> Any:
|
|
302
|
-
"""Interpret an enum environment variable value.
|
|
303
|
-
|
|
304
|
-
Args:
|
|
305
|
-
value: The environment variable value.
|
|
306
|
-
field_type: The field type.
|
|
307
|
-
field_name: The field name.
|
|
308
|
-
|
|
309
|
-
Returns:
|
|
310
|
-
The interpreted value.
|
|
311
|
-
|
|
312
|
-
Raises:
|
|
313
|
-
EnvironmentVarValueError: If the value is invalid.
|
|
314
|
-
"""
|
|
315
|
-
try:
|
|
316
|
-
return field_type(value)
|
|
317
|
-
except ValueError as ve:
|
|
318
|
-
msg = f"Invalid enum value: {value} for {field_name}"
|
|
319
|
-
raise EnvironmentVarValueError(msg) from ve
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
def interpret_env_var_value(
|
|
323
|
-
value: str, field_type: GenericType, field_name: str
|
|
324
|
-
) -> Any:
|
|
325
|
-
"""Interpret an environment variable value based on the field type.
|
|
326
|
-
|
|
327
|
-
Args:
|
|
328
|
-
value: The environment variable value.
|
|
329
|
-
field_type: The field type.
|
|
330
|
-
field_name: The field name.
|
|
331
|
-
|
|
332
|
-
Returns:
|
|
333
|
-
The interpreted value.
|
|
334
|
-
|
|
335
|
-
Raises:
|
|
336
|
-
ValueError: If the value is invalid.
|
|
337
|
-
"""
|
|
338
|
-
field_type = value_inside_optional(field_type)
|
|
339
|
-
|
|
340
|
-
if is_union(field_type):
|
|
341
|
-
msg = f"Union types are not supported for environment variables: {field_name}."
|
|
342
|
-
raise ValueError(msg)
|
|
343
|
-
|
|
344
|
-
if field_type is bool:
|
|
345
|
-
return interpret_boolean_env(value, field_name)
|
|
346
|
-
if field_type is str:
|
|
347
|
-
return value
|
|
348
|
-
if field_type is int:
|
|
349
|
-
return interpret_int_env(value, field_name)
|
|
350
|
-
if field_type is Path:
|
|
351
|
-
return interpret_path_env(value, field_name)
|
|
352
|
-
if field_type is ExistingPath:
|
|
353
|
-
return interpret_existing_path_env(value, field_name)
|
|
354
|
-
if get_origin(field_type) is list:
|
|
355
|
-
return [
|
|
356
|
-
interpret_env_var_value(
|
|
357
|
-
v,
|
|
358
|
-
get_args(field_type)[0],
|
|
359
|
-
f"{field_name}[{i}]",
|
|
360
|
-
)
|
|
361
|
-
for i, v in enumerate(value.split(":"))
|
|
362
|
-
]
|
|
363
|
-
if inspect.isclass(field_type) and issubclass(field_type, enum.Enum):
|
|
364
|
-
return interpret_enum_env(value, field_type, field_name)
|
|
365
|
-
|
|
366
|
-
msg = f"Invalid type for environment variable {field_name}: {field_type}. This is probably an issue in Reflex."
|
|
367
|
-
raise ValueError(msg)
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
T = TypeVar("T")
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
class EnvVar(Generic[T]):
|
|
374
|
-
"""Environment variable."""
|
|
375
|
-
|
|
376
|
-
name: str
|
|
377
|
-
default: Any
|
|
378
|
-
type_: T
|
|
379
|
-
|
|
380
|
-
def __init__(self, name: str, default: Any, type_: T) -> None:
|
|
381
|
-
"""Initialize the environment variable.
|
|
382
|
-
|
|
383
|
-
Args:
|
|
384
|
-
name: The environment variable name.
|
|
385
|
-
default: The default value.
|
|
386
|
-
type_: The type of the value.
|
|
387
|
-
"""
|
|
388
|
-
self.name = name
|
|
389
|
-
self.default = default
|
|
390
|
-
self.type_ = type_
|
|
391
|
-
|
|
392
|
-
def interpret(self, value: str) -> T:
|
|
393
|
-
"""Interpret the environment variable value.
|
|
394
|
-
|
|
395
|
-
Args:
|
|
396
|
-
value: The environment variable value.
|
|
397
|
-
|
|
398
|
-
Returns:
|
|
399
|
-
The interpreted value.
|
|
400
|
-
"""
|
|
401
|
-
return interpret_env_var_value(value, self.type_, self.name)
|
|
402
|
-
|
|
403
|
-
def getenv(self) -> T | None:
|
|
404
|
-
"""Get the interpreted environment variable value.
|
|
405
|
-
|
|
406
|
-
Returns:
|
|
407
|
-
The environment variable value.
|
|
408
|
-
"""
|
|
409
|
-
env_value = os.getenv(self.name, None)
|
|
410
|
-
if env_value and env_value.strip():
|
|
411
|
-
return self.interpret(env_value)
|
|
412
|
-
return None
|
|
413
|
-
|
|
414
|
-
def is_set(self) -> bool:
|
|
415
|
-
"""Check if the environment variable is set.
|
|
416
|
-
|
|
417
|
-
Returns:
|
|
418
|
-
True if the environment variable is set.
|
|
419
|
-
"""
|
|
420
|
-
return bool(os.getenv(self.name, "").strip())
|
|
421
|
-
|
|
422
|
-
def get(self) -> T:
|
|
423
|
-
"""Get the interpreted environment variable value or the default value if not set.
|
|
424
|
-
|
|
425
|
-
Returns:
|
|
426
|
-
The interpreted value.
|
|
427
|
-
"""
|
|
428
|
-
env_value = self.getenv()
|
|
429
|
-
if env_value is not None:
|
|
430
|
-
return env_value
|
|
431
|
-
return self.default
|
|
432
|
-
|
|
433
|
-
def set(self, value: T | None) -> None:
|
|
434
|
-
"""Set the environment variable. None unsets the variable.
|
|
435
|
-
|
|
436
|
-
Args:
|
|
437
|
-
value: The value to set.
|
|
438
|
-
"""
|
|
439
|
-
if value is None:
|
|
440
|
-
_ = os.environ.pop(self.name, None)
|
|
441
|
-
else:
|
|
442
|
-
if isinstance(value, enum.Enum):
|
|
443
|
-
value = value.value
|
|
444
|
-
if isinstance(value, list):
|
|
445
|
-
str_value = ":".join(str(v) for v in value)
|
|
446
|
-
else:
|
|
447
|
-
str_value = str(value)
|
|
448
|
-
os.environ[self.name] = str_value
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
@lru_cache
|
|
452
|
-
def get_type_hints_environment(cls: type) -> dict[str, Any]:
|
|
453
|
-
"""Get the type hints for the environment variables.
|
|
454
|
-
|
|
455
|
-
Args:
|
|
456
|
-
cls: The class.
|
|
457
|
-
|
|
458
|
-
Returns:
|
|
459
|
-
The type hints.
|
|
460
|
-
"""
|
|
461
|
-
return get_type_hints(cls)
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
class env_var: # noqa: N801 # pyright: ignore [reportRedeclaration]
|
|
465
|
-
"""Descriptor for environment variables."""
|
|
466
|
-
|
|
467
|
-
name: str
|
|
468
|
-
default: Any
|
|
469
|
-
internal: bool = False
|
|
470
|
-
|
|
471
|
-
def __init__(self, default: Any, internal: bool = False) -> None:
|
|
472
|
-
"""Initialize the descriptor.
|
|
473
|
-
|
|
474
|
-
Args:
|
|
475
|
-
default: The default value.
|
|
476
|
-
internal: Whether the environment variable is reflex internal.
|
|
477
|
-
"""
|
|
478
|
-
self.default = default
|
|
479
|
-
self.internal = internal
|
|
480
|
-
|
|
481
|
-
def __set_name__(self, owner: Any, name: str):
|
|
482
|
-
"""Set the name of the descriptor.
|
|
483
|
-
|
|
484
|
-
Args:
|
|
485
|
-
owner: The owner class.
|
|
486
|
-
name: The name of the descriptor.
|
|
487
|
-
"""
|
|
488
|
-
self.name = name
|
|
489
|
-
|
|
490
|
-
def __get__(
|
|
491
|
-
self, instance: EnvironmentVariables, owner: type[EnvironmentVariables]
|
|
492
|
-
):
|
|
493
|
-
"""Get the EnvVar instance.
|
|
494
|
-
|
|
495
|
-
Args:
|
|
496
|
-
instance: The instance.
|
|
497
|
-
owner: The owner class.
|
|
498
|
-
|
|
499
|
-
Returns:
|
|
500
|
-
The EnvVar instance.
|
|
501
|
-
"""
|
|
502
|
-
type_ = get_args(get_type_hints_environment(owner)[self.name])[0]
|
|
503
|
-
env_name = self.name
|
|
504
|
-
if self.internal:
|
|
505
|
-
env_name = f"__{env_name}"
|
|
506
|
-
return EnvVar(name=env_name, default=self.default, type_=type_)
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
if TYPE_CHECKING:
|
|
510
|
-
|
|
511
|
-
def env_var(default: Any, internal: bool = False) -> EnvVar:
|
|
512
|
-
"""Typing helper for the env_var descriptor.
|
|
513
|
-
|
|
514
|
-
Args:
|
|
515
|
-
default: The default value.
|
|
516
|
-
internal: Whether the environment variable is reflex internal.
|
|
517
|
-
|
|
518
|
-
Returns:
|
|
519
|
-
The EnvVar instance.
|
|
520
|
-
"""
|
|
521
|
-
return default
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
class PathExistsFlag:
|
|
525
|
-
"""Flag to indicate that a path must exist."""
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
ExistingPath = Annotated[Path, PathExistsFlag]
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
class PerformanceMode(enum.Enum):
|
|
532
|
-
"""Performance mode for the app."""
|
|
533
|
-
|
|
534
|
-
WARN = "warn"
|
|
535
|
-
RAISE = "raise"
|
|
536
|
-
OFF = "off"
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
class ExecutorType(enum.Enum):
|
|
540
|
-
"""Executor for compiling the frontend."""
|
|
541
|
-
|
|
542
|
-
THREAD = "thread"
|
|
543
|
-
PROCESS = "process"
|
|
544
|
-
MAIN_THREAD = "main_thread"
|
|
545
|
-
|
|
546
|
-
@classmethod
|
|
547
|
-
def get_executor_from_environment(cls):
|
|
548
|
-
"""Get the executor based on the environment variables.
|
|
549
|
-
|
|
550
|
-
Returns:
|
|
551
|
-
The executor.
|
|
552
|
-
"""
|
|
553
|
-
executor_type = environment.REFLEX_COMPILE_EXECUTOR.get()
|
|
554
|
-
|
|
555
|
-
reflex_compile_processes = environment.REFLEX_COMPILE_PROCESSES.get()
|
|
556
|
-
reflex_compile_threads = environment.REFLEX_COMPILE_THREADS.get()
|
|
557
|
-
# By default, use the main thread. Unless the user has specified a different executor.
|
|
558
|
-
# Using a process pool is much faster, but not supported on all platforms. It's gated behind a flag.
|
|
559
|
-
if executor_type is None:
|
|
560
|
-
if (
|
|
561
|
-
platform.system() not in ("Linux", "Darwin")
|
|
562
|
-
and reflex_compile_processes is not None
|
|
563
|
-
):
|
|
564
|
-
console.warn("Multiprocessing is only supported on Linux and MacOS.")
|
|
565
|
-
|
|
566
|
-
if (
|
|
567
|
-
platform.system() in ("Linux", "Darwin")
|
|
568
|
-
and reflex_compile_processes is not None
|
|
569
|
-
):
|
|
570
|
-
if reflex_compile_processes == 0:
|
|
571
|
-
console.warn(
|
|
572
|
-
"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."
|
|
573
|
-
)
|
|
574
|
-
reflex_compile_processes = None
|
|
575
|
-
elif reflex_compile_processes < 0:
|
|
576
|
-
console.warn(
|
|
577
|
-
"Number of processes must be greater than 0. Defaulting to None."
|
|
578
|
-
)
|
|
579
|
-
reflex_compile_processes = None
|
|
580
|
-
executor_type = ExecutorType.PROCESS
|
|
581
|
-
elif reflex_compile_threads is not None:
|
|
582
|
-
if reflex_compile_threads == 0:
|
|
583
|
-
console.warn(
|
|
584
|
-
"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."
|
|
585
|
-
)
|
|
586
|
-
reflex_compile_threads = None
|
|
587
|
-
elif reflex_compile_threads < 0:
|
|
588
|
-
console.warn(
|
|
589
|
-
"Number of threads must be greater than 0. Defaulting to None."
|
|
590
|
-
)
|
|
591
|
-
reflex_compile_threads = None
|
|
592
|
-
executor_type = ExecutorType.THREAD
|
|
593
|
-
else:
|
|
594
|
-
executor_type = ExecutorType.MAIN_THREAD
|
|
595
|
-
|
|
596
|
-
match executor_type:
|
|
597
|
-
case ExecutorType.PROCESS:
|
|
598
|
-
executor = concurrent.futures.ProcessPoolExecutor(
|
|
599
|
-
max_workers=reflex_compile_processes,
|
|
600
|
-
mp_context=multiprocessing.get_context("fork"),
|
|
601
|
-
)
|
|
602
|
-
case ExecutorType.THREAD:
|
|
603
|
-
executor = concurrent.futures.ThreadPoolExecutor(
|
|
604
|
-
max_workers=reflex_compile_threads
|
|
605
|
-
)
|
|
606
|
-
case ExecutorType.MAIN_THREAD:
|
|
607
|
-
FUTURE_RESULT_TYPE = TypeVar("FUTURE_RESULT_TYPE")
|
|
608
|
-
|
|
609
|
-
class MainThreadExecutor:
|
|
610
|
-
def __enter__(self):
|
|
611
|
-
return self
|
|
612
|
-
|
|
613
|
-
def __exit__(self, *args):
|
|
614
|
-
pass
|
|
615
|
-
|
|
616
|
-
def submit(
|
|
617
|
-
self, fn: Callable[..., FUTURE_RESULT_TYPE], *args, **kwargs
|
|
618
|
-
) -> concurrent.futures.Future[FUTURE_RESULT_TYPE]:
|
|
619
|
-
future_job = concurrent.futures.Future()
|
|
620
|
-
future_job.set_result(fn(*args, **kwargs))
|
|
621
|
-
return future_job
|
|
622
|
-
|
|
623
|
-
executor = MainThreadExecutor()
|
|
624
|
-
|
|
625
|
-
return executor
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
class EnvironmentVariables:
|
|
629
|
-
"""Environment variables class to instantiate environment variables."""
|
|
630
|
-
|
|
631
|
-
# Indicate the current command that was invoked in the reflex CLI.
|
|
632
|
-
REFLEX_COMPILE_CONTEXT: EnvVar[constants.CompileContext] = env_var(
|
|
633
|
-
constants.CompileContext.UNDEFINED, internal=True
|
|
634
|
-
)
|
|
635
|
-
|
|
636
|
-
# Whether to use npm over bun to install and run the frontend.
|
|
637
|
-
REFLEX_USE_NPM: EnvVar[bool] = env_var(False)
|
|
638
|
-
|
|
639
|
-
# The npm registry to use.
|
|
640
|
-
NPM_CONFIG_REGISTRY: EnvVar[str | None] = env_var(None)
|
|
641
|
-
|
|
642
|
-
# Whether to use Granian for the backend. By default, the backend uses Uvicorn if available.
|
|
643
|
-
REFLEX_USE_GRANIAN: EnvVar[bool] = env_var(False)
|
|
644
|
-
|
|
645
|
-
# Whether to use the system installed bun. If set to false, bun will be bundled with the app.
|
|
646
|
-
REFLEX_USE_SYSTEM_BUN: EnvVar[bool] = env_var(False)
|
|
647
|
-
|
|
648
|
-
# The working directory for the next.js commands.
|
|
649
|
-
REFLEX_WEB_WORKDIR: EnvVar[Path] = env_var(Path(constants.Dirs.WEB))
|
|
650
|
-
|
|
651
|
-
# The working directory for the states directory.
|
|
652
|
-
REFLEX_STATES_WORKDIR: EnvVar[Path] = env_var(Path(constants.Dirs.STATES))
|
|
653
|
-
|
|
654
|
-
# Path to the alembic config file
|
|
655
|
-
ALEMBIC_CONFIG: EnvVar[ExistingPath] = env_var(Path(constants.ALEMBIC_CONFIG))
|
|
656
|
-
|
|
657
|
-
# Disable SSL verification for HTTPX requests.
|
|
658
|
-
SSL_NO_VERIFY: EnvVar[bool] = env_var(False)
|
|
659
|
-
|
|
660
|
-
# The directory to store uploaded files.
|
|
661
|
-
REFLEX_UPLOADED_FILES_DIR: EnvVar[Path] = env_var(
|
|
662
|
-
Path(constants.Dirs.UPLOADED_FILES)
|
|
663
|
-
)
|
|
664
|
-
|
|
665
|
-
REFLEX_COMPILE_EXECUTOR: EnvVar[ExecutorType | None] = env_var(None)
|
|
666
|
-
|
|
667
|
-
# Whether to use separate processes to compile the frontend and how many. If not set, defaults to thread executor.
|
|
668
|
-
REFLEX_COMPILE_PROCESSES: EnvVar[int | None] = env_var(None)
|
|
669
|
-
|
|
670
|
-
# Whether to use separate threads to compile the frontend and how many. Defaults to `min(32, os.cpu_count() + 4)`.
|
|
671
|
-
REFLEX_COMPILE_THREADS: EnvVar[int | None] = env_var(None)
|
|
672
|
-
|
|
673
|
-
# The directory to store reflex dependencies.
|
|
674
|
-
REFLEX_DIR: EnvVar[Path] = env_var(constants.Reflex.DIR)
|
|
675
|
-
|
|
676
|
-
# Whether to print the SQL queries if the log level is INFO or lower.
|
|
677
|
-
SQLALCHEMY_ECHO: EnvVar[bool] = env_var(False)
|
|
678
|
-
|
|
679
|
-
# Whether to check db connections before using them.
|
|
680
|
-
SQLALCHEMY_POOL_PRE_PING: EnvVar[bool] = env_var(True)
|
|
681
|
-
|
|
682
|
-
# Whether to ignore the redis config error. Some redis servers only allow out-of-band configuration.
|
|
683
|
-
REFLEX_IGNORE_REDIS_CONFIG_ERROR: EnvVar[bool] = env_var(False)
|
|
684
|
-
|
|
685
|
-
# Whether to skip purging the web directory in dev mode.
|
|
686
|
-
REFLEX_PERSIST_WEB_DIR: EnvVar[bool] = env_var(False)
|
|
687
|
-
|
|
688
|
-
# The reflex.build frontend host.
|
|
689
|
-
REFLEX_BUILD_FRONTEND: EnvVar[str] = env_var(
|
|
690
|
-
constants.Templates.REFLEX_BUILD_FRONTEND
|
|
691
|
-
)
|
|
692
|
-
|
|
693
|
-
# The reflex.build backend host.
|
|
694
|
-
REFLEX_BUILD_BACKEND: EnvVar[str] = env_var(
|
|
695
|
-
constants.Templates.REFLEX_BUILD_BACKEND
|
|
696
|
-
)
|
|
697
|
-
|
|
698
|
-
# This env var stores the execution mode of the app
|
|
699
|
-
REFLEX_ENV_MODE: EnvVar[constants.Env] = env_var(constants.Env.DEV)
|
|
700
|
-
|
|
701
|
-
# Whether to run the backend only. Exclusive with REFLEX_FRONTEND_ONLY.
|
|
702
|
-
REFLEX_BACKEND_ONLY: EnvVar[bool] = env_var(False)
|
|
703
|
-
|
|
704
|
-
# Whether to run the frontend only. Exclusive with REFLEX_BACKEND_ONLY.
|
|
705
|
-
REFLEX_FRONTEND_ONLY: EnvVar[bool] = env_var(False)
|
|
706
|
-
|
|
707
|
-
# The port to run the frontend on.
|
|
708
|
-
REFLEX_FRONTEND_PORT: EnvVar[int | None] = env_var(None)
|
|
709
|
-
|
|
710
|
-
# The port to run the backend on.
|
|
711
|
-
REFLEX_BACKEND_PORT: EnvVar[int | None] = env_var(None)
|
|
712
|
-
|
|
713
|
-
# If this env var is set to "yes", App.compile will be a no-op
|
|
714
|
-
REFLEX_SKIP_COMPILE: EnvVar[bool] = env_var(False, internal=True)
|
|
715
|
-
|
|
716
|
-
# Whether to run app harness tests in headless mode.
|
|
717
|
-
APP_HARNESS_HEADLESS: EnvVar[bool] = env_var(False)
|
|
718
|
-
|
|
719
|
-
# Which app harness driver to use.
|
|
720
|
-
APP_HARNESS_DRIVER: EnvVar[str] = env_var("Chrome")
|
|
721
|
-
|
|
722
|
-
# Arguments to pass to the app harness driver.
|
|
723
|
-
APP_HARNESS_DRIVER_ARGS: EnvVar[str] = env_var("")
|
|
724
|
-
|
|
725
|
-
# Whether to check for outdated package versions.
|
|
726
|
-
REFLEX_CHECK_LATEST_VERSION: EnvVar[bool] = env_var(True)
|
|
727
|
-
|
|
728
|
-
# In which performance mode to run the app.
|
|
729
|
-
REFLEX_PERF_MODE: EnvVar[PerformanceMode] = env_var(PerformanceMode.WARN)
|
|
730
|
-
|
|
731
|
-
# The maximum size of the reflex state in kilobytes.
|
|
732
|
-
REFLEX_STATE_SIZE_LIMIT: EnvVar[int] = env_var(1000)
|
|
733
|
-
|
|
734
|
-
# Whether to use the turbopack bundler.
|
|
735
|
-
REFLEX_USE_TURBOPACK: EnvVar[bool] = env_var(False)
|
|
736
|
-
|
|
737
|
-
# Additional paths to include in the hot reload. Separated by a colon.
|
|
738
|
-
REFLEX_HOT_RELOAD_INCLUDE_PATHS: EnvVar[list[Path]] = env_var([])
|
|
739
|
-
|
|
740
|
-
# Paths to exclude from the hot reload. Takes precedence over include paths. Separated by a colon.
|
|
741
|
-
REFLEX_HOT_RELOAD_EXCLUDE_PATHS: EnvVar[list[Path]] = env_var([])
|
|
742
|
-
|
|
743
|
-
# Enables different behavior for when the backend would do a cold start if it was inactive.
|
|
744
|
-
REFLEX_DOES_BACKEND_COLD_START: EnvVar[bool] = env_var(False)
|
|
745
|
-
|
|
746
|
-
# The timeout for the backend to do a cold start in seconds.
|
|
747
|
-
REFLEX_BACKEND_COLD_START_TIMEOUT: EnvVar[int] = env_var(10)
|
|
748
|
-
|
|
749
|
-
# Used by flexgen to enumerate the pages.
|
|
750
|
-
REFLEX_ADD_ALL_ROUTES_ENDPOINT: EnvVar[bool] = env_var(False)
|
|
751
|
-
|
|
752
|
-
# The address to bind the HTTP client to. You can set this to "::" to enable IPv6.
|
|
753
|
-
REFLEX_HTTP_CLIENT_BIND_ADDRESS: EnvVar[str | None] = env_var(None)
|
|
754
|
-
|
|
755
|
-
# Maximum size of the message in the websocket server in bytes.
|
|
756
|
-
REFLEX_SOCKET_MAX_HTTP_BUFFER_SIZE: EnvVar[int] = env_var(
|
|
757
|
-
constants.POLLING_MAX_HTTP_BUFFER_SIZE
|
|
758
|
-
)
|
|
759
|
-
|
|
760
|
-
# The interval to send a ping to the websocket server in seconds.
|
|
761
|
-
REFLEX_SOCKET_INTERVAL: EnvVar[int] = env_var(constants.Ping.INTERVAL)
|
|
762
|
-
|
|
763
|
-
# The timeout to wait for a pong from the websocket server in seconds.
|
|
764
|
-
REFLEX_SOCKET_TIMEOUT: EnvVar[int] = env_var(constants.Ping.TIMEOUT)
|
|
765
|
-
|
|
766
|
-
# Whether to run Granian in a spawn process. This enables Reflex to pick up on environment variable changes between hot reloads.
|
|
767
|
-
REFLEX_STRICT_HOT_RELOAD: EnvVar[bool] = env_var(False)
|
|
768
|
-
|
|
769
|
-
# The path to the reflex log file. If not set, the log file will be stored in the reflex user directory.
|
|
770
|
-
REFLEX_LOG_FILE: EnvVar[Path | None] = env_var(None)
|
|
771
|
-
|
|
772
|
-
# Enable full logging of debug messages to reflex user directory.
|
|
773
|
-
REFLEX_ENABLE_FULL_LOGGING: EnvVar[bool] = env_var(False)
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
environment = EnvironmentVariables()
|
|
777
|
-
|
|
778
|
-
|
|
779
185
|
# These vars are not logged because they may contain sensitive information.
|
|
780
186
|
_sensitive_env_vars = {"DB_URL", "ASYNC_DB_URL", "REDIS_URL"}
|
|
781
187
|
|
|
@@ -1025,11 +431,11 @@ If you are not using tailwind, set `tailwind` to `None` in rxconfig.py.""",
|
|
|
1025
431
|
for key, field in self.__fields__.items():
|
|
1026
432
|
# The env var name is the key in uppercase.
|
|
1027
433
|
for prefix in self._prefixes:
|
|
1028
|
-
if
|
|
434
|
+
if environment_variable := os.environ.get(f"{prefix}{key.upper()}"):
|
|
1029
435
|
break
|
|
1030
436
|
else:
|
|
1031
437
|
# Default to non-prefixed env var if other are not found.
|
|
1032
|
-
if
|
|
438
|
+
if environment_variable := os.environ.get(key.upper()):
|
|
1033
439
|
console.deprecate(
|
|
1034
440
|
f"Usage of deprecated {key.upper()} env var detected.",
|
|
1035
441
|
reason=f"Prefer `{self._prefixes[0]}` prefix when setting env vars.",
|
|
@@ -1038,21 +444,23 @@ If you are not using tailwind, set `tailwind` to `None` in rxconfig.py.""",
|
|
|
1038
444
|
)
|
|
1039
445
|
|
|
1040
446
|
# If the env var is set, override the config value.
|
|
1041
|
-
if
|
|
447
|
+
if environment_variable and environment_variable.strip():
|
|
1042
448
|
# Interpret the value.
|
|
1043
449
|
value = interpret_env_var_value(
|
|
1044
|
-
|
|
450
|
+
environment_variable,
|
|
451
|
+
true_type_for_pydantic_field(field),
|
|
452
|
+
field.name,
|
|
1045
453
|
)
|
|
1046
454
|
|
|
1047
455
|
# Set the value.
|
|
1048
456
|
updated_values[key] = value
|
|
1049
457
|
|
|
1050
458
|
if key.upper() in _sensitive_env_vars:
|
|
1051
|
-
|
|
459
|
+
environment_variable = "***"
|
|
1052
460
|
|
|
1053
461
|
if value != getattr(self, key):
|
|
1054
462
|
console.debug(
|
|
1055
|
-
f"Overriding config value {key} with env var {key.upper()}={
|
|
463
|
+
f"Overriding config value {key} with env var {key.upper()}={environment_variable}",
|
|
1056
464
|
dedupe=True,
|
|
1057
465
|
)
|
|
1058
466
|
return updated_values
|
reflex/constants/base.py
CHANGED
|
@@ -147,7 +147,7 @@ class Templates(SimpleNamespace):
|
|
|
147
147
|
Returns:
|
|
148
148
|
The URL to redirect to reflex.build.
|
|
149
149
|
"""
|
|
150
|
-
from reflex.
|
|
150
|
+
from reflex.environment import environment
|
|
151
151
|
|
|
152
152
|
return (
|
|
153
153
|
environment.REFLEX_BUILD_FRONTEND.get()
|
|
@@ -162,7 +162,7 @@ class Templates(SimpleNamespace):
|
|
|
162
162
|
Returns:
|
|
163
163
|
The URL to poll waiting for the user to select a generation.
|
|
164
164
|
"""
|
|
165
|
-
from reflex.
|
|
165
|
+
from reflex.environment import environment
|
|
166
166
|
|
|
167
167
|
return environment.REFLEX_BUILD_BACKEND.get() + "/api/init/{reflex_init_token}"
|
|
168
168
|
|
|
@@ -174,7 +174,7 @@ class Templates(SimpleNamespace):
|
|
|
174
174
|
Returns:
|
|
175
175
|
The URL to fetch the generation's reflex code.
|
|
176
176
|
"""
|
|
177
|
-
from reflex.
|
|
177
|
+
from reflex.environment import environment
|
|
178
178
|
|
|
179
179
|
return (
|
|
180
180
|
environment.REFLEX_BUILD_BACKEND.get()
|