orionis 0.404.0__py3-none-any.whl → 0.406.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 +18 -10
- orionis/foundation/config/logging/entities/daily.py +17 -9
- orionis/foundation/config/logging/entities/hourly.py +15 -7
- orionis/foundation/config/logging/entities/logging.py +12 -18
- orionis/foundation/config/logging/entities/monthly.py +16 -8
- orionis/foundation/config/logging/entities/stack.py +15 -7
- orionis/foundation/config/logging/entities/weekly.py +15 -7
- orionis/foundation/config/logging/validators/path.py +6 -0
- 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/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/log/handlers/filename.py +64 -0
- orionis/services/log/handlers/size_rotating.py +9 -40
- orionis/services/log/handlers/timed_rotating.py +9 -41
- orionis/services/log/log_service.py +9 -52
- 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 +82 -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.404.0.dist-info → orionis-0.406.0.dist-info}/METADATA +1 -1
- {orionis-0.404.0.dist-info → orionis-0.406.0.dist-info}/RECORD +160 -108
- 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/foundation/config/logging/test_foundation_config_logging_chunked.py +12 -34
- tests/foundation/config/logging/test_foundation_config_logging_daily.py +11 -11
- tests/foundation/config/logging/test_foundation_config_logging_hourly.py +7 -8
- tests/foundation/config/logging/test_foundation_config_logging_monthly.py +7 -10
- tests/foundation/config/logging/test_foundation_config_logging_stack.py +6 -11
- tests/foundation/config/logging/test_foundation_config_logging_weekly.py +6 -5
- tests/foundation/config/testing/test_foundation_config_testing.py +1 -1
- tests/metadata/test_metadata_framework.py +18 -18
- 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.404.0.dist-info → orionis-0.406.0.dist-info}/WHEEL +0 -0
- {orionis-0.404.0.dist-info → orionis-0.406.0.dist-info}/licenses/LICENCE +0 -0
- {orionis-0.404.0.dist-info → orionis-0.406.0.dist-info}/top_level.txt +0 -0
- {orionis-0.404.0.dist-info → orionis-0.406.0.dist-info}/zip-safe +0 -0
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
from dataclasses import
|
|
1
|
+
from dataclasses import dataclass, field
|
|
2
2
|
from orionis.foundation.exceptions import OrionisIntegrityException
|
|
3
|
+
from orionis.support.entities.base import BaseEntity
|
|
3
4
|
|
|
4
5
|
@dataclass(unsafe_hash=True, kw_only=True)
|
|
5
|
-
class File:
|
|
6
|
+
class File(BaseEntity):
|
|
6
7
|
"""
|
|
7
8
|
Represents a file configuration entity for storing outgoing emails.
|
|
8
9
|
Attributes:
|
|
@@ -17,8 +18,11 @@ class File:
|
|
|
17
18
|
"""
|
|
18
19
|
|
|
19
20
|
path: str = field(
|
|
20
|
-
default="storage/mail",
|
|
21
|
-
metadata={
|
|
21
|
+
default = "storage/mail",
|
|
22
|
+
metadata = {
|
|
23
|
+
"description": "The file path where outgoing emails are stored.",
|
|
24
|
+
"default": "storage/mail",
|
|
25
|
+
}
|
|
22
26
|
)
|
|
23
27
|
|
|
24
28
|
def __post_init__(self):
|
|
@@ -29,35 +33,4 @@ class File:
|
|
|
29
33
|
OrionisIntegrityException: If 'path' is not a non-empty string.
|
|
30
34
|
"""
|
|
31
35
|
if not isinstance(self.path, str) or self.path.strip() == "":
|
|
32
|
-
raise OrionisIntegrityException("The 'path' attribute must be a non-empty string.")
|
|
33
|
-
|
|
34
|
-
def toDict(self) -> dict:
|
|
35
|
-
"""
|
|
36
|
-
Converts the current instance into a dictionary representation.
|
|
37
|
-
|
|
38
|
-
Returns:
|
|
39
|
-
dict: A dictionary containing all the fields of the instance.
|
|
40
|
-
"""
|
|
41
|
-
return asdict(self)
|
|
42
|
-
|
|
43
|
-
def getFields(self):
|
|
44
|
-
"""
|
|
45
|
-
Retrieves a list of field information for the current dataclass instance.
|
|
46
|
-
|
|
47
|
-
Returns:
|
|
48
|
-
list: A list of dictionaries, each containing details about a field:
|
|
49
|
-
- name (str): The name of the field.
|
|
50
|
-
- type (type): The type of the field.
|
|
51
|
-
- default: The default value of the field, if specified; otherwise, the value from metadata or None.
|
|
52
|
-
- metadata (mapping): The metadata associated with the field.
|
|
53
|
-
"""
|
|
54
|
-
__fields = []
|
|
55
|
-
for field in fields(self):
|
|
56
|
-
__metadata = dict(field.metadata) or {}
|
|
57
|
-
__fields.append({
|
|
58
|
-
"name": field.name,
|
|
59
|
-
"type": field.type.__name__ if hasattr(field.type, '__name__') else str(field.type),
|
|
60
|
-
"default": field.default if (field.default is not None and '_MISSING_TYPE' not in str(field.default)) else __metadata.get('default', None),
|
|
61
|
-
"metadata": __metadata
|
|
62
|
-
})
|
|
63
|
-
return __fields
|
|
36
|
+
raise OrionisIntegrityException("The 'path' attribute must be a non-empty string.")
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
from dataclasses import
|
|
1
|
+
from dataclasses import dataclass, field, fields
|
|
2
2
|
from orionis.foundation.exceptions import OrionisIntegrityException
|
|
3
3
|
from orionis.foundation.config.mail.entities.mailers import Mailers
|
|
4
|
+
from orionis.support.entities.base import BaseEntity
|
|
4
5
|
|
|
5
6
|
@dataclass(unsafe_hash=True, kw_only=True)
|
|
6
|
-
class Mail:
|
|
7
|
+
class Mail(BaseEntity):
|
|
7
8
|
"""
|
|
8
9
|
Represents the mail configuration entity.
|
|
9
10
|
Attributes:
|
|
@@ -18,13 +19,19 @@ class Mail:
|
|
|
18
19
|
"""
|
|
19
20
|
|
|
20
21
|
default: str = field(
|
|
21
|
-
default="smtp",
|
|
22
|
-
metadata={
|
|
22
|
+
default = "smtp",
|
|
23
|
+
metadata = {
|
|
24
|
+
"description": "The default mailer transport to use.",
|
|
25
|
+
"default": "smtp",
|
|
26
|
+
}
|
|
23
27
|
)
|
|
24
28
|
|
|
25
|
-
mailers: Mailers = field(
|
|
26
|
-
default_factory=Mailers,
|
|
27
|
-
metadata={
|
|
29
|
+
mailers: Mailers | dict = field(
|
|
30
|
+
default_factory = lambda: Mailers(),
|
|
31
|
+
metadata = {
|
|
32
|
+
"description": "The available mail transport configurations.",
|
|
33
|
+
"default": Mailers().toDict()
|
|
34
|
+
}
|
|
28
35
|
)
|
|
29
36
|
|
|
30
37
|
def __post_init__(self):
|
|
@@ -37,42 +44,17 @@ class Mail:
|
|
|
37
44
|
OrionisIntegrityException: If 'default' is not a valid string option or if 'mailers' is not a Mailers object.
|
|
38
45
|
"""
|
|
39
46
|
|
|
47
|
+
# Validate 'default' attribute
|
|
40
48
|
options = [f.name for f in fields(Mailers)]
|
|
41
49
|
if not isinstance(self.default, str) or self.default not in options:
|
|
42
50
|
raise OrionisIntegrityException(
|
|
43
51
|
f"The 'default' property must be a string and match one of the available options ({options})."
|
|
44
52
|
)
|
|
45
53
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
Returns:
|
|
54
|
-
dict: A dictionary containing all the fields of the instance.
|
|
55
|
-
"""
|
|
56
|
-
return asdict(self)
|
|
57
|
-
|
|
58
|
-
def getFields(self):
|
|
59
|
-
"""
|
|
60
|
-
Retrieves a list of field information for the current dataclass instance.
|
|
61
|
-
|
|
62
|
-
Returns:
|
|
63
|
-
list: A list of dictionaries, each containing details about a field:
|
|
64
|
-
- name (str): The name of the field.
|
|
65
|
-
- type (type): The type of the field.
|
|
66
|
-
- default: The default value of the field, if specified; otherwise, the value from metadata or None.
|
|
67
|
-
- metadata (mapping): The metadata associated with the field.
|
|
68
|
-
"""
|
|
69
|
-
__fields = []
|
|
70
|
-
for field in fields(self):
|
|
71
|
-
__metadata = dict(field.metadata) or {}
|
|
72
|
-
__fields.append({
|
|
73
|
-
"name": field.name,
|
|
74
|
-
"type": field.type.__name__ if hasattr(field.type, '__name__') else str(field.type),
|
|
75
|
-
"default": field.default if (field.default is not None and '_MISSING_TYPE' not in str(field.default)) else __metadata.get('default', None),
|
|
76
|
-
"metadata": __metadata
|
|
77
|
-
})
|
|
78
|
-
return __fields
|
|
54
|
+
# Validate 'mailers' attribute
|
|
55
|
+
if not isinstance(self.mailers, (Mailers, dict)):
|
|
56
|
+
raise OrionisIntegrityException(
|
|
57
|
+
"The 'mailers' property must be an instance of Mailers or a dictionary."
|
|
58
|
+
)
|
|
59
|
+
if isinstance(self.mailers, dict):
|
|
60
|
+
self.mailers = Mailers(**self.mailers)
|
|
@@ -1,15 +1,18 @@
|
|
|
1
|
-
from dataclasses import
|
|
1
|
+
from dataclasses import dataclass, field
|
|
2
2
|
from orionis.foundation.exceptions import OrionisIntegrityException
|
|
3
3
|
from orionis.foundation.config.mail.entities.file import File
|
|
4
4
|
from orionis.foundation.config.mail.entities.smtp import Smtp
|
|
5
|
+
from orionis.support.entities.base import BaseEntity
|
|
5
6
|
|
|
6
7
|
@dataclass(unsafe_hash=True, kw_only=True)
|
|
7
|
-
class Mailers:
|
|
8
|
+
class Mailers(BaseEntity):
|
|
8
9
|
"""
|
|
9
10
|
Represents the mail transport configurations for the application.
|
|
11
|
+
|
|
10
12
|
Attributes:
|
|
11
13
|
smtp (Smtp): The SMTP configuration used for sending emails.
|
|
12
14
|
file (File): The file-based mail transport configuration.
|
|
15
|
+
|
|
13
16
|
Methods:
|
|
14
17
|
__post_init__():
|
|
15
18
|
Validates that the 'smtp' and 'file' attributes are instances of their respective classes.
|
|
@@ -19,14 +22,20 @@ class Mailers:
|
|
|
19
22
|
Serializes the Mailers instance to a dictionary.
|
|
20
23
|
"""
|
|
21
24
|
|
|
22
|
-
smtp: Smtp = field(
|
|
23
|
-
default_factory=Smtp,
|
|
24
|
-
metadata={
|
|
25
|
+
smtp: Smtp | dict = field(
|
|
26
|
+
default_factory = lambda: Smtp(),
|
|
27
|
+
metadata = {
|
|
28
|
+
"description": "The SMTP configuration used for sending emails.",
|
|
29
|
+
"default": Smtp().toDict()
|
|
30
|
+
}
|
|
25
31
|
)
|
|
26
32
|
|
|
27
|
-
file: File = field(
|
|
28
|
-
default_factory=File,
|
|
29
|
-
metadata={
|
|
33
|
+
file: File | dict = field(
|
|
34
|
+
default_factory = lambda: File(),
|
|
35
|
+
metadata = {
|
|
36
|
+
"description": "The file-based mail transport configuration.",
|
|
37
|
+
"default": File().toDict()
|
|
38
|
+
}
|
|
30
39
|
)
|
|
31
40
|
|
|
32
41
|
def __post_init__(self):
|
|
@@ -34,43 +43,19 @@ class Mailers:
|
|
|
34
43
|
Post-initialization method to validate attribute types.
|
|
35
44
|
|
|
36
45
|
Ensures that the 'smtp' attribute is an instance of the Smtp class and the 'file' attribute is an instance of the File class.
|
|
46
|
+
|
|
37
47
|
Raises:
|
|
38
48
|
OrionisIntegrityException: If 'smtp' is not a Smtp object or 'file' is not a File object.
|
|
39
49
|
"""
|
|
40
50
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
if
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
dict: A dictionary containing all the fields of the instance.
|
|
53
|
-
"""
|
|
54
|
-
return asdict(self)
|
|
55
|
-
|
|
56
|
-
def getFields(self):
|
|
57
|
-
"""
|
|
58
|
-
Retrieves a list of field information for the current dataclass instance.
|
|
59
|
-
|
|
60
|
-
Returns:
|
|
61
|
-
list: A list of dictionaries, each containing details about a field:
|
|
62
|
-
- name (str): The name of the field.
|
|
63
|
-
- type (type): The type of the field.
|
|
64
|
-
- default: The default value of the field, if specified; otherwise, the value from metadata or None.
|
|
65
|
-
- metadata (mapping): The metadata associated with the field.
|
|
66
|
-
"""
|
|
67
|
-
__fields = []
|
|
68
|
-
for field in fields(self):
|
|
69
|
-
__metadata = dict(field.metadata) or {}
|
|
70
|
-
__fields.append({
|
|
71
|
-
"name": field.name,
|
|
72
|
-
"type": field.type.__name__ if hasattr(field.type, '__name__') else str(field.type),
|
|
73
|
-
"default": field.default if (field.default is not None and '_MISSING_TYPE' not in str(field.default)) else __metadata.get('default', None),
|
|
74
|
-
"metadata": __metadata
|
|
75
|
-
})
|
|
76
|
-
return __fields
|
|
51
|
+
# Validate `smtp` attribute
|
|
52
|
+
if not isinstance(self.smtp, (Smtp, dict)):
|
|
53
|
+
raise OrionisIntegrityException("The 'smtp' attribute must be a Smtp object or a dictionary.")
|
|
54
|
+
if isinstance(self.smtp, dict):
|
|
55
|
+
self.smtp = Smtp(**self.smtp)
|
|
56
|
+
|
|
57
|
+
# Validate `file` attribute
|
|
58
|
+
if not isinstance(self.file, (File, dict)):
|
|
59
|
+
raise OrionisIntegrityException("The 'file' attribute must be a File object or a dictionary.")
|
|
60
|
+
if isinstance(self.file, dict):
|
|
61
|
+
self.file = File(**self.file)
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
from dataclasses import
|
|
1
|
+
from dataclasses import dataclass, field
|
|
2
2
|
from typing import Optional
|
|
3
3
|
from orionis.foundation.exceptions import OrionisIntegrityException
|
|
4
|
+
from orionis.support.entities.base import BaseEntity
|
|
4
5
|
|
|
5
6
|
@dataclass(unsafe_hash=True, kw_only=True)
|
|
6
|
-
class Smtp:
|
|
7
|
+
class Smtp(BaseEntity):
|
|
7
8
|
"""
|
|
8
9
|
Represents the configuration for an SMTP (Simple Mail Transfer Protocol) server.
|
|
9
10
|
Attributes:
|
|
@@ -26,38 +27,59 @@ class Smtp:
|
|
|
26
27
|
"""
|
|
27
28
|
|
|
28
29
|
url: str = field(
|
|
29
|
-
default="smtp.mailtrap.io",
|
|
30
|
-
metadata={
|
|
30
|
+
default = "smtp.mailtrap.io",
|
|
31
|
+
metadata = {
|
|
32
|
+
"description": "The full URL for the SMTP service.",
|
|
33
|
+
"default": "smtp.mailtrap.io"
|
|
34
|
+
}
|
|
31
35
|
)
|
|
32
36
|
|
|
33
37
|
host: str = field(
|
|
34
|
-
default="smtp.mailtrap.io",
|
|
35
|
-
metadata={
|
|
38
|
+
default = "smtp.mailtrap.io",
|
|
39
|
+
metadata = {
|
|
40
|
+
"description": "The hostname of the SMTP server.",
|
|
41
|
+
"default": "smtp.mailtrap.io"
|
|
42
|
+
}
|
|
36
43
|
)
|
|
37
44
|
|
|
38
45
|
port: int = field(
|
|
39
|
-
default=587,
|
|
40
|
-
metadata={
|
|
46
|
+
default = 587,
|
|
47
|
+
metadata = {
|
|
48
|
+
"description": "The port number used for SMTP communication.",
|
|
49
|
+
"default": 587
|
|
50
|
+
}
|
|
41
51
|
)
|
|
42
52
|
|
|
43
53
|
encryption: str = field(
|
|
44
|
-
default="TLS",
|
|
45
|
-
metadata={
|
|
54
|
+
default = "TLS",
|
|
55
|
+
metadata = {
|
|
56
|
+
"description": "The encryption type used for secure communication.",
|
|
57
|
+
"default": "TLS"
|
|
58
|
+
}
|
|
46
59
|
)
|
|
47
60
|
|
|
48
61
|
username: str = field(
|
|
49
|
-
default="",
|
|
50
|
-
metadata={
|
|
62
|
+
default = "",
|
|
63
|
+
metadata = {
|
|
64
|
+
"description": "The username for authentication with the SMTP server.",
|
|
65
|
+
"default": ""
|
|
66
|
+
}
|
|
51
67
|
)
|
|
52
68
|
|
|
53
69
|
password: str = field(
|
|
54
|
-
default="",
|
|
55
|
-
metadata={
|
|
70
|
+
default = "",
|
|
71
|
+
metadata = {
|
|
72
|
+
"description": "The password for authentication with the SMTP server.",
|
|
73
|
+
"default": ""
|
|
74
|
+
}
|
|
56
75
|
)
|
|
57
76
|
|
|
58
77
|
timeout: Optional[int] = field(
|
|
59
|
-
default=None,
|
|
60
|
-
metadata={
|
|
78
|
+
default = None,
|
|
79
|
+
metadata = {
|
|
80
|
+
"description": "The connection timeout duration in seconds.",
|
|
81
|
+
"default": None
|
|
82
|
+
}
|
|
61
83
|
)
|
|
62
84
|
|
|
63
85
|
def __post_init__(self):
|
|
@@ -73,54 +95,31 @@ class Smtp:
|
|
|
73
95
|
Raises:
|
|
74
96
|
OrionisIntegrityException: If any attribute fails its validation check.
|
|
75
97
|
"""
|
|
98
|
+
|
|
99
|
+
# Validate `url` attribute
|
|
76
100
|
if not isinstance(self.url, str):
|
|
77
101
|
raise OrionisIntegrityException("The 'url' attribute must be a string.")
|
|
78
102
|
|
|
103
|
+
# Validate `host` attribute
|
|
79
104
|
if not isinstance(self.host, str):
|
|
80
105
|
raise OrionisIntegrityException("The 'host' attribute must be a string.")
|
|
81
106
|
|
|
107
|
+
# Validate `port` attribute
|
|
82
108
|
if not isinstance(self.port, int) or self.port < 0:
|
|
83
109
|
raise OrionisIntegrityException("The 'port' attribute must be a non-negative integer.")
|
|
84
110
|
|
|
111
|
+
# Validate `encryption` attribute
|
|
85
112
|
if not isinstance(self.encryption, str):
|
|
86
113
|
raise OrionisIntegrityException("The 'encryption' attribute must be a string.")
|
|
87
114
|
|
|
115
|
+
# Validate `username` attribute
|
|
88
116
|
if not isinstance(self.username, str):
|
|
89
117
|
raise OrionisIntegrityException("The 'username' attribute must be a string.")
|
|
90
118
|
|
|
119
|
+
# Validate `password` attribute
|
|
91
120
|
if not isinstance(self.password, str):
|
|
92
121
|
raise OrionisIntegrityException("The 'password' attribute must be a string.")
|
|
93
122
|
|
|
123
|
+
# Validate `timeout` attribute
|
|
94
124
|
if self.timeout is not None and (not isinstance(self.timeout, int) or self.timeout < 0):
|
|
95
|
-
raise OrionisIntegrityException("The 'timeout' attribute must be a non-negative integer or None.")
|
|
96
|
-
|
|
97
|
-
def toDict(self) -> dict:
|
|
98
|
-
"""
|
|
99
|
-
Converts the current instance into a dictionary representation.
|
|
100
|
-
|
|
101
|
-
Returns:
|
|
102
|
-
dict: A dictionary containing all the fields of the instance.
|
|
103
|
-
"""
|
|
104
|
-
return asdict(self)
|
|
105
|
-
|
|
106
|
-
def getFields(self):
|
|
107
|
-
"""
|
|
108
|
-
Retrieves a list of field information for the current dataclass instance.
|
|
109
|
-
|
|
110
|
-
Returns:
|
|
111
|
-
list: A list of dictionaries, each containing details about a field:
|
|
112
|
-
- name (str): The name of the field.
|
|
113
|
-
- type (type): The type of the field.
|
|
114
|
-
- default: The default value of the field, if specified; otherwise, the value from metadata or None.
|
|
115
|
-
- metadata (mapping): The metadata associated with the field.
|
|
116
|
-
"""
|
|
117
|
-
__fields = []
|
|
118
|
-
for field in fields(self):
|
|
119
|
-
__metadata = dict(field.metadata) or {}
|
|
120
|
-
__fields.append({
|
|
121
|
-
"name": field.name,
|
|
122
|
-
"type": field.type.__name__ if hasattr(field.type, '__name__') else str(field.type),
|
|
123
|
-
"default": field.default if (field.default is not None and '_MISSING_TYPE' not in str(field.default)) else __metadata.get('default', None),
|
|
124
|
-
"metadata": __metadata
|
|
125
|
-
})
|
|
126
|
-
return __fields
|
|
125
|
+
raise OrionisIntegrityException("The 'timeout' attribute must be a non-negative integer or None.")
|
|
@@ -1,15 +1,18 @@
|
|
|
1
1
|
|
|
2
|
-
from dataclasses import
|
|
2
|
+
from dataclasses import dataclass, field
|
|
3
3
|
from orionis.foundation.exceptions import OrionisIntegrityException
|
|
4
4
|
from orionis.foundation.config.queue.entities.database import Database
|
|
5
|
+
from orionis.support.entities.base import BaseEntity
|
|
5
6
|
|
|
6
7
|
@dataclass(unsafe_hash=True, kw_only=True)
|
|
7
|
-
class Brokers:
|
|
8
|
+
class Brokers(BaseEntity):
|
|
8
9
|
"""
|
|
9
10
|
Represents the configuration for queue brokers.
|
|
11
|
+
|
|
10
12
|
Attributes:
|
|
11
13
|
sync (bool): Indicates if the sync broker is enabled. Defaults to True.
|
|
12
14
|
database (Database): The configuration for the database-backed queue. Defaults to a new Database instance.
|
|
15
|
+
|
|
13
16
|
Methods:
|
|
14
17
|
__post_init__():
|
|
15
18
|
Validates and normalizes the properties after initialization.
|
|
@@ -17,61 +20,36 @@ class Brokers:
|
|
|
17
20
|
"""
|
|
18
21
|
|
|
19
22
|
sync: bool = field(
|
|
20
|
-
default=True,
|
|
21
|
-
metadata={
|
|
23
|
+
default = True,
|
|
24
|
+
metadata = {
|
|
22
25
|
"description": "Indicates if the sync broker is enabled.",
|
|
23
26
|
"default": True
|
|
24
27
|
}
|
|
25
28
|
)
|
|
26
29
|
|
|
27
|
-
database: Database = field(
|
|
28
|
-
default_factory=Database,
|
|
29
|
-
metadata={
|
|
30
|
+
database: Database | dict = field(
|
|
31
|
+
default_factory = lambda: Database(),
|
|
32
|
+
metadata = {
|
|
30
33
|
"description": "The configuration for the database-backed queue.",
|
|
31
|
-
"default":
|
|
34
|
+
"default": Database().toDict()
|
|
32
35
|
}
|
|
33
36
|
)
|
|
34
37
|
|
|
35
38
|
def __post_init__(self):
|
|
36
39
|
"""
|
|
37
40
|
Post-initialization validation for the Brokers entity.
|
|
41
|
+
|
|
38
42
|
Validates and normalizes the following properties:
|
|
39
43
|
- sync: Must be a boolean.
|
|
40
44
|
- database: Must be an instance of the Database class.
|
|
41
45
|
"""
|
|
46
|
+
|
|
47
|
+
# Validate 'sync' property
|
|
42
48
|
if not isinstance(self.sync, bool):
|
|
43
49
|
raise OrionisIntegrityException("sync must be a boolean.")
|
|
44
50
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
Converts the current instance into a dictionary representation.
|
|
51
|
-
|
|
52
|
-
Returns:
|
|
53
|
-
dict: A dictionary containing all the fields of the instance.
|
|
54
|
-
"""
|
|
55
|
-
return asdict(self)
|
|
56
|
-
|
|
57
|
-
def getFields(self):
|
|
58
|
-
"""
|
|
59
|
-
Retrieves a list of field information for the current dataclass instance.
|
|
60
|
-
|
|
61
|
-
Returns:
|
|
62
|
-
list: A list of dictionaries, each containing details about a field:
|
|
63
|
-
- name (str): The name of the field.
|
|
64
|
-
- type (type): The type of the field.
|
|
65
|
-
- default: The default value of the field, if specified; otherwise, the value from metadata or None.
|
|
66
|
-
- metadata (mapping): The metadata associated with the field.
|
|
67
|
-
"""
|
|
68
|
-
__fields = []
|
|
69
|
-
for field in fields(self):
|
|
70
|
-
__metadata = dict(field.metadata) or {}
|
|
71
|
-
__fields.append({
|
|
72
|
-
"name": field.name,
|
|
73
|
-
"type": field.type.__name__ if hasattr(field.type, '__name__') else str(field.type),
|
|
74
|
-
"default": field.default if (field.default is not None and '_MISSING_TYPE' not in str(field.default)) else __metadata.get('default', None),
|
|
75
|
-
"metadata": __metadata
|
|
76
|
-
})
|
|
77
|
-
return __fields
|
|
51
|
+
# Validate 'database' property
|
|
52
|
+
if not isinstance(self.database, (Database, dict)):
|
|
53
|
+
raise OrionisIntegrityException("database must be an instance of the Database class or a dictionary.")
|
|
54
|
+
if isinstance(self.database, dict):
|
|
55
|
+
self.database = Database(**self.database)
|
|
@@ -1,18 +1,21 @@
|
|
|
1
1
|
|
|
2
|
-
from dataclasses import
|
|
2
|
+
from dataclasses import dataclass, field
|
|
3
3
|
from orionis.foundation.exceptions import OrionisIntegrityException
|
|
4
4
|
from orionis.foundation.config.queue.enums import Strategy
|
|
5
|
+
from orionis.support.entities.base import BaseEntity
|
|
5
6
|
import re
|
|
6
7
|
|
|
7
8
|
@dataclass(unsafe_hash=True, kw_only=True)
|
|
8
|
-
class Database:
|
|
9
|
+
class Database(BaseEntity):
|
|
9
10
|
"""
|
|
10
11
|
Represents the configuration entity for a database-backed queue.
|
|
12
|
+
|
|
11
13
|
Attributes:
|
|
12
14
|
table (str): The name of the table used for the queue. Must match the pattern `[a-z_][a-z_]*` (lowercase letters or underscores only, no numbers).
|
|
13
15
|
queue (str): The name of the queue. Must contain only ASCII characters.
|
|
14
16
|
retry_after (int): The time in seconds to wait before retrying a failed job. Must be a positive integer.
|
|
15
17
|
strategy (str | Strategy): The strategy used for the queue. Options are FIFO, LIFO, or PRIORITY. Can be provided as a string (case-insensitive) or as a `Strategy` enum member.
|
|
18
|
+
|
|
16
19
|
Methods:
|
|
17
20
|
__post_init__():
|
|
18
21
|
Validates and normalizes the entity's properties after initialization.
|
|
@@ -23,49 +26,52 @@ class Database:
|
|
|
23
26
|
"""
|
|
24
27
|
|
|
25
28
|
table: str = field(
|
|
26
|
-
default="jobs",
|
|
27
|
-
metadata={
|
|
29
|
+
default = "jobs",
|
|
30
|
+
metadata = {
|
|
28
31
|
"description": "The name of the table used for the queue.",
|
|
29
|
-
"default": "jobs"
|
|
32
|
+
"default": "jobs"
|
|
30
33
|
}
|
|
31
34
|
)
|
|
32
35
|
|
|
33
36
|
queue: str = field(
|
|
34
|
-
default="default",
|
|
35
|
-
metadata={
|
|
37
|
+
default = "default",
|
|
38
|
+
metadata = {
|
|
36
39
|
"description": "The name of the queue.",
|
|
37
|
-
"default": "default"
|
|
40
|
+
"default": "default"
|
|
38
41
|
}
|
|
39
42
|
)
|
|
40
43
|
|
|
41
44
|
retry_after: int = field(
|
|
42
|
-
default=90,
|
|
43
|
-
metadata={
|
|
45
|
+
default = 90,
|
|
46
|
+
metadata = {
|
|
44
47
|
"description": "The time in seconds to wait before retrying a failed job.",
|
|
45
|
-
"default": 90
|
|
48
|
+
"default": 90
|
|
46
49
|
}
|
|
47
50
|
)
|
|
48
51
|
|
|
49
52
|
strategy : str | Strategy = field(
|
|
50
|
-
default=Strategy.FIFO,
|
|
51
|
-
metadata={
|
|
53
|
+
default = Strategy.FIFO.value,
|
|
54
|
+
metadata = {
|
|
52
55
|
"description": "The strategy used for the queue. Options are FIFO, LIFO, or PRIORITY.",
|
|
53
|
-
"default":
|
|
56
|
+
"default": Strategy.FIFO.value
|
|
54
57
|
}
|
|
55
58
|
)
|
|
56
59
|
|
|
57
60
|
def __post_init__(self):
|
|
58
61
|
"""
|
|
59
62
|
Post-initialization validation for the entity.
|
|
63
|
+
|
|
60
64
|
Validates and normalizes the following properties:
|
|
61
65
|
- `table`: Must be a string matching the pattern `[a-z_][a-z_]*` (lowercase letters or underscores only, no numbers).
|
|
62
66
|
- `queue`: Must be a string containing only ASCII characters.
|
|
63
67
|
- `retry_after`: Must be a positive integer.
|
|
64
68
|
- `strategy`: Must be either a string (matching a valid `Strategy` member name, case-insensitive) or an instance of `Strategy`. Converts the value to the corresponding `Strategy` enum value.
|
|
69
|
+
|
|
65
70
|
Raises:
|
|
66
71
|
OrionisIntegrityException: If any property fails validation.
|
|
67
72
|
"""
|
|
68
73
|
|
|
74
|
+
# Validate `table` attribute
|
|
69
75
|
if not isinstance(self.table, str):
|
|
70
76
|
raise OrionisIntegrityException("The 'table' property must be a string.")
|
|
71
77
|
if not re.fullmatch(r'[a-z_][a-z_]*', self.table):
|
|
@@ -73,6 +79,7 @@ class Database:
|
|
|
73
79
|
"The 'table' property must be a valid table name: start with a lowercase letter or underscore, contain only lowercase letters or underscores (no numbers allowed)."
|
|
74
80
|
)
|
|
75
81
|
|
|
82
|
+
# Validate `queue` attribute
|
|
76
83
|
if not isinstance(self.queue, str):
|
|
77
84
|
raise OrionisIntegrityException("The 'queue' property must be a string.")
|
|
78
85
|
try:
|
|
@@ -80,9 +87,11 @@ class Database:
|
|
|
80
87
|
except UnicodeEncodeError:
|
|
81
88
|
raise OrionisIntegrityException("The 'queue' property must contain only ASCII characters (no UTF-8 or non-ASCII allowed).")
|
|
82
89
|
|
|
90
|
+
# Validate `retry_after` attribute
|
|
83
91
|
if not isinstance(self.retry_after, int) or self.retry_after <= 0:
|
|
84
92
|
raise OrionisIntegrityException("The 'retry_after' property must be a positive integer.")
|
|
85
93
|
|
|
94
|
+
# Validate `strategy` attribute
|
|
86
95
|
if not isinstance(self.strategy, (str, Strategy)):
|
|
87
96
|
raise OrionisIntegrityException("The 'strategy' property must be a string or an instance of Strategy.")
|
|
88
97
|
if isinstance(self.strategy, str):
|
|
@@ -95,35 +104,4 @@ class Database:
|
|
|
95
104
|
else:
|
|
96
105
|
self.strategy = Strategy[_value].value
|
|
97
106
|
else:
|
|
98
|
-
self.strategy = self.strategy.value
|
|
99
|
-
|
|
100
|
-
def toDict(self) -> dict:
|
|
101
|
-
"""
|
|
102
|
-
Converts the current instance into a dictionary representation.
|
|
103
|
-
|
|
104
|
-
Returns:
|
|
105
|
-
dict: A dictionary containing all the fields of the instance.
|
|
106
|
-
"""
|
|
107
|
-
return asdict(self)
|
|
108
|
-
|
|
109
|
-
def getFields(self):
|
|
110
|
-
"""
|
|
111
|
-
Retrieves a list of field information for the current dataclass instance.
|
|
112
|
-
|
|
113
|
-
Returns:
|
|
114
|
-
list: A list of dictionaries, each containing details about a field:
|
|
115
|
-
- name (str): The name of the field.
|
|
116
|
-
- type (type): The type of the field.
|
|
117
|
-
- default: The default value of the field, if specified; otherwise, the value from metadata or None.
|
|
118
|
-
- metadata (mapping): The metadata associated with the field.
|
|
119
|
-
"""
|
|
120
|
-
__fields = []
|
|
121
|
-
for field in fields(self):
|
|
122
|
-
__metadata = dict(field.metadata) or {}
|
|
123
|
-
__fields.append({
|
|
124
|
-
"name": field.name,
|
|
125
|
-
"type": field.type.__name__ if hasattr(field.type, '__name__') else str(field.type),
|
|
126
|
-
"default": field.default if (field.default is not None and '_MISSING_TYPE' not in str(field.default)) else __metadata.get('default', None),
|
|
127
|
-
"metadata": __metadata
|
|
128
|
-
})
|
|
129
|
-
return __fields
|
|
107
|
+
self.strategy = self.strategy.value
|