orionis 0.405.0__py3-none-any.whl → 0.407.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/console/base/command.py +57 -50
- orionis/console/base/contracts/command.py +68 -0
- orionis/console/dynamic/contracts/progress_bar.py +3 -3
- orionis/console/dynamic/progress_bar.py +8 -8
- orionis/console/output/console.py +8 -2
- orionis/console/output/contracts/console.py +1 -1
- orionis/container/container.py +2 -2
- orionis/container/context/scope.py +4 -1
- orionis/container/contracts/service_provider.py +2 -2
- orionis/container/entities/binding.py +31 -44
- orionis/container/enums/lifetimes.py +22 -1
- orionis/container/facades/facade.py +1 -2
- orionis/container/providers/service_provider.py +2 -2
- orionis/foundation/application.py +542 -248
- orionis/foundation/config/app/entities/app.py +107 -90
- orionis/foundation/config/auth/entities/auth.py +4 -33
- orionis/foundation/config/cache/entities/cache.py +18 -41
- orionis/foundation/config/cache/entities/file.py +8 -35
- orionis/foundation/config/cache/entities/stores.py +17 -38
- orionis/foundation/config/cors/entities/cors.py +41 -54
- orionis/foundation/config/database/entities/connections.py +40 -56
- orionis/foundation/config/database/entities/database.py +11 -38
- orionis/foundation/config/database/entities/mysql.py +48 -76
- orionis/foundation/config/database/entities/oracle.py +30 -57
- orionis/foundation/config/database/entities/pgsql.py +45 -61
- orionis/foundation/config/database/entities/sqlite.py +26 -53
- orionis/foundation/config/filesystems/entitites/aws.py +28 -49
- orionis/foundation/config/filesystems/entitites/disks.py +27 -47
- orionis/foundation/config/filesystems/entitites/filesystems.py +15 -37
- orionis/foundation/config/filesystems/entitites/local.py +9 -35
- orionis/foundation/config/filesystems/entitites/public.py +14 -41
- orionis/foundation/config/logging/entities/channels.py +56 -86
- orionis/foundation/config/logging/entities/chunked.py +9 -9
- orionis/foundation/config/logging/entities/daily.py +8 -8
- orionis/foundation/config/logging/entities/hourly.py +6 -6
- orionis/foundation/config/logging/entities/logging.py +12 -18
- orionis/foundation/config/logging/entities/monthly.py +7 -7
- orionis/foundation/config/logging/entities/stack.py +5 -5
- orionis/foundation/config/logging/entities/weekly.py +6 -6
- orionis/foundation/config/mail/entities/file.py +9 -36
- orionis/foundation/config/mail/entities/mail.py +22 -40
- orionis/foundation/config/mail/entities/mailers.py +29 -44
- orionis/foundation/config/mail/entities/smtp.py +47 -48
- orionis/foundation/config/queue/entities/brokers.py +19 -41
- orionis/foundation/config/queue/entities/database.py +24 -46
- orionis/foundation/config/queue/entities/queue.py +28 -40
- orionis/foundation/config/roots/paths.py +272 -468
- orionis/foundation/config/session/entities/session.py +23 -53
- orionis/foundation/config/startup.py +165 -135
- orionis/foundation/config/testing/entities/testing.py +137 -122
- orionis/foundation/config/testing/enums/__init__.py +6 -2
- orionis/foundation/config/testing/enums/drivers.py +16 -0
- orionis/foundation/config/testing/enums/verbosity.py +18 -0
- orionis/foundation/contracts/application.py +152 -362
- orionis/foundation/providers/console_provider.py +24 -2
- orionis/foundation/providers/dumper_provider.py +24 -2
- orionis/foundation/providers/logger_provider.py +24 -2
- orionis/foundation/providers/path_resolver_provider.py +25 -2
- orionis/foundation/providers/progress_bar_provider.py +24 -2
- orionis/foundation/providers/testing_provider.py +39 -0
- orionis/foundation/providers/workers_provider.py +24 -2
- orionis/metadata/framework.py +1 -1
- orionis/services/asynchrony/contracts/coroutines.py +13 -5
- orionis/services/asynchrony/coroutines.py +33 -29
- orionis/services/asynchrony/exceptions/exception.py +9 -1
- orionis/services/environment/core/dot_env.py +46 -34
- orionis/services/environment/enums/__init__.py +0 -0
- orionis/services/environment/enums/cast_type.py +42 -0
- orionis/services/environment/helpers/functions.py +1 -2
- orionis/services/environment/key/__init__.py +0 -0
- orionis/services/environment/key/key_generator.py +37 -0
- orionis/services/environment/serializer/__init__.py +0 -0
- orionis/services/environment/serializer/values.py +21 -0
- orionis/services/environment/validators/__init__.py +0 -0
- orionis/services/environment/validators/key_name.py +46 -0
- orionis/services/environment/validators/types.py +45 -0
- orionis/services/system/contracts/imports.py +38 -18
- orionis/services/system/contracts/workers.py +29 -12
- orionis/services/system/imports.py +65 -25
- orionis/services/system/runtime/imports.py +18 -9
- orionis/services/system/workers.py +49 -16
- orionis/support/entities/__init__.py +0 -0
- orionis/support/entities/base.py +104 -0
- orionis/support/facades/testing.py +15 -0
- orionis/support/facades/workers.py +1 -1
- orionis/test/cases/asynchronous.py +0 -11
- orionis/test/cases/synchronous.py +0 -9
- orionis/test/contracts/dumper.py +11 -4
- orionis/test/contracts/kernel.py +5 -110
- orionis/test/contracts/logs.py +27 -65
- orionis/test/contracts/printer.py +16 -128
- orionis/test/contracts/test_result.py +100 -0
- orionis/test/contracts/unit_test.py +87 -150
- orionis/test/core/unit_test.py +608 -554
- orionis/test/entities/result.py +22 -2
- orionis/test/enums/__init__.py +0 -2
- orionis/test/enums/status.py +14 -9
- orionis/test/exceptions/config.py +9 -1
- orionis/test/exceptions/failure.py +34 -11
- orionis/test/exceptions/persistence.py +10 -2
- orionis/test/exceptions/runtime.py +9 -1
- orionis/test/exceptions/value.py +13 -1
- orionis/test/kernel.py +87 -289
- orionis/test/output/dumper.py +83 -18
- orionis/test/output/printer.py +399 -156
- orionis/test/records/logs.py +203 -82
- orionis/test/validators/__init__.py +33 -0
- orionis/test/validators/base_path.py +45 -0
- orionis/test/validators/execution_mode.py +45 -0
- orionis/test/validators/fail_fast.py +37 -0
- orionis/test/validators/folder_path.py +34 -0
- orionis/test/validators/module_name.py +31 -0
- orionis/test/validators/name_pattern.py +40 -0
- orionis/test/validators/pattern.py +36 -0
- orionis/test/validators/persistent.py +42 -0
- orionis/test/validators/persistent_driver.py +43 -0
- orionis/test/validators/print_result.py +37 -0
- orionis/test/validators/tags.py +37 -0
- orionis/test/validators/throw_exception.py +39 -0
- orionis/test/validators/verbosity.py +37 -0
- orionis/test/validators/web_report.py +35 -0
- orionis/test/validators/workers.py +31 -0
- orionis/test/view/render.py +48 -54
- {orionis-0.405.0.dist-info → orionis-0.407.0.dist-info}/METADATA +1 -1
- {orionis-0.405.0.dist-info → orionis-0.407.0.dist-info}/RECORD +170 -112
- tests/container/__init__.py +0 -0
- tests/container/context/__init__.py +0 -0
- tests/container/context/test_manager.py +27 -0
- tests/container/context/test_scope.py +23 -0
- tests/container/entities/__init__.py +0 -0
- tests/container/entities/test_binding.py +133 -0
- tests/container/enums/__init__.py +0 -0
- tests/container/enums/test_lifetimes.py +63 -0
- tests/container/facades/__init__.py +0 -0
- tests/container/facades/test_facade.py +61 -0
- tests/container/mocks/__init__.py +0 -0
- tests/container/mocks/mock_complex_classes.py +482 -0
- tests/container/mocks/mock_simple_classes.py +32 -0
- tests/container/providers/__init__.py +0 -0
- tests/container/providers/test_providers.py +48 -0
- tests/container/resolver/__init__.py +0 -0
- tests/container/resolver/test_resolver.py +55 -0
- tests/container/test_container.py +254 -0
- tests/container/test_singleton.py +98 -0
- tests/container/test_thread_safety.py +217 -0
- tests/container/validators/__init__.py +0 -0
- tests/container/validators/test_implements.py +140 -0
- tests/container/validators/test_is_abstract_class.py +99 -0
- tests/container/validators/test_is_callable.py +73 -0
- tests/container/validators/test_is_concrete_class.py +97 -0
- tests/container/validators/test_is_instance.py +105 -0
- tests/container/validators/test_is_not_subclass.py +117 -0
- tests/container/validators/test_is_subclass.py +115 -0
- tests/container/validators/test_is_valid_alias.py +113 -0
- tests/container/validators/test_lifetime.py +75 -0
- tests/example/test_example.py +2 -2
- tests/foundation/config/testing/test_foundation_config_testing.py +1 -1
- tests/metadata/test_metadata_framework.py +89 -24
- tests/metadata/test_metadata_package.py +55 -10
- tests/services/asynchrony/test_services_asynchrony_coroutine.py +52 -7
- tests/services/system/test_services_system_imports.py +119 -16
- tests/services/system/test_services_system_workers.py +71 -30
- tests/testing/test_testing_result.py +117 -117
- tests/testing/test_testing_unit.py +209 -209
- orionis/foundation/config/base.py +0 -112
- orionis/test/arguments/parser.py +0 -187
- orionis/test/contracts/parser.py +0 -43
- orionis/test/entities/arguments.py +0 -38
- orionis/test/enums/execution_mode.py +0 -16
- /orionis/{test/arguments → console/base/contracts}/__init__.py +0 -0
- /orionis/foundation/config/testing/enums/{test_mode.py → mode.py} +0 -0
- {orionis-0.405.0.dist-info → orionis-0.407.0.dist-info}/WHEEL +0 -0
- {orionis-0.405.0.dist-info → orionis-0.407.0.dist-info}/licenses/LICENCE +0 -0
- {orionis-0.405.0.dist-info → orionis-0.407.0.dist-info}/top_level.txt +0 -0
- {orionis-0.405.0.dist-info → orionis-0.407.0.dist-info}/zip-safe +0 -0
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import base64
|
|
3
|
+
|
|
4
|
+
class SecureKeyGenerator:
|
|
5
|
+
"""
|
|
6
|
+
Provides static methods for generating secure random keys in base64 format.
|
|
7
|
+
|
|
8
|
+
Methods
|
|
9
|
+
-------
|
|
10
|
+
generate_key() : str
|
|
11
|
+
Generates a secure random key encoded in base64.
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
@staticmethod
|
|
15
|
+
def generate() -> str:
|
|
16
|
+
"""
|
|
17
|
+
Generates a secure random key and encodes it in base64 format.
|
|
18
|
+
|
|
19
|
+
This method creates a cryptographically secure random key of 32 bytes,
|
|
20
|
+
encodes it using base64 encoding, and returns the result as a string
|
|
21
|
+
prefixed with 'base64:'.
|
|
22
|
+
|
|
23
|
+
Returns
|
|
24
|
+
-------
|
|
25
|
+
str
|
|
26
|
+
A string in the format 'base64:<key>', where <key> is a base64-encoded
|
|
27
|
+
representation of a securely generated 32-byte random key.
|
|
28
|
+
"""
|
|
29
|
+
|
|
30
|
+
# Generate 32 bytes of cryptographically secure random data
|
|
31
|
+
key = os.urandom(32)
|
|
32
|
+
|
|
33
|
+
# Encode the random bytes using base64 and decode to a UTF-8 string
|
|
34
|
+
encoded = base64.b64encode(key).decode('utf-8')
|
|
35
|
+
|
|
36
|
+
# Return the key in the required format
|
|
37
|
+
return f"base64:{encoded}"
|
|
File without changes
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
from orionis.services.environment.enums.cast_type import EnvCastType
|
|
2
|
+
|
|
3
|
+
class SerializerValue:
|
|
4
|
+
|
|
5
|
+
def __init__(self, value):
|
|
6
|
+
pass
|
|
7
|
+
|
|
8
|
+
def to(self, type_hint: str | EnvCastType = None):
|
|
9
|
+
pass
|
|
10
|
+
|
|
11
|
+
def get(self):
|
|
12
|
+
pass
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class SerializerFrom:
|
|
16
|
+
|
|
17
|
+
def __init__(self, key: str):
|
|
18
|
+
pass
|
|
19
|
+
|
|
20
|
+
def get(self):
|
|
21
|
+
pass
|
|
File without changes
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import re
|
|
2
|
+
from orionis.services.environment.exceptions.value import OrionisEnvironmentValueError
|
|
3
|
+
|
|
4
|
+
class __ValidateKeyName:
|
|
5
|
+
|
|
6
|
+
# Regular expression pattern to match valid environment variable names
|
|
7
|
+
_pattern = re.compile(r'^[A-Z][A-Z0-9_]*$')
|
|
8
|
+
|
|
9
|
+
def __call__(self, key: object) -> str:
|
|
10
|
+
"""
|
|
11
|
+
Validates that the provided environment variable name meets the required format.
|
|
12
|
+
|
|
13
|
+
Parameters
|
|
14
|
+
----------
|
|
15
|
+
key : object
|
|
16
|
+
The environment variable name to validate.
|
|
17
|
+
|
|
18
|
+
Returns
|
|
19
|
+
-------
|
|
20
|
+
str
|
|
21
|
+
The validated environment variable name if it meets the format requirements.
|
|
22
|
+
|
|
23
|
+
Raises
|
|
24
|
+
------
|
|
25
|
+
OrionisEnvironmentValueError
|
|
26
|
+
If the provided key is not a string or does not match the required format.
|
|
27
|
+
"""
|
|
28
|
+
|
|
29
|
+
# Check if the key is a string
|
|
30
|
+
if not isinstance(key, str):
|
|
31
|
+
raise OrionisEnvironmentValueError(
|
|
32
|
+
f"Environment variable name must be a string, got {type(key).__name__}."
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
# Validate the key against the pattern
|
|
36
|
+
if not self._pattern.fullmatch(key):
|
|
37
|
+
raise OrionisEnvironmentValueError(
|
|
38
|
+
f"Invalid environment variable name '{key}'. It must start with an uppercase letter, "
|
|
39
|
+
"contain only uppercase letters, numbers, or underscores. Example: 'MY_ENV_VAR'."
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
# Return the validated key
|
|
43
|
+
return key
|
|
44
|
+
|
|
45
|
+
# Instance to be used for key name validation
|
|
46
|
+
ValidateKeyName = __ValidateKeyName()
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import re
|
|
2
|
+
from typing import Any, Union
|
|
3
|
+
from orionis.services.environment.enums.cast_type import EnvCastType
|
|
4
|
+
from orionis.services.environment.exceptions.value import OrionisEnvironmentValueError
|
|
5
|
+
|
|
6
|
+
class __ValidateTypes:
|
|
7
|
+
|
|
8
|
+
def __call__(self, value: Union[str, int, float, bool, list, dict, tuple, set], type_hint: str | EnvCastType = None) -> str:
|
|
9
|
+
|
|
10
|
+
# Ensure the value is a valid type.
|
|
11
|
+
if not isinstance(value, (str, int, float, bool, list, dict, tuple, set)):
|
|
12
|
+
raise OrionisEnvironmentValueError(
|
|
13
|
+
f"Unsupported value type: {type(value).__name__}. Allowed types are str, int, float, bool, list, dict, tuple, set."
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
# If a type hint is provided, ensure it is valid.
|
|
17
|
+
if type_hint and not isinstance(type_hint, (str, EnvCastType)):
|
|
18
|
+
raise OrionisEnvironmentValueError(
|
|
19
|
+
f"Type hint must be a string or EnvCastType, got {type(type_hint).__name__}."
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
# If type_hint is provided, convert it to a string if it's an EnvCastType.
|
|
23
|
+
if type_hint:
|
|
24
|
+
|
|
25
|
+
# If type_hint is a string, convert it to EnvCastType if valid.
|
|
26
|
+
if isinstance(type_hint, str):
|
|
27
|
+
try:
|
|
28
|
+
type_hint = EnvCastType[type_hint.upper()].value
|
|
29
|
+
except KeyError:
|
|
30
|
+
raise OrionisEnvironmentValueError(
|
|
31
|
+
f"Invalid type hint: {type_hint}. Allowed types are {[e.value for e in EnvCastType]}"
|
|
32
|
+
)
|
|
33
|
+
elif isinstance(type_hint, EnvCastType):
|
|
34
|
+
type_hint = type_hint.value
|
|
35
|
+
|
|
36
|
+
# If no type hint is provided, use the type of the value.
|
|
37
|
+
else:
|
|
38
|
+
type_hint = type(value).__name__.lower()
|
|
39
|
+
|
|
40
|
+
# Return the type hint as a string.
|
|
41
|
+
return type_hint
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
# Instance to be used for key name validation
|
|
45
|
+
ValidateTypes = __ValidateTypes()
|
|
@@ -1,51 +1,71 @@
|
|
|
1
1
|
from abc import ABC, abstractmethod
|
|
2
2
|
|
|
3
3
|
class IImports(ABC):
|
|
4
|
-
"""
|
|
5
|
-
Interface for a utility to collect and display information about currently loaded Python modules.
|
|
6
|
-
|
|
7
|
-
Methods
|
|
8
|
-
-------
|
|
9
|
-
collect()
|
|
10
|
-
Collects information about user-defined Python modules currently loaded in sys.modules.
|
|
11
|
-
|
|
12
|
-
display()
|
|
13
|
-
Displays a formatted table of collected import statements.
|
|
14
|
-
|
|
15
|
-
clear()
|
|
16
|
-
Clears the collected imports list.
|
|
17
|
-
"""
|
|
18
4
|
|
|
19
5
|
@abstractmethod
|
|
20
6
|
def collect(self):
|
|
21
7
|
"""
|
|
22
|
-
|
|
8
|
+
Collects information about user-defined Python modules currently loaded in `sys.modules`.
|
|
9
|
+
|
|
10
|
+
This method should scan the current Python runtime environment and gather details about
|
|
11
|
+
all user-defined modules that have been imported and are present in `sys.modules`. The
|
|
12
|
+
collected information may include module names, file paths, and other relevant metadata,
|
|
13
|
+
depending on the implementation.
|
|
23
14
|
|
|
24
15
|
Returns
|
|
25
16
|
-------
|
|
26
17
|
IImports
|
|
27
|
-
|
|
18
|
+
Returns the current instance (`self`) with its internal imports information updated
|
|
19
|
+
to reflect the latest state of loaded modules.
|
|
20
|
+
|
|
21
|
+
Notes
|
|
22
|
+
-----
|
|
23
|
+
This method does not modify the actual modules loaded in memory; it only updates the
|
|
24
|
+
internal collection maintained by the implementation. Subclasses should implement the
|
|
25
|
+
logic for identifying and storing relevant module information.
|
|
28
26
|
"""
|
|
27
|
+
|
|
28
|
+
# Subclasses should implement logic to scan sys.modules and update internal imports collection.
|
|
29
29
|
pass
|
|
30
30
|
|
|
31
31
|
@abstractmethod
|
|
32
32
|
def display(self) -> None:
|
|
33
33
|
"""
|
|
34
|
-
|
|
34
|
+
Displays a formatted table summarizing the collected import statements.
|
|
35
|
+
|
|
36
|
+
This method should present the information about the currently collected Python module imports
|
|
37
|
+
in a human-readable tabular format. The display may include details such as module names,
|
|
38
|
+
file paths, and other relevant metadata, depending on the implementation.
|
|
35
39
|
|
|
36
40
|
Returns
|
|
37
41
|
-------
|
|
38
42
|
None
|
|
43
|
+
This method does not return any value. Its sole purpose is to output the collected import
|
|
44
|
+
information for inspection or debugging.
|
|
45
|
+
|
|
46
|
+
Notes
|
|
47
|
+
-----
|
|
48
|
+
The actual formatting and output destination (e.g., console, log, GUI) are determined by the
|
|
49
|
+
implementing subclass.
|
|
39
50
|
"""
|
|
51
|
+
|
|
52
|
+
# Subclasses should implement logic to format and output the collected imports.
|
|
40
53
|
pass
|
|
41
54
|
|
|
42
55
|
@abstractmethod
|
|
43
56
|
def clear(self) -> None:
|
|
44
57
|
"""
|
|
45
|
-
|
|
58
|
+
Removes all entries from the collected imports list, resetting the internal state.
|
|
59
|
+
|
|
60
|
+
This method should be called when you want to discard all previously collected import
|
|
61
|
+
information and start fresh. It does not affect the actual Python modules loaded in memory,
|
|
62
|
+
only the internal collection maintained by the implementation.
|
|
46
63
|
|
|
47
64
|
Returns
|
|
48
65
|
-------
|
|
49
66
|
None
|
|
67
|
+
This method does not return any value.
|
|
50
68
|
"""
|
|
69
|
+
|
|
70
|
+
# Subclasses should implement logic to clear their internal imports collection.
|
|
51
71
|
pass
|
|
@@ -1,35 +1,52 @@
|
|
|
1
1
|
from abc import ABC, abstractmethod
|
|
2
2
|
|
|
3
3
|
class IWorkers(ABC):
|
|
4
|
-
"""
|
|
5
|
-
Interface for calculating the optimal number of workers a machine can handle based on CPU and memory resources.
|
|
6
|
-
|
|
7
|
-
Notes
|
|
8
|
-
-----
|
|
9
|
-
Implementations should provide logic to determine the recommended number of worker processes
|
|
10
|
-
according to the available CPU and memory resources of the current machine.
|
|
11
|
-
"""
|
|
12
4
|
|
|
13
5
|
@abstractmethod
|
|
14
6
|
def setRamPerWorker(self, ram_per_worker: float) -> None:
|
|
15
7
|
"""
|
|
16
|
-
Set the amount of RAM
|
|
8
|
+
Set the amount of RAM to allocate for each worker process.
|
|
17
9
|
|
|
18
10
|
Parameters
|
|
19
11
|
----------
|
|
20
12
|
ram_per_worker : float
|
|
21
|
-
|
|
13
|
+
The amount of RAM, in gigabytes (GB), to allocate for each worker process.
|
|
14
|
+
|
|
15
|
+
Returns
|
|
16
|
+
-------
|
|
17
|
+
None
|
|
18
|
+
This method does not return any value.
|
|
19
|
+
|
|
20
|
+
Notes
|
|
21
|
+
-----
|
|
22
|
+
This method should be implemented by subclasses to configure the memory usage
|
|
23
|
+
per worker, which may affect the total number of workers that can be spawned
|
|
24
|
+
based on system resources.
|
|
22
25
|
"""
|
|
26
|
+
|
|
27
|
+
# Implementation should assign the specified RAM per worker.
|
|
23
28
|
pass
|
|
24
29
|
|
|
25
30
|
@abstractmethod
|
|
26
31
|
def calculate(self) -> int:
|
|
27
32
|
"""
|
|
28
|
-
Compute the maximum number of
|
|
33
|
+
Compute the recommended maximum number of worker processes for the current machine.
|
|
34
|
+
|
|
35
|
+
This method should consider both CPU and memory constraints to determine the optimal
|
|
36
|
+
number of worker processes that can be safely spawned without overloading system resources.
|
|
29
37
|
|
|
30
38
|
Returns
|
|
31
39
|
-------
|
|
32
40
|
int
|
|
33
|
-
|
|
41
|
+
The maximum number of worker processes that can be supported by the current machine,
|
|
42
|
+
based on available CPU cores and memory limits.
|
|
43
|
+
|
|
44
|
+
Notes
|
|
45
|
+
-----
|
|
46
|
+
Subclasses should implement this method to analyze system resources and return an integer
|
|
47
|
+
representing the recommended number of workers. The calculation should ensure that each
|
|
48
|
+
worker receives sufficient resources as configured (e.g., RAM per worker).
|
|
34
49
|
"""
|
|
50
|
+
|
|
51
|
+
# Implementation should analyze system resources and return the recommended worker count.
|
|
35
52
|
pass
|
|
@@ -2,58 +2,68 @@ from typing import List, Dict, Any
|
|
|
2
2
|
from orionis.services.system.contracts.imports import IImports
|
|
3
3
|
|
|
4
4
|
class Imports(IImports):
|
|
5
|
-
"""
|
|
6
|
-
Utility class to collect and display information about currently loaded Python modules.
|
|
7
|
-
|
|
8
|
-
This class provides methods to gather details about user-defined Python modules
|
|
9
|
-
currently loaded in `sys.modules`, excluding standard library and virtual environment modules.
|
|
10
|
-
It can display the collected information in a formatted table using the Rich library.
|
|
11
|
-
"""
|
|
12
5
|
|
|
13
6
|
def __init__(self):
|
|
14
7
|
"""
|
|
15
|
-
Initialize the Imports
|
|
8
|
+
Initialize the Imports instance.
|
|
9
|
+
|
|
10
|
+
This constructor sets up the Imports object by initializing an empty list
|
|
11
|
+
to store information about user-defined Python modules. The list will
|
|
12
|
+
contain dictionaries, each representing a module with its name, file path,
|
|
13
|
+
and defined symbols.
|
|
16
14
|
|
|
17
|
-
|
|
15
|
+
Returns
|
|
16
|
+
-------
|
|
17
|
+
None
|
|
18
|
+
This method does not return any value.
|
|
18
19
|
"""
|
|
20
|
+
|
|
21
|
+
# List to hold information about imported modules
|
|
19
22
|
self.imports: List[Dict[str, Any]] = []
|
|
20
23
|
|
|
21
24
|
def collect(self) -> 'Imports':
|
|
22
25
|
"""
|
|
23
26
|
Collect information about user-defined Python modules currently loaded.
|
|
24
27
|
|
|
25
|
-
|
|
26
|
-
-
|
|
27
|
-
-
|
|
28
|
-
-
|
|
28
|
+
Iterates through all modules in `sys.modules` and gathers details for each qualifying module:
|
|
29
|
+
- Module name.
|
|
30
|
+
- Relative file path from the current working directory.
|
|
31
|
+
- List of symbols (functions, classes, or submodules) defined in the module.
|
|
29
32
|
|
|
30
|
-
Excludes:
|
|
31
|
-
-
|
|
32
|
-
-
|
|
33
|
-
-
|
|
34
|
-
-
|
|
33
|
+
Excludes modules that:
|
|
34
|
+
- Are part of the standard library.
|
|
35
|
+
- Reside in the active virtual environment (if any).
|
|
36
|
+
- Are binary extension modules (e.g., `.pyd`, `.dll`, `.so`).
|
|
37
|
+
- Are special modules such as `"__main__"`, `"__mp_main__"`, or those starting with `"_distutils"`.
|
|
35
38
|
|
|
36
|
-
The collected information is stored in `self.imports` as a list of dictionaries.
|
|
39
|
+
The collected information is stored in `self.imports` as a list of dictionaries, each containing the module's name, file path, and symbols.
|
|
37
40
|
|
|
38
41
|
Returns
|
|
39
42
|
-------
|
|
40
43
|
Imports
|
|
41
|
-
The current instance with
|
|
44
|
+
The current instance of `Imports` with the `imports` attribute updated to include information about the collected modules.
|
|
42
45
|
"""
|
|
43
46
|
|
|
44
47
|
import sys
|
|
45
48
|
import os
|
|
46
49
|
import types
|
|
47
50
|
|
|
51
|
+
# Clear any previously collected imports
|
|
48
52
|
self.imports.clear()
|
|
53
|
+
|
|
54
|
+
# Get standard library paths to exclude standard modules
|
|
49
55
|
stdlib_paths = [os.path.dirname(os.__file__)]
|
|
56
|
+
|
|
57
|
+
# Get virtual environment path if active
|
|
50
58
|
venv_path = os.environ.get("VIRTUAL_ENV")
|
|
51
59
|
if venv_path:
|
|
52
60
|
venv_path = os.path.abspath(venv_path)
|
|
53
61
|
|
|
62
|
+
# Iterate over all loaded modules
|
|
54
63
|
for name, module in list(sys.modules.items()):
|
|
55
|
-
file:str = getattr(module, '__file__', None)
|
|
64
|
+
file: str = getattr(module, '__file__', None)
|
|
56
65
|
|
|
66
|
+
# Filter out unwanted modules based on path, type, and name
|
|
57
67
|
if (
|
|
58
68
|
file
|
|
59
69
|
and not any(file.startswith(stdlib_path) for stdlib_path in stdlib_paths)
|
|
@@ -62,18 +72,25 @@ class Imports(IImports):
|
|
|
62
72
|
and name not in ("__main__", "__mp_main__")
|
|
63
73
|
and not name.startswith("_distutils")
|
|
64
74
|
):
|
|
75
|
+
|
|
76
|
+
# Get relative file path from current working directory
|
|
65
77
|
rel_file = os.path.relpath(file, os.getcwd())
|
|
66
78
|
symbols = []
|
|
67
79
|
|
|
80
|
+
# Collect symbols defined in the module (functions, classes, submodules)
|
|
68
81
|
try:
|
|
69
82
|
for attr in dir(module):
|
|
70
83
|
value = getattr(module, attr)
|
|
71
84
|
if isinstance(value, (types.FunctionType, type, types.ModuleType)):
|
|
85
|
+
|
|
86
|
+
# Ensure symbol is defined in this module
|
|
72
87
|
if getattr(value, '__module__', None) == name:
|
|
73
88
|
symbols.append(attr)
|
|
74
89
|
except Exception:
|
|
90
|
+
# Ignore errors during symbol collection
|
|
75
91
|
pass
|
|
76
92
|
|
|
93
|
+
# Only add modules that are not __init__.py and have symbols
|
|
77
94
|
if not rel_file.endswith('__init__.py') and symbols:
|
|
78
95
|
self.imports.append({
|
|
79
96
|
"name": name,
|
|
@@ -81,32 +98,45 @@ class Imports(IImports):
|
|
|
81
98
|
"symbols": symbols,
|
|
82
99
|
})
|
|
83
100
|
|
|
101
|
+
# Return the current instance with updated imports
|
|
84
102
|
return self
|
|
85
103
|
|
|
86
104
|
def display(self) -> None:
|
|
87
105
|
"""
|
|
88
106
|
Display a formatted table of collected import statements using the Rich library.
|
|
89
107
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
rendered inside a styled panel in the console
|
|
108
|
+
This method presents a visual summary of all collected user-defined Python modules.
|
|
109
|
+
If the imports have not been collected yet, it automatically calls `self.collect()` to gather them.
|
|
110
|
+
The output is rendered as a table inside a styled panel in the console, showing each module's name,
|
|
111
|
+
relative file path, and its defined symbols.
|
|
112
|
+
|
|
113
|
+
Parameters
|
|
114
|
+
----------
|
|
115
|
+
None
|
|
93
116
|
|
|
94
117
|
Returns
|
|
95
118
|
-------
|
|
96
119
|
None
|
|
120
|
+
This method does not return any value. It outputs the formatted table to the console.
|
|
97
121
|
"""
|
|
98
122
|
|
|
123
|
+
# Collect imports if not already done
|
|
99
124
|
if not self.imports:
|
|
100
125
|
self.collect()
|
|
101
126
|
|
|
127
|
+
# Import Rich components for console output
|
|
102
128
|
from rich.console import Console
|
|
103
129
|
from rich.table import Table
|
|
104
130
|
from rich.box import MINIMAL
|
|
105
131
|
from rich.panel import Panel
|
|
106
132
|
|
|
133
|
+
# Create a console instance for output
|
|
107
134
|
console = Console()
|
|
135
|
+
|
|
136
|
+
# Set table width to 75% of console width
|
|
108
137
|
width = int(console.size.width * 0.75)
|
|
109
138
|
|
|
139
|
+
# Create a table with minimal box style and custom formatting
|
|
110
140
|
table = Table(
|
|
111
141
|
box=MINIMAL,
|
|
112
142
|
show_header=True,
|
|
@@ -117,14 +147,17 @@ class Imports(IImports):
|
|
|
117
147
|
collapse_padding=True,
|
|
118
148
|
)
|
|
119
149
|
|
|
150
|
+
# Add columns for module name, file path, and symbols
|
|
120
151
|
table.add_column("Name", style="cyan", no_wrap=True)
|
|
121
152
|
table.add_column("File", style="white")
|
|
122
153
|
table.add_column("Symbols", style="magenta")
|
|
123
154
|
|
|
155
|
+
# Populate the table with sorted import data
|
|
124
156
|
for imp in sorted(self.imports, key=lambda x: x["name"].lower()):
|
|
125
157
|
symbols_str = ", ".join(imp["symbols"])
|
|
126
158
|
table.add_row(imp["name"], imp["file"], symbols_str)
|
|
127
159
|
|
|
160
|
+
# Render the table inside a styled panel in the console
|
|
128
161
|
console.print(Panel(
|
|
129
162
|
table,
|
|
130
163
|
title="[bold blue]🔎 Loaded Python Modules (Orionis Imports Trace)[/bold blue]",
|
|
@@ -134,10 +167,17 @@ class Imports(IImports):
|
|
|
134
167
|
|
|
135
168
|
def clear(self) -> None:
|
|
136
169
|
"""
|
|
137
|
-
|
|
170
|
+
Remove all entries from the collected imports list.
|
|
171
|
+
|
|
172
|
+
This method resets the `imports` attribute by removing all currently stored
|
|
173
|
+
module information. It is useful for discarding previously collected data
|
|
174
|
+
before performing a new collection or when a fresh state is required.
|
|
138
175
|
|
|
139
176
|
Returns
|
|
140
177
|
-------
|
|
141
178
|
None
|
|
179
|
+
This method does not return any value. The `imports` list is emptied in place.
|
|
142
180
|
"""
|
|
181
|
+
|
|
182
|
+
# Remove all items from the imports list to reset its state
|
|
143
183
|
self.imports.clear()
|
|
@@ -25,6 +25,7 @@ Notes
|
|
|
25
25
|
- Thread safety is provided via a threading.Lock.
|
|
26
26
|
|
|
27
27
|
"""
|
|
28
|
+
|
|
28
29
|
import builtins
|
|
29
30
|
from collections import defaultdict
|
|
30
31
|
from threading import Lock
|
|
@@ -40,40 +41,48 @@ _import_lock = Lock()
|
|
|
40
41
|
|
|
41
42
|
def custom_import(name, globals=None, locals=None, fromlist=(), level=0):
|
|
42
43
|
"""
|
|
43
|
-
|
|
44
|
+
Tracks and logs imports of modules whose names start with 'orionis'.
|
|
45
|
+
|
|
46
|
+
This function overrides Python's built-in import mechanism to monitor
|
|
47
|
+
how many times modules from the 'orionis' package are imported. It
|
|
48
|
+
increments an internal counter for each such import and prints a log
|
|
49
|
+
message with the module name, import count, and fromlist. Thread safety
|
|
50
|
+
is ensured using a lock.
|
|
44
51
|
|
|
45
52
|
Parameters
|
|
46
53
|
----------
|
|
47
54
|
name : str
|
|
48
55
|
The name of the module to import.
|
|
49
56
|
globals : dict, optional
|
|
50
|
-
The global namespace.
|
|
57
|
+
The global namespace in which the import is performed.
|
|
51
58
|
locals : dict, optional
|
|
52
|
-
The local namespace.
|
|
59
|
+
The local namespace in which the import is performed.
|
|
53
60
|
fromlist : tuple, optional
|
|
54
61
|
Names to import from the module.
|
|
55
62
|
level : int, optional
|
|
56
|
-
Relative import level.
|
|
63
|
+
Relative import level (0 for absolute, >0 for relative).
|
|
57
64
|
|
|
58
65
|
Returns
|
|
59
66
|
-------
|
|
60
|
-
module
|
|
61
|
-
The imported module.
|
|
67
|
+
module : ModuleType
|
|
68
|
+
The imported module object as returned by the original import function.
|
|
62
69
|
"""
|
|
63
|
-
#
|
|
70
|
+
# Only track imports for modules starting with 'orionis'
|
|
64
71
|
if str(name).startswith("orionis"):
|
|
65
72
|
with _import_lock:
|
|
73
|
+
|
|
74
|
+
# Increment the import count for this module
|
|
66
75
|
_import_count[name] += 1
|
|
67
76
|
count = _import_count[name]
|
|
68
77
|
|
|
69
|
-
# Print
|
|
78
|
+
# Print import details to the console
|
|
70
79
|
print(
|
|
71
80
|
f"\033[1;37mModule\033[0m: \033[90m{name}\033[0m | "
|
|
72
81
|
f"\033[1;37mImported\033[0m: \033[90m{count}\033[0m | "
|
|
73
82
|
f"\033[1;37mFromList\033[0m: \033[90m{fromlist}\033[0m"
|
|
74
83
|
)
|
|
75
84
|
|
|
76
|
-
#
|
|
85
|
+
# Delegate the actual import to the original __import__ function
|
|
77
86
|
return _original_import(name, globals, locals, fromlist, level)
|
|
78
87
|
|
|
79
88
|
# Override the built-in __import__ function
|