orionis 0.245.0__py3-none-any.whl → 0.247.0__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.
- orionis/framework.py +1 -1
- orionis/luminate/config/app/__init__.py +10 -0
- orionis/luminate/config/app/entities/app.py +205 -0
- orionis/luminate/config/app/enums/ciphers.py +34 -0
- orionis/luminate/config/app/enums/environments.py +15 -0
- orionis/luminate/config/auth/__init__.py +7 -0
- orionis/luminate/config/auth/entities/auth.py +11 -0
- orionis/luminate/config/cache/__init__.py +9 -0
- orionis/luminate/config/cache/entities/cache.py +58 -0
- orionis/luminate/config/cache/entities/file.py +29 -0
- orionis/luminate/config/cache/entities/stores.py +35 -0
- orionis/luminate/config/cache/enums/drivers.py +12 -0
- orionis/luminate/config/contracts/config.py +27 -0
- orionis/luminate/config/entities/testing.py +215 -0
- orionis/luminate/config/exceptions/integrity_exception.py +30 -0
- orionis/luminate/console/dumper/dump_die.py +418 -0
- orionis/luminate/contracts/facades/commands/scheduler_facade.py +1 -1
- orionis/luminate/facades/files/path_facade.py +1 -1
- orionis/luminate/patterns/__init__.py +4 -0
- orionis/luminate/patterns/singleton/__init__.py +10 -0
- orionis/luminate/patterns/singleton/meta_class.py +56 -0
- orionis/luminate/providers/commands/reactor_commands_service_provider.py +3 -3
- orionis/luminate/providers/commands/scheduler_provider.py +1 -1
- orionis/luminate/providers/config/config_service_provider.py +1 -1
- orionis/luminate/providers/environment/environment__service_provider.py +2 -2
- orionis/luminate/providers/files/paths_provider.py +1 -1
- orionis/luminate/providers/log/log_service_provider.py +2 -2
- orionis/luminate/services/environment/__init__.py +10 -0
- orionis/luminate/services/environment/contracts/__init__.py +5 -0
- orionis/luminate/services/environment/contracts/env.py +93 -0
- orionis/luminate/services/environment/dot_env.py +293 -0
- orionis/luminate/services/environment/env.py +77 -0
- orionis/luminate/services/paths/__init__.py +9 -0
- orionis/luminate/services/paths/contracts/__init__.py +0 -0
- orionis/luminate/services/paths/contracts/resolver.py +67 -0
- orionis/luminate/services/paths/resolver.py +83 -0
- orionis/luminate/services/workers/__init__.py +10 -0
- orionis/luminate/services/workers/maximum_workers.py +36 -0
- orionis/luminate/services_/__init__.py +0 -0
- orionis/luminate/services_/commands/__init__.py +0 -0
- orionis/luminate/services_/config/__init__.py +0 -0
- orionis/luminate/services_/log/__init__.py +0 -0
- orionis/luminate/support/introspection/abstracts/entities/__init__.py +0 -0
- orionis/luminate/support/introspection/abstracts/entities/abstract_class_attributes.py +11 -0
- orionis/luminate/support/introspection/abstracts/reflect_abstract.py +154 -16
- orionis/luminate/support/introspection/instances/reflection_instance.py +2 -2
- orionis/luminate/test/__init__.py +11 -1
- orionis/luminate/test/cases/test_async.py +1 -10
- orionis/luminate/test/cases/test_case.py +8 -3
- orionis/luminate/test/cases/test_sync.py +1 -0
- orionis/luminate/test/core/contracts/test_suite.py +19 -31
- orionis/luminate/test/core/contracts/test_unit.py +103 -59
- orionis/luminate/test/core/test_suite.py +50 -42
- orionis/luminate/test/core/test_unit.py +756 -196
- orionis/luminate/test/entities/test_result.py +19 -18
- orionis/luminate/test/enums/test_mode.py +16 -0
- orionis/luminate/test/exceptions/test_config_exception.py +28 -0
- orionis/luminate/test/exceptions/test_exception.py +41 -34
- orionis/luminate/test/output/contracts/test_std_out.py +22 -11
- orionis/luminate/test/output/test_std_out.py +79 -48
- {orionis-0.245.0.dist-info → orionis-0.247.0.dist-info}/METADATA +4 -1
- {orionis-0.245.0.dist-info → orionis-0.247.0.dist-info}/RECORD +98 -61
- tests/config/__init__.py +0 -0
- tests/config/test_app.py +122 -0
- tests/config/test_auth.py +21 -0
- tests/config/test_cache.py +20 -0
- tests/patterns/__init__.py +0 -0
- tests/patterns/singleton/__init__.py +0 -0
- tests/patterns/singleton/test_singleton.py +18 -0
- tests/services/__init__.py +0 -0
- tests/services/environment/__init__.py +0 -0
- tests/services/environment/test_env.py +33 -0
- tests/support/inspection/fakes/fake_reflect_abstract.py +61 -5
- tests/support/inspection/test_reflect_abstract.py +62 -1
- tests/support/inspection/test_reflect_instance.py +0 -1
- orionis/luminate/config/app.py +0 -47
- orionis/luminate/config/auth.py +0 -15
- orionis/luminate/config/cache.py +0 -51
- orionis/luminate/support/environment/contracts/env.py +0 -68
- orionis/luminate/support/environment/env.py +0 -138
- orionis/luminate/support/environment/functions.py +0 -49
- orionis/luminate/support/environment/helper.py +0 -26
- orionis/luminate/support/patterns/singleton.py +0 -44
- tests/support/environment/test_env.py +0 -91
- tests/support/patterns/test_singleton.py +0 -18
- /orionis/luminate/{services/commands → config/app/entities}/__init__.py +0 -0
- /orionis/luminate/{services/config → config/app/enums}/__init__.py +0 -0
- /orionis/luminate/{services/log → config/auth/entities}/__init__.py +0 -0
- /orionis/luminate/{support/environment → config/cache/entities}/__init__.py +0 -0
- /orionis/luminate/{support/environment/contracts → config/cache/enums}/__init__.py +0 -0
- /orionis/luminate/{support/patterns → config/contracts}/__init__.py +0 -0
- /orionis/luminate/config/{cors.py → entities/cors.py} +0 -0
- /orionis/luminate/config/{database.py → entities/database.py} +0 -0
- /orionis/luminate/config/{filesystems.py → entities/filesystems.py} +0 -0
- /orionis/luminate/config/{logging.py → entities/logging.py} +0 -0
- /orionis/luminate/config/{mail.py → entities/mail.py} +0 -0
- /orionis/luminate/config/{queue.py → entities/queue.py} +0 -0
- /orionis/luminate/config/{session.py → entities/session.py} +0 -0
- {tests/support/environment → orionis/luminate/config/exceptions}/__init__.py +0 -0
- {tests/support/patterns → orionis/luminate/console/dumper}/__init__.py +0 -0
- /orionis/luminate/{services → services_}/commands/reactor_commands_service.py +0 -0
- /orionis/luminate/{services → services_}/commands/scheduler_service.py +0 -0
- /orionis/luminate/{services → services_}/config/config_service.py +0 -0
- /orionis/luminate/{services → services_}/log/log_service.py +0 -0
- {orionis-0.245.0.dist-info → orionis-0.247.0.dist-info}/LICENCE +0 -0
- {orionis-0.245.0.dist-info → orionis-0.247.0.dist-info}/WHEEL +0 -0
- {orionis-0.245.0.dist-info → orionis-0.247.0.dist-info}/entry_points.txt +0 -0
- {orionis-0.245.0.dist-info → orionis-0.247.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,10 @@
|
|
1
|
+
from orionis.luminate.patterns.singleton.meta_class import Singleton
|
2
|
+
|
3
|
+
__all__ = [
|
4
|
+
"Singleton",
|
5
|
+
]
|
6
|
+
__author__ = "Raúl Mauricio Uñate Castro"
|
7
|
+
__description__ = (
|
8
|
+
"This module provides a singleton class to manage environment variables. "
|
9
|
+
"It allows setting, getting, and deleting environment variables."
|
10
|
+
)
|
@@ -0,0 +1,56 @@
|
|
1
|
+
import threading
|
2
|
+
import asyncio
|
3
|
+
from typing import Dict, Type, Any, TypeVar
|
4
|
+
|
5
|
+
T = TypeVar('T')
|
6
|
+
|
7
|
+
class Singleton(type):
|
8
|
+
"""
|
9
|
+
Thread-safe + Async-safe singleton metaclass.
|
10
|
+
Works for both synchronous and asynchronous contexts.
|
11
|
+
"""
|
12
|
+
|
13
|
+
_instances: Dict[Type[T], T] = {}
|
14
|
+
_lock = threading.Lock()
|
15
|
+
_async_lock = asyncio.Lock()
|
16
|
+
|
17
|
+
def __call__(cls: Type[T], *args: Any, **kwargs: Any) -> T:
|
18
|
+
"""
|
19
|
+
Creates and returns a singleton instance of the class.
|
20
|
+
|
21
|
+
If an instance of the class does not already exist, this method acquires a lock to ensure thread safety,
|
22
|
+
creates a new instance using the provided arguments, and stores it in the class-level _instances dictionary.
|
23
|
+
Subsequent calls return the existing instance.
|
24
|
+
|
25
|
+
Args:
|
26
|
+
*args: Positional arguments to pass to the class constructor.
|
27
|
+
**kwargs: Keyword arguments to pass to the class constructor.
|
28
|
+
|
29
|
+
Returns:
|
30
|
+
T: The singleton instance of the class.
|
31
|
+
"""
|
32
|
+
if cls not in cls._instances:
|
33
|
+
with cls._lock:
|
34
|
+
if cls not in cls._instances:
|
35
|
+
cls._instances[cls] = super().__call__(*args, **kwargs)
|
36
|
+
return cls._instances[cls]
|
37
|
+
|
38
|
+
async def __acall__(cls: Type[T], *args: Any, **kwargs: Any) -> T:
|
39
|
+
"""
|
40
|
+
Asynchronously creates or retrieves a singleton instance of the class.
|
41
|
+
|
42
|
+
If an instance of the class does not exist, acquires an asynchronous lock to ensure thread safety,
|
43
|
+
creates the instance, and stores it. Subsequent calls return the existing instance.
|
44
|
+
|
45
|
+
Args:
|
46
|
+
*args: Positional arguments to pass to the class constructor.
|
47
|
+
**kwargs: Keyword arguments to pass to the class constructor.
|
48
|
+
|
49
|
+
Returns:
|
50
|
+
T: The singleton instance of the class.
|
51
|
+
"""
|
52
|
+
if cls not in cls._instances:
|
53
|
+
async with cls._async_lock:
|
54
|
+
if cls not in cls._instances:
|
55
|
+
cls._instances[cls] = super().__call__(*args, **kwargs)
|
56
|
+
return cls._instances[cls]
|
@@ -2,9 +2,9 @@ from orionis.luminate.contracts.services.commands.reactor_commands_service impor
|
|
2
2
|
from orionis.luminate.contracts.services.config.config_service import IConfigService
|
3
3
|
from orionis.luminate.contracts.services.log.log_service import ILogguerService
|
4
4
|
from orionis.luminate.providers.service_provider import ServiceProvider
|
5
|
-
from orionis.luminate.
|
6
|
-
from orionis.luminate.
|
7
|
-
from orionis.luminate.
|
5
|
+
from orionis.luminate.services_.commands.reactor_commands_service import ReactorCommandsService
|
6
|
+
from orionis.luminate.services_.config.config_service import ConfigService
|
7
|
+
from orionis.luminate.services_.log.log_service import LogguerService
|
8
8
|
|
9
9
|
class ReactorCommandsServiceProvider(ServiceProvider):
|
10
10
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
from orionis.luminate.contracts.services.commands.schedule_service import IScheduleService
|
2
2
|
from orionis.luminate.providers.service_provider import ServiceProvider
|
3
|
-
from orionis.luminate.
|
3
|
+
from orionis.luminate.services_.commands.scheduler_service import ScheduleService
|
4
4
|
|
5
5
|
class ScheduleServiceProvider(ServiceProvider):
|
6
6
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
from orionis.luminate.contracts.services.config.config_service import IConfigService
|
2
2
|
from orionis.luminate.providers.service_provider import ServiceProvider
|
3
|
-
from orionis.luminate.
|
3
|
+
from orionis.luminate.services_.config.config_service import ConfigService
|
4
4
|
|
5
5
|
class ConfigServiceProvider(ServiceProvider):
|
6
6
|
|
@@ -1,7 +1,7 @@
|
|
1
1
|
from orionis.luminate.contracts.services.environment.environment_service import IEnvironmentService
|
2
2
|
from orionis.luminate.providers.service_provider import ServiceProvider
|
3
|
-
from orionis.luminate.
|
4
|
-
from orionis.luminate.
|
3
|
+
from orionis.luminate.services_.environment.environment_service import EnvironmentService
|
4
|
+
from orionis.luminate.services_.files.path_resolver_service import PathResolverService
|
5
5
|
|
6
6
|
class EnvironmentServiceProvider(ServiceProvider):
|
7
7
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
from orionis.luminate.contracts.services.files.path_resolver_service import IPathResolverService
|
2
2
|
from orionis.luminate.providers.service_provider import ServiceProvider
|
3
|
-
from orionis.luminate.
|
3
|
+
from orionis.luminate.services_.files.path_resolver_service import PathResolverService
|
4
4
|
|
5
5
|
class PathResolverProvider(ServiceProvider):
|
6
6
|
|
@@ -1,8 +1,8 @@
|
|
1
1
|
from orionis.luminate.contracts.services.config.config_service import IConfigService
|
2
2
|
from orionis.luminate.contracts.services.log.log_service import ILogguerService
|
3
3
|
from orionis.luminate.providers.service_provider import ServiceProvider
|
4
|
-
from orionis.luminate.
|
5
|
-
from orionis.luminate.
|
4
|
+
from orionis.luminate.services_.config.config_service import ConfigService
|
5
|
+
from orionis.luminate.services_.log.log_service import LogguerService
|
6
6
|
|
7
7
|
class LogServiceProvider(ServiceProvider):
|
8
8
|
|
@@ -0,0 +1,10 @@
|
|
1
|
+
from orionis.luminate.services.environment.env import Env
|
2
|
+
|
3
|
+
__all__ = [
|
4
|
+
"Env",
|
5
|
+
]
|
6
|
+
__author__ = "Raúl Mauricio Uñate Castro"
|
7
|
+
__description__ = (
|
8
|
+
"This module provides a singleton class to manage environment variables. "
|
9
|
+
"It allows setting, getting, and deleting environment variables."
|
10
|
+
)
|
@@ -0,0 +1,93 @@
|
|
1
|
+
from typing import Any, Dict, Optional
|
2
|
+
from abc import ABC, abstractmethod
|
3
|
+
|
4
|
+
class IEnv(ABC):
|
5
|
+
"""Interface contract for environment management operations."""
|
6
|
+
|
7
|
+
@staticmethod
|
8
|
+
@abstractmethod
|
9
|
+
def get(key: str, default: Optional[Any] = None) -> Any:
|
10
|
+
"""
|
11
|
+
Retrieves an environment variable's value.
|
12
|
+
|
13
|
+
Args:
|
14
|
+
key: Environment variable name
|
15
|
+
default: Default value if key doesn't exist
|
16
|
+
|
17
|
+
Returns:
|
18
|
+
The parsed value or default if not found
|
19
|
+
"""
|
20
|
+
pass
|
21
|
+
|
22
|
+
@staticmethod
|
23
|
+
@abstractmethod
|
24
|
+
def set(key: str, value: str) -> bool:
|
25
|
+
"""
|
26
|
+
Sets an environment variable.
|
27
|
+
|
28
|
+
Args:
|
29
|
+
key: Environment variable name
|
30
|
+
value: Value to set
|
31
|
+
|
32
|
+
Returns:
|
33
|
+
True if successful, False otherwise
|
34
|
+
"""
|
35
|
+
pass
|
36
|
+
|
37
|
+
@staticmethod
|
38
|
+
@abstractmethod
|
39
|
+
def unset(key: str) -> bool:
|
40
|
+
"""
|
41
|
+
Removes an environment variable.
|
42
|
+
|
43
|
+
Args:
|
44
|
+
key: Environment variable name
|
45
|
+
|
46
|
+
Returns:
|
47
|
+
True if successful, False otherwise
|
48
|
+
"""
|
49
|
+
pass
|
50
|
+
|
51
|
+
@staticmethod
|
52
|
+
@abstractmethod
|
53
|
+
def all() -> Dict[str, Any]:
|
54
|
+
"""
|
55
|
+
Retrieves all environment variables.
|
56
|
+
|
57
|
+
Returns:
|
58
|
+
Dictionary of all key-value pairs
|
59
|
+
"""
|
60
|
+
pass
|
61
|
+
|
62
|
+
@staticmethod
|
63
|
+
@abstractmethod
|
64
|
+
def destroy() -> bool:
|
65
|
+
"""
|
66
|
+
Clears the entire environment.
|
67
|
+
|
68
|
+
Returns:
|
69
|
+
True if successful, False otherwise
|
70
|
+
"""
|
71
|
+
pass
|
72
|
+
|
73
|
+
@staticmethod
|
74
|
+
@abstractmethod
|
75
|
+
def toJson() -> str:
|
76
|
+
"""
|
77
|
+
Serializes environment to JSON.
|
78
|
+
|
79
|
+
Returns:
|
80
|
+
JSON string representation
|
81
|
+
"""
|
82
|
+
pass
|
83
|
+
|
84
|
+
@staticmethod
|
85
|
+
@abstractmethod
|
86
|
+
def toBase64() -> str:
|
87
|
+
"""
|
88
|
+
Encodes environment to Base64.
|
89
|
+
|
90
|
+
Returns:
|
91
|
+
Base64 encoded string
|
92
|
+
"""
|
93
|
+
pass
|
@@ -0,0 +1,293 @@
|
|
1
|
+
import ast
|
2
|
+
import os
|
3
|
+
from pathlib import Path
|
4
|
+
from typing import Any, Optional, Union
|
5
|
+
from dotenv import dotenv_values, load_dotenv, set_key, unset_key
|
6
|
+
from orionis.luminate.patterns.singleton import Singleton
|
7
|
+
|
8
|
+
class DotEnv(metaclass=Singleton):
|
9
|
+
"""
|
10
|
+
DotEnv is a singleton class for managing environment variables using a `.env` file.
|
11
|
+
This class provides methods to load, get, set, unset, and list environment variables,
|
12
|
+
with automatic serialization and deserialization of common Python data types.
|
13
|
+
It ensures that changes to the `.env` file are reflected in the current process's
|
14
|
+
environment variables and vice versa.
|
15
|
+
"""
|
16
|
+
|
17
|
+
def __init__(self, path: str = None) -> None:
|
18
|
+
"""
|
19
|
+
Initializes the environment service by resolving the path to the `.env` file, ensuring its existence,
|
20
|
+
and loading environment variables from it.
|
21
|
+
Args:
|
22
|
+
path (str, optional): The path to the `.env` file. If not provided, defaults to a `.env` file
|
23
|
+
in the current working directory.
|
24
|
+
Raises:
|
25
|
+
OSError: If the `.env` file cannot be created when it does not exist.
|
26
|
+
"""
|
27
|
+
|
28
|
+
# Path to the `.env` file - If no path is provided, use the default path
|
29
|
+
if path:
|
30
|
+
self._resolved_path = Path(path).expanduser().resolve()
|
31
|
+
else:
|
32
|
+
self._resolved_path = Path(os.getcwd()) / ".env"
|
33
|
+
|
34
|
+
# Ensure that the `.env` file exists
|
35
|
+
if not self._resolved_path.exists():
|
36
|
+
self._resolved_path.touch()
|
37
|
+
|
38
|
+
# Load environment variables from the `.env` file
|
39
|
+
load_dotenv(self._resolved_path)
|
40
|
+
|
41
|
+
def destroy(self) -> bool:
|
42
|
+
"""
|
43
|
+
Deletes the `.env` file at the resolved path.
|
44
|
+
Returns:
|
45
|
+
bool: True if the `.env` file was successfully deleted, False if the file did not exist.
|
46
|
+
"""
|
47
|
+
|
48
|
+
# Deletes the `.env` file and returns True if it was successfully deleted.
|
49
|
+
if self._resolved_path.exists():
|
50
|
+
os.remove(self._resolved_path)
|
51
|
+
return True
|
52
|
+
return False
|
53
|
+
|
54
|
+
def get(self, key: str, default: Optional[Any] = None) -> Any:
|
55
|
+
"""
|
56
|
+
Retrieve the value of an environment variable.
|
57
|
+
This method attempts to fetch the value of the specified environment variable `key`
|
58
|
+
from a `.env` file. If the variable is not found in the `.env` file, it falls back
|
59
|
+
to the system environment variables. If the variable is still not found, the provided
|
60
|
+
`default` value is returned.
|
61
|
+
Args:
|
62
|
+
key (str): The name of the environment variable to retrieve.
|
63
|
+
default (Optional[Any], optional): The value to return if the environment variable is not found. Defaults to None.
|
64
|
+
Returns:
|
65
|
+
Any: The value of the environment variable, parsed if found; otherwise, the `default` value.
|
66
|
+
"""
|
67
|
+
|
68
|
+
# Gets the value of an environment variable from the `.env` file or from system environment variables.
|
69
|
+
value = dotenv_values(self._resolved_path).get(key)
|
70
|
+
if value is None:
|
71
|
+
value = os.getenv(key)
|
72
|
+
|
73
|
+
# If the value is not found, return the default value
|
74
|
+
return self.__parseValue(value) if value is not None else default
|
75
|
+
|
76
|
+
def set(self, key: str, value: Union[str, int, float, bool, list, dict]) -> bool:
|
77
|
+
"""
|
78
|
+
Sets the value of an environment variable in both the `.env` file and the current system environment.
|
79
|
+
Args:
|
80
|
+
key (str): The name of the environment variable to set.
|
81
|
+
value (Union[str, int, float, bool, list, dict]): The value to assign to the environment variable.
|
82
|
+
The value will be serialized before being written to the `.env` file.
|
83
|
+
Notes:
|
84
|
+
- The value is serialized for storage in the `.env` file.
|
85
|
+
- The environment variable is also set in the current process's environment, making it immediately available.
|
86
|
+
"""
|
87
|
+
|
88
|
+
# Serializes and sets the value of an environment variable in the `.env` file.
|
89
|
+
serialized_value = self.__serializeValue(value)
|
90
|
+
|
91
|
+
# Sets the value in the `.env` file
|
92
|
+
set_key(str(self._resolved_path), key, serialized_value)
|
93
|
+
|
94
|
+
# Also sets the value in the system environment variables
|
95
|
+
# so that it is available in the current environment.
|
96
|
+
# This is useful if you need to access the environment variable immediately
|
97
|
+
os.environ[key] = str(value)
|
98
|
+
|
99
|
+
# Return True to indicate that the operation was successful
|
100
|
+
return True
|
101
|
+
|
102
|
+
def unset(self, key: str) -> bool:
|
103
|
+
"""
|
104
|
+
Removes an environment variable from both the `.env` file and the current system environment.
|
105
|
+
Args:
|
106
|
+
key (str): The name of the environment variable to remove.
|
107
|
+
This method updates the `.env` file by removing the specified key and also ensures
|
108
|
+
that the variable is no longer present in the current process's environment variables.
|
109
|
+
"""
|
110
|
+
|
111
|
+
# Removes an environment variable from the `.env` file and from the system environment.
|
112
|
+
unset_key(str(self._resolved_path), key)
|
113
|
+
|
114
|
+
# Also removes the environment variable from the system
|
115
|
+
# so that it is not available in the current environment.
|
116
|
+
os.environ.pop(key, None)
|
117
|
+
|
118
|
+
# Return True to indicate that the operation was successful
|
119
|
+
return True
|
120
|
+
|
121
|
+
def all(self) -> dict:
|
122
|
+
"""
|
123
|
+
Returns all environment variables from the `.env` file as a dictionary.
|
124
|
+
|
125
|
+
Reads the environment variables from the resolved `.env` file path, parses each value
|
126
|
+
using the `__parseValue` method, and returns a dictionary mapping variable names to their
|
127
|
+
parsed values.
|
128
|
+
|
129
|
+
Returns:
|
130
|
+
dict: A dictionary containing all environment variables and their parsed values.
|
131
|
+
"""
|
132
|
+
|
133
|
+
# Returns all environment variables from the `.env` file as a dictionary,
|
134
|
+
# parsing the values using __parseValue.
|
135
|
+
raw_values = dotenv_values(self._resolved_path)
|
136
|
+
return {k: self.__parseValue(v) for k, v in raw_values.items()}
|
137
|
+
|
138
|
+
def toJson(self) -> str:
|
139
|
+
"""
|
140
|
+
Converts the environment variables from the `.env` file into a JSON string.
|
141
|
+
|
142
|
+
This method retrieves all environment variables, parses their values using the
|
143
|
+
`__parseValue` method, and returns a JSON string representation of the resulting dictionary.
|
144
|
+
|
145
|
+
Returns:
|
146
|
+
str: A JSON string representing all environment variables and their parsed values.
|
147
|
+
"""
|
148
|
+
|
149
|
+
# Converts the environment variables to a JSON string.
|
150
|
+
import json
|
151
|
+
return json.dumps(self.all(), indent=4)
|
152
|
+
|
153
|
+
def toBase64(self) -> str:
|
154
|
+
"""
|
155
|
+
Converts the environment variables from the `.env` file into a Base64 encoded string.
|
156
|
+
|
157
|
+
This method retrieves all environment variables, parses their values using the
|
158
|
+
`__parseValue` method, and returns a Base64 encoded string representation of the resulting dictionary.
|
159
|
+
|
160
|
+
Returns:
|
161
|
+
str: A Base64 encoded string representing all environment variables and their parsed values.
|
162
|
+
"""
|
163
|
+
|
164
|
+
# Converts the environment variables to a Base64 encoded string.
|
165
|
+
import base64
|
166
|
+
import json
|
167
|
+
return base64.b64encode(json.dumps(self.all()).encode()).decode()
|
168
|
+
|
169
|
+
def __parseValue(self, value: Any) -> Any:
|
170
|
+
"""
|
171
|
+
Parses a given value and attempts to convert it into an appropriate Python data type.
|
172
|
+
The function handles the following conversions:
|
173
|
+
- Returns None for None, empty strings, or string representations of null values ('none', 'null', 'nan').
|
174
|
+
- Returns the value unchanged if it is already a primitive type (bool, int, float).
|
175
|
+
- Converts string representations of booleans ('true', 'false') to their respective boolean values.
|
176
|
+
- Converts string representations of integers and floats to their respective numeric types.
|
177
|
+
- Attempts to evaluate the string as a Python literal (e.g., lists, dicts, tuples).
|
178
|
+
- Returns the original string if no conversion is possible.
|
179
|
+
Args:
|
180
|
+
value (Any): The value to parse.
|
181
|
+
Returns:
|
182
|
+
Any: The parsed value in its appropriate Python data type, or the original string if no conversion is possible.
|
183
|
+
"""
|
184
|
+
|
185
|
+
# Parses a string value into a Python data type.
|
186
|
+
if value is None:
|
187
|
+
return None
|
188
|
+
|
189
|
+
# If it is already a primitive type, return it
|
190
|
+
if isinstance(value, (bool, int, float)):
|
191
|
+
return value
|
192
|
+
|
193
|
+
value_str = str(value).strip()
|
194
|
+
|
195
|
+
# Special cases: empty or representations of None
|
196
|
+
if not value_str or value_str.lower() in {'none', 'null', 'nan'}:
|
197
|
+
return None
|
198
|
+
|
199
|
+
# Booleans
|
200
|
+
if value_str.lower() == 'true':
|
201
|
+
return True
|
202
|
+
if value_str.lower() == 'false':
|
203
|
+
return False
|
204
|
+
|
205
|
+
# Try to convert to int
|
206
|
+
try:
|
207
|
+
if value_str.isdigit() or (value_str.startswith('-') and value_str[1:].isdigit()):
|
208
|
+
return int(value_str)
|
209
|
+
except Exception:
|
210
|
+
pass
|
211
|
+
|
212
|
+
# Try to convert to float
|
213
|
+
try:
|
214
|
+
float_val = float(value_str)
|
215
|
+
# Avoid converting strings like '1e10' to float if it is not really a number
|
216
|
+
if '.' in value_str or 'e' in value_str.lower():
|
217
|
+
return float_val
|
218
|
+
except Exception:
|
219
|
+
pass
|
220
|
+
|
221
|
+
# Try to evaluate as Python literal (lists, dicts, etc.)
|
222
|
+
try:
|
223
|
+
return ast.literal_eval(value_str)
|
224
|
+
except Exception:
|
225
|
+
pass
|
226
|
+
|
227
|
+
# If all else fails, return the original string
|
228
|
+
return value_str
|
229
|
+
|
230
|
+
def __serializeValue(self, value: Any) -> str:
|
231
|
+
"""
|
232
|
+
Serializes a Python value into a string suitable for storing in a `.env` file.
|
233
|
+
Supported types:
|
234
|
+
- None: serialized as the string "None"
|
235
|
+
- str: returned as-is
|
236
|
+
- bool: converted to "true" or "false"
|
237
|
+
- int, float: converted to their string representation
|
238
|
+
- list, dict: converted to their string representation using repr()
|
239
|
+
Raises:
|
240
|
+
TypeError: If the value is an instance of a custom class or an unsupported type (e.g., set, tuple).
|
241
|
+
Args:
|
242
|
+
value (Any): The value to serialize.
|
243
|
+
Returns:
|
244
|
+
str: The serialized string representation of the value.
|
245
|
+
"""
|
246
|
+
|
247
|
+
# if it is None, return "None"
|
248
|
+
# This is useful to avoid problems when saving None in the .env file
|
249
|
+
if value is None:
|
250
|
+
return "None"
|
251
|
+
|
252
|
+
# If it is a string, return it as is
|
253
|
+
if isinstance(value, str):
|
254
|
+
return value
|
255
|
+
|
256
|
+
# If it is a boolean, convert it to string
|
257
|
+
if isinstance(value, bool):
|
258
|
+
return str(value).lower()
|
259
|
+
|
260
|
+
# If it is a number, convert it to string
|
261
|
+
if isinstance(value, int):
|
262
|
+
return str(value)
|
263
|
+
|
264
|
+
# If is a float, convert it to string
|
265
|
+
if isinstance(value, float):
|
266
|
+
value = str(value)
|
267
|
+
if 'e' in value or 'E' in value:
|
268
|
+
raise ValueError('scientific notation is not supported, use a string instead')
|
269
|
+
return value
|
270
|
+
|
271
|
+
# If it is a list or dictionary, convert them to string
|
272
|
+
if isinstance(value, (list, dict)):
|
273
|
+
return repr(value)
|
274
|
+
|
275
|
+
# If it is an object of a custom class, raise an error
|
276
|
+
# This is useful to avoid problems when saving class instances in the .env file
|
277
|
+
if hasattr(value, '__dict__'):
|
278
|
+
raise TypeError(f"Type {type(value).__name__} is not serializable for .env")
|
279
|
+
|
280
|
+
# If it is an unsupported data type, raise an error
|
281
|
+
# This is useful to avoid problems when saving unsupported data types in the .env file
|
282
|
+
# such as sets, tuples, etc.
|
283
|
+
if not isinstance(value, (list, dict, bool, int, float, str)):
|
284
|
+
raise TypeError(f"Type {type(value).__name__} is not serializable for .env")
|
285
|
+
|
286
|
+
# Serializes a Python data type into a string for storing in the `.env` file.
|
287
|
+
# Only allows simple serializable types and not class instances.
|
288
|
+
if isinstance(value, (list, dict, bool, int, float, str)):
|
289
|
+
# Prevent serializing instances of custom classes
|
290
|
+
if type(value).__module__ != "builtins" and not isinstance(value, str):
|
291
|
+
raise TypeError(f"Type {type(value).__name__} is not serializable for .env")
|
292
|
+
return repr(value) if not isinstance(value, str) else value
|
293
|
+
raise TypeError(f"Type {type(value).__name__} is not serializable for .env")
|
@@ -0,0 +1,77 @@
|
|
1
|
+
from orionis.luminate.services.environment.contracts.env import IEnv
|
2
|
+
from orionis.luminate.services.environment.dot_env import DotEnv
|
3
|
+
from typing import Any, Optional, Dict
|
4
|
+
|
5
|
+
def env(key: str, default: Any = None) -> Any:
|
6
|
+
"""
|
7
|
+
Helper function to retrieve the value of an environment variable by key.
|
8
|
+
"""
|
9
|
+
return DotEnv().get(key, default)
|
10
|
+
|
11
|
+
class Env(IEnv):
|
12
|
+
"""
|
13
|
+
Env is a utility class that provides static methods for managing environment variables
|
14
|
+
using the DotEnv class. It allows getting, setting, unsetting, listing, destroying,
|
15
|
+
and serializing environment variables.
|
16
|
+
"""
|
17
|
+
|
18
|
+
_dotenv_instance: Optional[DotEnv] = None
|
19
|
+
|
20
|
+
@classmethod
|
21
|
+
def _dotenv(cls) -> DotEnv:
|
22
|
+
if cls._dotenv_instance is None:
|
23
|
+
cls._dotenv_instance = DotEnv()
|
24
|
+
return cls._dotenv_instance
|
25
|
+
|
26
|
+
@staticmethod
|
27
|
+
def get(key: str, default: Any = None) -> Any:
|
28
|
+
"""
|
29
|
+
Retrieve the value of an environment variable by key.
|
30
|
+
"""
|
31
|
+
return Env._dotenv().get(key, default)
|
32
|
+
|
33
|
+
@staticmethod
|
34
|
+
def set(key: str, value: str) -> bool:
|
35
|
+
"""
|
36
|
+
Sets the value of an environment variable.
|
37
|
+
"""
|
38
|
+
return Env._dotenv().set(key, value)
|
39
|
+
|
40
|
+
@staticmethod
|
41
|
+
def unset(key: str) -> bool:
|
42
|
+
"""
|
43
|
+
Removes the specified environment variable from the environment.
|
44
|
+
"""
|
45
|
+
return Env._dotenv().unset(key)
|
46
|
+
|
47
|
+
@staticmethod
|
48
|
+
def all() -> Dict[str, Any]:
|
49
|
+
"""
|
50
|
+
Retrieve all environment variables from the DotEnv instance.
|
51
|
+
"""
|
52
|
+
return Env._dotenv().all()
|
53
|
+
|
54
|
+
@staticmethod
|
55
|
+
def destroy() -> bool:
|
56
|
+
"""
|
57
|
+
Destroys the current environment by resetting the DotEnv instance.
|
58
|
+
"""
|
59
|
+
if Env._dotenv_instance is not None:
|
60
|
+
result = Env._dotenv_instance.destroy()
|
61
|
+
Env._dotenv_instance = None
|
62
|
+
return result
|
63
|
+
return False
|
64
|
+
|
65
|
+
@staticmethod
|
66
|
+
def toJson() -> str:
|
67
|
+
"""
|
68
|
+
Serializes the current environment variables managed by the DotEnv instance to a JSON-formatted string.
|
69
|
+
"""
|
70
|
+
return Env._dotenv().toJson()
|
71
|
+
|
72
|
+
@staticmethod
|
73
|
+
def toBase64() -> str:
|
74
|
+
"""
|
75
|
+
Converts the current environment variables to a Base64-encoded string.
|
76
|
+
"""
|
77
|
+
return Env._dotenv().toBase64()
|
@@ -0,0 +1,9 @@
|
|
1
|
+
from orionis.luminate.services.paths.resolver import Resolver
|
2
|
+
|
3
|
+
__all__ = [
|
4
|
+
"Resolver",
|
5
|
+
]
|
6
|
+
__author__ = "Raúl Mauricio Uñate Castro"
|
7
|
+
__description__ = (
|
8
|
+
"This module provides a Resolver class that is used to resolve paths in the Orionis Framework application. "
|
9
|
+
)
|
File without changes
|