orionis 0.282.0__py3-none-any.whl → 0.284.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/application.py +2 -7
- orionis/foundation/config/testing/entities/testing.py +25 -0
- orionis/metadata/framework.py +1 -1
- orionis/services/asynchrony/{async_io.py → coroutines.py} +2 -1
- orionis/services/asynchrony/exceptions/__init__.py +0 -0
- orionis/services/asynchrony/exceptions/coroutine_exception.py +26 -0
- orionis/services/environment/dot_env.py +44 -14
- orionis/services/environment/env.py +60 -12
- orionis/services/environment/exceptions/__init__.py +0 -0
- orionis/services/environment/exceptions/value_exception.py +27 -0
- orionis/services/introspection/exceptions/__init__.py +0 -0
- orionis/services/introspection/exceptions/types.py +0 -0
- orionis/services/introspection/helpers/__init__.py +0 -0
- orionis/services/introspection/helpers/functions.py +285 -0
- orionis/services/introspection/reflection.py +216 -0
- orionis/services/parsers/exceptions/__init__.py +0 -0
- orionis/services/parsers/serializer.py +1 -1
- orionis/services/paths/exceptions/__init__.py +0 -0
- orionis/services/paths/exceptions/not_found_exceptions.py +28 -0
- orionis/services/paths/exceptions/path_value_exceptions.py +28 -0
- orionis/services/paths/resolver.py +6 -4
- orionis/services/standard/exceptions/__init__.py +0 -0
- orionis/services/standard/exceptions/path_value_exceptions.py +28 -0
- orionis/services/standard/std.py +4 -3
- orionis/test/entities/test_result.py +14 -1
- orionis/test/exceptions/test_persistence_error.py +34 -0
- orionis/test/exceptions/test_runtime_error.py +26 -0
- orionis/test/exceptions/test_value_error.py +26 -0
- orionis/test/logs/contracts/__init__.py +0 -0
- orionis/test/logs/contracts/history.py +54 -0
- orionis/test/logs/history.py +372 -0
- orionis/test/output/contracts/dumper.py +24 -8
- orionis/test/output/dumper.py +52 -21
- orionis/test/suites/contracts/test_suite.py +27 -13
- orionis/test/suites/contracts/test_unit.py +101 -61
- orionis/test/suites/test_suite.py +57 -25
- orionis/test/suites/test_unit.py +559 -290
- orionis/unittesting.py +13 -1
- {orionis-0.282.0.dist-info → orionis-0.284.0.dist-info}/METADATA +1 -1
- {orionis-0.282.0.dist-info → orionis-0.284.0.dist-info}/RECORD +47 -27
- tests/services/asynchrony/test_async_io.py +3 -2
- tests/services/environment/test_env.py +3 -3
- orionis/test/logs/log_test.py +0 -211
- /orionis/services/parsers/{exception.py → exceptions/exception_parser.py} +0 -0
- {orionis-0.282.0.dist-info → orionis-0.284.0.dist-info}/WHEEL +0 -0
- {orionis-0.282.0.dist-info → orionis-0.284.0.dist-info}/licenses/LICENCE +0 -0
- {orionis-0.282.0.dist-info → orionis-0.284.0.dist-info}/top_level.txt +0 -0
- {orionis-0.282.0.dist-info → orionis-0.284.0.dist-info}/zip-safe +0 -0
orionis/application.py
CHANGED
@@ -1,15 +1,10 @@
|
|
1
1
|
from orionis.foundation.config.startup import Configuration
|
2
|
+
from orionis.patterns.singleton.meta_class import Singleton
|
2
3
|
|
3
|
-
class Orionis:
|
4
|
+
class Orionis(metaclass=Singleton):
|
4
5
|
|
5
6
|
def __init__(
|
6
7
|
self,
|
7
8
|
config: Configuration = None
|
8
9
|
):
|
9
|
-
"""
|
10
|
-
Initializes the Orionis instance with optional configuration objects.
|
11
|
-
|
12
|
-
Args:
|
13
|
-
config (Configuration, optional): Custom application configuration.
|
14
|
-
"""
|
15
10
|
self.__config = config or Configuration()
|
@@ -136,6 +136,15 @@ class Testing:
|
|
136
136
|
}
|
137
137
|
)
|
138
138
|
|
139
|
+
persistent_driver: str = field(
|
140
|
+
default='sqlite',
|
141
|
+
metadata={
|
142
|
+
"description": "Specifies the driver to use for persisting test results. Supported values: 'sqlite', 'json'. Default is 'sqlite'.",
|
143
|
+
"required": False,
|
144
|
+
"default": 'sqlite'
|
145
|
+
}
|
146
|
+
)
|
147
|
+
|
139
148
|
def __post_init__(self):
|
140
149
|
"""
|
141
150
|
Post-initialization validation for the testing configuration entity.
|
@@ -202,6 +211,7 @@ class Testing:
|
|
202
211
|
raise OrionisIntegrityException(
|
203
212
|
f"Invalid type for 'folder_path': {type(self.folder_path).__name__}. It must be a string or a list of strings representing the folder path pattern."
|
204
213
|
)
|
214
|
+
|
205
215
|
if isinstance(self.folder_path, list):
|
206
216
|
for i, folder in enumerate(self.folder_path):
|
207
217
|
if not isinstance(folder, str):
|
@@ -230,6 +240,21 @@ class Testing:
|
|
230
240
|
f"Invalid type for tag at index {i} in 'tags': {type(tag).__name__}. Each tag must be a string."
|
231
241
|
)
|
232
242
|
|
243
|
+
if not isinstance(self.persistent, bool):
|
244
|
+
raise OrionisIntegrityException(
|
245
|
+
f"Invalid type for 'persistent': {type(self.persistent).__name__}. It must be a boolean (True or False)."
|
246
|
+
)
|
247
|
+
|
248
|
+
if not isinstance(self.persistent_driver, str):
|
249
|
+
raise OrionisIntegrityException(
|
250
|
+
f"Invalid type for 'persistent_driver': {type(self.persistent_driver).__name__}. It must be a string."
|
251
|
+
)
|
252
|
+
|
253
|
+
if self.persistent_driver not in ['sqlite', 'json']:
|
254
|
+
raise OrionisIntegrityException(
|
255
|
+
f"Invalid value for 'persistent_driver': {self.persistent_driver}. It must be one of: ['sqlite', 'json']."
|
256
|
+
)
|
257
|
+
|
233
258
|
def toDict(self) -> dict:
|
234
259
|
"""
|
235
260
|
Convert the object to a dictionary representation.
|
orionis/metadata/framework.py
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
import asyncio
|
2
2
|
from typing import Any, Coroutine, TypeVar, Union
|
3
|
+
from orionis.services.asynchrony.exceptions.coroutine_exception import OrionisCoroutineException
|
3
4
|
|
4
5
|
T = TypeVar("T")
|
5
6
|
|
@@ -18,7 +19,7 @@ def run_coroutine(coro: Coroutine[Any, Any, T]) -> Union[T, asyncio.Future]:
|
|
18
19
|
from inspect import iscoroutine
|
19
20
|
|
20
21
|
if not iscoroutine(coro):
|
21
|
-
raise
|
22
|
+
raise OrionisCoroutineException("Expected a coroutine object.")
|
22
23
|
|
23
24
|
try:
|
24
25
|
loop = asyncio.get_running_loop()
|
File without changes
|
@@ -0,0 +1,26 @@
|
|
1
|
+
class OrionisCoroutineException(Exception):
|
2
|
+
"""
|
3
|
+
Exception raised for errors related to coroutine operations in the Orionis framework.
|
4
|
+
This exception is intended to signal issues encountered during asynchronous
|
5
|
+
operations, providing a clear and descriptive error message to facilitate debugging.
|
6
|
+
msg (str): A detailed message describing the cause of the exception.
|
7
|
+
Example:
|
8
|
+
raise OrionisCoroutineException("Coroutine execution failed due to timeout.")
|
9
|
+
"""
|
10
|
+
|
11
|
+
def __init__(self, msg: str):
|
12
|
+
"""
|
13
|
+
Initialize the exception with a custom error message.
|
14
|
+
Args:
|
15
|
+
msg (str): The error message describing the exception.
|
16
|
+
"""
|
17
|
+
super().__init__(msg)
|
18
|
+
|
19
|
+
def __str__(self) -> str:
|
20
|
+
"""
|
21
|
+
Return a string representation of the exception, including the class name and the first argument.
|
22
|
+
|
23
|
+
Returns:
|
24
|
+
str: A formatted string with the exception class name and its first argument.
|
25
|
+
"""
|
26
|
+
return f"{self.__class__.__name__}: {self.args[0]}"
|
@@ -5,6 +5,7 @@ from pathlib import Path
|
|
5
5
|
from typing import Any, Optional, Union
|
6
6
|
from dotenv import dotenv_values, load_dotenv, set_key, unset_key
|
7
7
|
from orionis.patterns.singleton.meta_class import Singleton
|
8
|
+
from orionis.services.environment.exceptions.value_exception import OrionisEnvironmentValueException
|
8
9
|
|
9
10
|
class DotEnv(metaclass=Singleton):
|
10
11
|
"""
|
@@ -39,7 +40,7 @@ class DotEnv(metaclass=Singleton):
|
|
39
40
|
|
40
41
|
load_dotenv(self._resolved_path)
|
41
42
|
|
42
|
-
def get(self, key: str, default: Optional[Any] = None) -> Any:
|
43
|
+
def get(self, key: str, default: Optional[Any] = None, is_path:bool=False) -> Any:
|
43
44
|
"""
|
44
45
|
Retrieve the value of an environment variable by key.
|
45
46
|
|
@@ -54,6 +55,8 @@ class DotEnv(metaclass=Singleton):
|
|
54
55
|
key (str): The name of the environment variable to retrieve.
|
55
56
|
default (Optional[Any], optional): The value to return if the key is not found.
|
56
57
|
Defaults to None.
|
58
|
+
is_path (bool, optional): If True, the value is treated as a file path and backslashes are replaced with forward slashes.
|
59
|
+
This is useful for Windows paths. Defaults to False.
|
57
60
|
|
58
61
|
Returns:
|
59
62
|
Any: The parsed value of the environment variable, or the default if not found.
|
@@ -62,9 +65,9 @@ class DotEnv(metaclass=Singleton):
|
|
62
65
|
value = dotenv_values(self._resolved_path).get(key)
|
63
66
|
if value is None:
|
64
67
|
value = os.getenv(key)
|
65
|
-
return self.__parseValue(value) if value is not None else default
|
68
|
+
return self.__parseValue(value, is_path) if value is not None else default
|
66
69
|
|
67
|
-
def set(self, key: str, value: Union[str, int, float, bool, list, dict]) -> bool:
|
70
|
+
def set(self, key: str, value: Union[str, int, float, bool, list, dict], is_path:bool=False) -> bool:
|
68
71
|
"""
|
69
72
|
Sets an environment variable with the specified key and value.
|
70
73
|
|
@@ -73,13 +76,16 @@ class DotEnv(metaclass=Singleton):
|
|
73
76
|
Args:
|
74
77
|
key (str): The name of the environment variable to set.
|
75
78
|
value (Union[str, int, float, bool, list, dict]): The value to assign to the environment variable. Supported types include string, integer, float, boolean, list, and dictionary.
|
79
|
+
is_path (bool, optional): If True, the value is treated as a file path and backslashes are replaced with forward slashes.
|
80
|
+
This is useful for Windows paths. Defaults to False.
|
76
81
|
|
77
82
|
Returns:
|
78
83
|
bool: True if the environment variable was successfully set.
|
79
84
|
"""
|
85
|
+
|
80
86
|
with self._lock:
|
81
|
-
serialized_value = self.__serializeValue(value)
|
82
|
-
set_key(str(self._resolved_path), key,
|
87
|
+
serialized_value = self.__serializeValue(value, is_path)
|
88
|
+
set_key(str(self._resolved_path), key, serialized_value)
|
83
89
|
os.environ[key] = str(value)
|
84
90
|
return True
|
85
91
|
|
@@ -133,7 +139,7 @@ class DotEnv(metaclass=Singleton):
|
|
133
139
|
with self._lock:
|
134
140
|
return base64.b64encode(json.dumps(self.all()).encode()).decode()
|
135
141
|
|
136
|
-
def __parseValue(self, value: Any) -> Any:
|
142
|
+
def __parseValue(self, value: Any, is_path:bool=False) -> Any:
|
137
143
|
"""
|
138
144
|
Parses and converts the input value to an appropriate Python data type.
|
139
145
|
|
@@ -151,67 +157,91 @@ class DotEnv(metaclass=Singleton):
|
|
151
157
|
"""
|
152
158
|
if value is None:
|
153
159
|
return None
|
160
|
+
|
154
161
|
if isinstance(value, (bool, int, float)):
|
155
162
|
return value
|
163
|
+
|
156
164
|
value_str = str(value).strip()
|
157
165
|
if not value_str or value_str.lower() in {'none', 'null', 'nan'}:
|
158
166
|
return None
|
167
|
+
|
159
168
|
if value_str.lower() == 'true':
|
160
169
|
return True
|
170
|
+
|
161
171
|
if value_str.lower() == 'false':
|
162
172
|
return False
|
173
|
+
|
174
|
+
if is_path:
|
175
|
+
return value_str.replace("\\", "/")
|
176
|
+
|
163
177
|
try:
|
164
178
|
if value_str.isdigit() or (value_str.startswith('-') and value_str[1:].isdigit()):
|
165
179
|
return int(value_str)
|
166
180
|
except Exception:
|
167
181
|
pass
|
182
|
+
|
168
183
|
try:
|
169
184
|
float_val = float(value_str)
|
170
185
|
if '.' in value_str or 'e' in value_str.lower():
|
171
186
|
return float_val
|
172
187
|
except Exception:
|
173
188
|
pass
|
189
|
+
|
174
190
|
try:
|
175
191
|
return ast.literal_eval(value_str)
|
176
192
|
except Exception:
|
177
193
|
pass
|
194
|
+
|
178
195
|
return value_str
|
179
196
|
|
180
|
-
def __serializeValue(self, value: Any) -> str:
|
197
|
+
def __serializeValue(self, value: Any, is_path:bool=False) -> str:
|
181
198
|
"""
|
182
199
|
Serializes a given value to a string suitable for storage in a .env file.
|
183
200
|
|
184
201
|
Parameters:
|
185
202
|
value (Any): The value to serialize. Supported types are None, str, bool, int, float, list, and dict.
|
203
|
+
is_path (bool): If True, the value is treated as a file path and backslashes are replaced with forward slashes.
|
204
|
+
This is useful for Windows paths.
|
186
205
|
|
187
206
|
Returns:
|
188
207
|
str: The serialized string representation of the value.
|
189
208
|
|
190
209
|
Raises:
|
191
|
-
|
192
|
-
TypeError: If the value's type is not serializable for .env files.
|
210
|
+
OrionisEnvironmentValueException: If a float value is in scientific notation or If the value's type is not serializable for .env files.
|
193
211
|
"""
|
212
|
+
if is_path:
|
213
|
+
return str(value).replace("\\", "/")
|
214
|
+
|
194
215
|
if value is None:
|
195
216
|
return "None"
|
217
|
+
|
196
218
|
if isinstance(value, str):
|
197
219
|
return value
|
220
|
+
|
198
221
|
if isinstance(value, bool):
|
199
222
|
return str(value).lower()
|
223
|
+
|
200
224
|
if isinstance(value, int):
|
201
225
|
return str(value)
|
226
|
+
|
202
227
|
if isinstance(value, float):
|
203
228
|
value = str(value)
|
204
229
|
if 'e' in value or 'E' in value:
|
205
|
-
raise
|
230
|
+
raise OrionisEnvironmentValueException('scientific notation is not supported, use a string instead')
|
206
231
|
return value
|
232
|
+
|
207
233
|
if isinstance(value, (list, dict)):
|
208
234
|
return repr(value)
|
235
|
+
|
209
236
|
if hasattr(value, '__dict__'):
|
210
|
-
raise
|
237
|
+
raise OrionisEnvironmentValueException(f"Type {type(value).__name__} is not serializable for .env")
|
238
|
+
|
211
239
|
if not isinstance(value, (list, dict, bool, int, float, str)):
|
212
|
-
raise
|
240
|
+
raise OrionisEnvironmentValueException(f"Type {type(value).__name__} is not serializable for .env")
|
241
|
+
|
213
242
|
if isinstance(value, (list, dict, bool, int, float, str)):
|
214
243
|
if type(value).__module__ != "builtins" and not isinstance(value, str):
|
215
|
-
raise
|
244
|
+
raise OrionisEnvironmentValueException(f"Type {type(value).__name__} is not serializable for .env")
|
216
245
|
return repr(value) if not isinstance(value, str) else value
|
217
|
-
|
246
|
+
|
247
|
+
raise OrionisEnvironmentValueException(f"Type {type(value).__name__} is not serializable for .env")
|
@@ -2,11 +2,19 @@ from orionis.services.environment.contracts.env import IEnv
|
|
2
2
|
from orionis.services.environment.dot_env import DotEnv
|
3
3
|
from typing import Any, Optional, Dict
|
4
4
|
|
5
|
-
def env(key: str, default: Any = None) -> Any:
|
5
|
+
def env(key: str, default: Any = None, is_path: bool = False) -> Any:
|
6
6
|
"""
|
7
|
-
|
7
|
+
Retrieve the value of an environment variable by key.
|
8
|
+
|
9
|
+
Args:
|
10
|
+
key (str): The name of the environment variable to retrieve.
|
11
|
+
default (Any, optional): The value to return if the key is not found. Defaults to None.
|
12
|
+
is_path (bool, optional): If True, the value will be treated as a file path. Defaults to False.
|
13
|
+
|
14
|
+
Returns:
|
15
|
+
Any: The value of the environment variable if found, otherwise the default value.
|
8
16
|
"""
|
9
|
-
return DotEnv().get(key, default)
|
17
|
+
return DotEnv().get(key, default, is_path)
|
10
18
|
|
11
19
|
class Env(IEnv):
|
12
20
|
"""
|
@@ -19,48 +27,88 @@ class Env(IEnv):
|
|
19
27
|
|
20
28
|
@classmethod
|
21
29
|
def _dotenv(cls) -> DotEnv:
|
30
|
+
"""
|
31
|
+
Returns a singleton instance of the DotEnv class.
|
32
|
+
|
33
|
+
If the instance does not exist, it creates a new one and stores it in the class attribute.
|
34
|
+
Subsequent calls will return the same instance.
|
35
|
+
|
36
|
+
Returns:
|
37
|
+
DotEnv: The singleton instance of the DotEnv class.
|
38
|
+
"""
|
22
39
|
if cls._dotenv_instance is None:
|
23
40
|
cls._dotenv_instance = DotEnv()
|
24
41
|
return cls._dotenv_instance
|
25
42
|
|
26
43
|
@staticmethod
|
27
|
-
def get(key: str, default: Any = None) -> Any:
|
44
|
+
def get(key: str, default: Any = None, is_path: bool = False) -> Any:
|
28
45
|
"""
|
29
|
-
Retrieve the value of an environment variable
|
46
|
+
Retrieve the value of an environment variable.
|
47
|
+
|
48
|
+
Args:
|
49
|
+
key (str): The name of the environment variable to retrieve.
|
50
|
+
default (Any, optional): The value to return if the environment variable is not found. Defaults to None.
|
51
|
+
is_path (bool, optional): If True, treat the value as a filesystem path. Defaults to False.
|
52
|
+
|
53
|
+
Returns:
|
54
|
+
Any: The value of the environment variable if found, otherwise the default value.
|
30
55
|
"""
|
31
|
-
return Env._dotenv().get(key, default)
|
56
|
+
return Env._dotenv().get(key, default, is_path)
|
32
57
|
|
33
58
|
@staticmethod
|
34
|
-
def set(key: str, value: str) -> bool:
|
59
|
+
def set(key: str, value: str, is_path: bool = False) -> bool:
|
35
60
|
"""
|
36
|
-
Sets the
|
61
|
+
Sets an environment variable with the specified key and value.
|
62
|
+
|
63
|
+
Args:
|
64
|
+
key (str): The name of the environment variable to set.
|
65
|
+
value (str): The value to assign to the environment variable.
|
66
|
+
is_path (bool, optional): If True, treats the value as a file system path. Defaults to False.
|
67
|
+
|
68
|
+
Returns:
|
69
|
+
bool: True if the environment variable was set successfully, False otherwise.
|
37
70
|
"""
|
38
|
-
return Env._dotenv().set(key, value)
|
71
|
+
return Env._dotenv().set(key, value, is_path)
|
39
72
|
|
40
73
|
@staticmethod
|
41
74
|
def unset(key: str) -> bool:
|
42
75
|
"""
|
43
76
|
Removes the specified environment variable from the environment.
|
77
|
+
|
78
|
+
Args:
|
79
|
+
key (str): The name of the environment variable to remove.
|
80
|
+
|
81
|
+
Returns:
|
82
|
+
bool: True if the variable was successfully removed, False otherwise.
|
44
83
|
"""
|
45
84
|
return Env._dotenv().unset(key)
|
46
85
|
|
47
86
|
@staticmethod
|
48
87
|
def all() -> Dict[str, Any]:
|
49
88
|
"""
|
50
|
-
Retrieve all environment variables
|
89
|
+
Retrieve all environment variables as a dictionary.
|
90
|
+
|
91
|
+
Returns:
|
92
|
+
Dict[str, Any]: A dictionary containing all environment variables loaded by the dotenv configuration.
|
51
93
|
"""
|
52
94
|
return Env._dotenv().all()
|
53
95
|
|
54
96
|
@staticmethod
|
55
97
|
def toJson() -> str:
|
56
98
|
"""
|
57
|
-
Serializes the
|
99
|
+
Serializes the environment variables managed by the Env class into a JSON-formatted string.
|
100
|
+
|
101
|
+
Returns:
|
102
|
+
str: A JSON string representation of the environment variables.
|
58
103
|
"""
|
59
104
|
return Env._dotenv().toJson()
|
60
105
|
|
61
106
|
@staticmethod
|
62
107
|
def toBase64() -> str:
|
63
108
|
"""
|
64
|
-
Converts the
|
109
|
+
Converts the environment variables loaded by the dotenv instance to a Base64-encoded string.
|
110
|
+
|
111
|
+
Returns:
|
112
|
+
str: The Base64-encoded representation of the environment variables.
|
65
113
|
"""
|
66
114
|
return Env._dotenv().toBase64()
|
File without changes
|
@@ -0,0 +1,27 @@
|
|
1
|
+
class OrionisEnvironmentValueException(Exception):
|
2
|
+
"""
|
3
|
+
Exception raised for invalid or unexpected environment values within the Orionis framework.
|
4
|
+
This exception is intended to signal issues encountered when an environment variable,
|
5
|
+
configuration value, or similar parameter does not meet the expected criteria or format.
|
6
|
+
It provides a clear and descriptive error message to facilitate debugging and error handling.
|
7
|
+
Attributes:
|
8
|
+
raise OrionisEnvironmentValueException("Invalid value for ORIONIS_MODE: expected 'production' or 'development'.")
|
9
|
+
msg (str): The error message describing the specific value-related exception.
|
10
|
+
"""
|
11
|
+
|
12
|
+
def __init__(self, msg: str):
|
13
|
+
"""
|
14
|
+
Initializes the exception with a custom error message.
|
15
|
+
Args:
|
16
|
+
msg (str): The error message describing the exception.
|
17
|
+
"""
|
18
|
+
super().__init__(msg)
|
19
|
+
|
20
|
+
def __str__(self) -> str:
|
21
|
+
"""
|
22
|
+
Return a string representation of the exception, including the class name and the first argument.
|
23
|
+
|
24
|
+
Returns:
|
25
|
+
str: A formatted string with the exception class name and its first argument.
|
26
|
+
"""
|
27
|
+
return f"{self.__class__.__name__}: {self.args[0]}"
|
File without changes
|
File without changes
|
File without changes
|