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.
Files changed (165) hide show
  1. orionis/console/base/command.py +57 -50
  2. orionis/console/base/contracts/command.py +68 -0
  3. orionis/console/dynamic/contracts/progress_bar.py +3 -3
  4. orionis/console/dynamic/progress_bar.py +8 -8
  5. orionis/console/output/console.py +8 -2
  6. orionis/console/output/contracts/console.py +1 -1
  7. orionis/container/container.py +2 -2
  8. orionis/container/context/scope.py +4 -1
  9. orionis/container/contracts/service_provider.py +2 -2
  10. orionis/container/entities/binding.py +31 -44
  11. orionis/container/enums/lifetimes.py +22 -1
  12. orionis/container/facades/facade.py +1 -2
  13. orionis/container/providers/service_provider.py +2 -2
  14. orionis/foundation/application.py +542 -248
  15. orionis/foundation/config/app/entities/app.py +107 -90
  16. orionis/foundation/config/auth/entities/auth.py +4 -33
  17. orionis/foundation/config/cache/entities/cache.py +18 -41
  18. orionis/foundation/config/cache/entities/file.py +8 -35
  19. orionis/foundation/config/cache/entities/stores.py +17 -38
  20. orionis/foundation/config/cors/entities/cors.py +41 -54
  21. orionis/foundation/config/database/entities/connections.py +40 -56
  22. orionis/foundation/config/database/entities/database.py +11 -38
  23. orionis/foundation/config/database/entities/mysql.py +48 -76
  24. orionis/foundation/config/database/entities/oracle.py +30 -57
  25. orionis/foundation/config/database/entities/pgsql.py +45 -61
  26. orionis/foundation/config/database/entities/sqlite.py +26 -53
  27. orionis/foundation/config/filesystems/entitites/aws.py +28 -49
  28. orionis/foundation/config/filesystems/entitites/disks.py +27 -47
  29. orionis/foundation/config/filesystems/entitites/filesystems.py +15 -37
  30. orionis/foundation/config/filesystems/entitites/local.py +9 -35
  31. orionis/foundation/config/filesystems/entitites/public.py +14 -41
  32. orionis/foundation/config/logging/entities/channels.py +56 -86
  33. orionis/foundation/config/logging/entities/chunked.py +18 -10
  34. orionis/foundation/config/logging/entities/daily.py +17 -9
  35. orionis/foundation/config/logging/entities/hourly.py +15 -7
  36. orionis/foundation/config/logging/entities/logging.py +12 -18
  37. orionis/foundation/config/logging/entities/monthly.py +16 -8
  38. orionis/foundation/config/logging/entities/stack.py +15 -7
  39. orionis/foundation/config/logging/entities/weekly.py +15 -7
  40. orionis/foundation/config/logging/validators/path.py +6 -0
  41. orionis/foundation/config/mail/entities/file.py +9 -36
  42. orionis/foundation/config/mail/entities/mail.py +22 -40
  43. orionis/foundation/config/mail/entities/mailers.py +29 -44
  44. orionis/foundation/config/mail/entities/smtp.py +47 -48
  45. orionis/foundation/config/queue/entities/brokers.py +19 -41
  46. orionis/foundation/config/queue/entities/database.py +24 -46
  47. orionis/foundation/config/queue/entities/queue.py +28 -40
  48. orionis/foundation/config/roots/paths.py +272 -468
  49. orionis/foundation/config/session/entities/session.py +23 -53
  50. orionis/foundation/config/startup.py +165 -135
  51. orionis/foundation/config/testing/entities/testing.py +137 -122
  52. orionis/foundation/config/testing/enums/__init__.py +6 -2
  53. orionis/foundation/config/testing/enums/drivers.py +16 -0
  54. orionis/foundation/config/testing/enums/verbosity.py +18 -0
  55. orionis/foundation/contracts/application.py +152 -362
  56. orionis/foundation/providers/console_provider.py +24 -2
  57. orionis/foundation/providers/dumper_provider.py +24 -2
  58. orionis/foundation/providers/logger_provider.py +24 -2
  59. orionis/foundation/providers/path_resolver_provider.py +25 -2
  60. orionis/foundation/providers/progress_bar_provider.py +24 -2
  61. orionis/foundation/providers/testing_provider.py +39 -0
  62. orionis/foundation/providers/workers_provider.py +24 -2
  63. orionis/metadata/framework.py +1 -1
  64. orionis/services/environment/helpers/functions.py +1 -2
  65. orionis/services/environment/key/__init__.py +0 -0
  66. orionis/services/environment/key/key_generator.py +37 -0
  67. orionis/services/log/handlers/filename.py +64 -0
  68. orionis/services/log/handlers/size_rotating.py +9 -40
  69. orionis/services/log/handlers/timed_rotating.py +9 -41
  70. orionis/services/log/log_service.py +9 -52
  71. orionis/support/entities/__init__.py +0 -0
  72. orionis/support/entities/base.py +104 -0
  73. orionis/support/facades/testing.py +15 -0
  74. orionis/support/facades/workers.py +1 -1
  75. orionis/test/cases/asynchronous.py +0 -11
  76. orionis/test/cases/synchronous.py +0 -9
  77. orionis/test/contracts/dumper.py +11 -4
  78. orionis/test/contracts/kernel.py +5 -110
  79. orionis/test/contracts/logs.py +27 -65
  80. orionis/test/contracts/printer.py +16 -128
  81. orionis/test/contracts/test_result.py +100 -0
  82. orionis/test/contracts/unit_test.py +87 -150
  83. orionis/test/core/unit_test.py +608 -554
  84. orionis/test/entities/result.py +22 -2
  85. orionis/test/enums/__init__.py +0 -2
  86. orionis/test/enums/status.py +14 -9
  87. orionis/test/exceptions/config.py +9 -1
  88. orionis/test/exceptions/failure.py +34 -11
  89. orionis/test/exceptions/persistence.py +10 -2
  90. orionis/test/exceptions/runtime.py +9 -1
  91. orionis/test/exceptions/value.py +13 -1
  92. orionis/test/kernel.py +87 -289
  93. orionis/test/output/dumper.py +82 -18
  94. orionis/test/output/printer.py +399 -156
  95. orionis/test/records/logs.py +203 -82
  96. orionis/test/validators/__init__.py +33 -0
  97. orionis/test/validators/base_path.py +45 -0
  98. orionis/test/validators/execution_mode.py +45 -0
  99. orionis/test/validators/fail_fast.py +37 -0
  100. orionis/test/validators/folder_path.py +34 -0
  101. orionis/test/validators/module_name.py +31 -0
  102. orionis/test/validators/name_pattern.py +40 -0
  103. orionis/test/validators/pattern.py +36 -0
  104. orionis/test/validators/persistent.py +42 -0
  105. orionis/test/validators/persistent_driver.py +43 -0
  106. orionis/test/validators/print_result.py +37 -0
  107. orionis/test/validators/tags.py +37 -0
  108. orionis/test/validators/throw_exception.py +39 -0
  109. orionis/test/validators/verbosity.py +37 -0
  110. orionis/test/validators/web_report.py +35 -0
  111. orionis/test/validators/workers.py +31 -0
  112. orionis/test/view/render.py +48 -54
  113. {orionis-0.404.0.dist-info → orionis-0.406.0.dist-info}/METADATA +1 -1
  114. {orionis-0.404.0.dist-info → orionis-0.406.0.dist-info}/RECORD +160 -108
  115. tests/container/__init__.py +0 -0
  116. tests/container/context/__init__.py +0 -0
  117. tests/container/context/test_manager.py +27 -0
  118. tests/container/context/test_scope.py +23 -0
  119. tests/container/entities/__init__.py +0 -0
  120. tests/container/entities/test_binding.py +133 -0
  121. tests/container/enums/__init__.py +0 -0
  122. tests/container/enums/test_lifetimes.py +63 -0
  123. tests/container/facades/__init__.py +0 -0
  124. tests/container/facades/test_facade.py +61 -0
  125. tests/container/mocks/__init__.py +0 -0
  126. tests/container/mocks/mock_complex_classes.py +482 -0
  127. tests/container/mocks/mock_simple_classes.py +32 -0
  128. tests/container/providers/__init__.py +0 -0
  129. tests/container/providers/test_providers.py +48 -0
  130. tests/container/resolver/__init__.py +0 -0
  131. tests/container/resolver/test_resolver.py +55 -0
  132. tests/container/test_container.py +254 -0
  133. tests/container/test_singleton.py +98 -0
  134. tests/container/test_thread_safety.py +217 -0
  135. tests/container/validators/__init__.py +0 -0
  136. tests/container/validators/test_implements.py +140 -0
  137. tests/container/validators/test_is_abstract_class.py +99 -0
  138. tests/container/validators/test_is_callable.py +73 -0
  139. tests/container/validators/test_is_concrete_class.py +97 -0
  140. tests/container/validators/test_is_instance.py +105 -0
  141. tests/container/validators/test_is_not_subclass.py +117 -0
  142. tests/container/validators/test_is_subclass.py +115 -0
  143. tests/container/validators/test_is_valid_alias.py +113 -0
  144. tests/container/validators/test_lifetime.py +75 -0
  145. tests/foundation/config/logging/test_foundation_config_logging_chunked.py +12 -34
  146. tests/foundation/config/logging/test_foundation_config_logging_daily.py +11 -11
  147. tests/foundation/config/logging/test_foundation_config_logging_hourly.py +7 -8
  148. tests/foundation/config/logging/test_foundation_config_logging_monthly.py +7 -10
  149. tests/foundation/config/logging/test_foundation_config_logging_stack.py +6 -11
  150. tests/foundation/config/logging/test_foundation_config_logging_weekly.py +6 -5
  151. tests/foundation/config/testing/test_foundation_config_testing.py +1 -1
  152. tests/metadata/test_metadata_framework.py +18 -18
  153. tests/testing/test_testing_result.py +117 -117
  154. tests/testing/test_testing_unit.py +209 -209
  155. orionis/foundation/config/base.py +0 -112
  156. orionis/test/arguments/parser.py +0 -187
  157. orionis/test/contracts/parser.py +0 -43
  158. orionis/test/entities/arguments.py +0 -38
  159. orionis/test/enums/execution_mode.py +0 -16
  160. /orionis/{test/arguments → console/base/contracts}/__init__.py +0 -0
  161. /orionis/foundation/config/testing/enums/{test_mode.py → mode.py} +0 -0
  162. {orionis-0.404.0.dist-info → orionis-0.406.0.dist-info}/WHEEL +0 -0
  163. {orionis-0.404.0.dist-info → orionis-0.406.0.dist-info}/licenses/LICENCE +0 -0
  164. {orionis-0.404.0.dist-info → orionis-0.406.0.dist-info}/top_level.txt +0 -0
  165. {orionis-0.404.0.dist-info → orionis-0.406.0.dist-info}/zip-safe +0 -0
@@ -1,8 +1,9 @@
1
- from dataclasses import asdict, dataclass, field, fields
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={"description": "The file path where outgoing emails are stored."}
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 asdict, dataclass, field, fields
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={"description": "The default mailer transport to use."}
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={"description": "The available mail transport configurations."}
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
- if not isinstance(self.mailers, Mailers):
47
- raise OrionisIntegrityException("The 'mailers' attribute must be a Mailers object.")
48
-
49
- def toDict(self) -> dict:
50
- """
51
- Converts the current instance into a dictionary representation.
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 asdict, dataclass, field, fields
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={"description": "The SMTP configuration used for sending emails."}
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={"description": "The file-based mail transport configuration."}
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
- if not isinstance(self.smtp, Smtp):
42
- raise OrionisIntegrityException("The 'smtp' attribute must be a Smtp object.")
43
-
44
- if not isinstance(self.file, File):
45
- raise OrionisIntegrityException("The 'file' attribute must be a File object.")
46
-
47
- def toDict(self) -> dict:
48
- """
49
- Converts the current instance into a dictionary representation.
50
-
51
- Returns:
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 asdict, dataclass, field, fields
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={"description": "The full URL for the SMTP service."}
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={"description": "The hostname of the SMTP server."}
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={"description": "The port number used for SMTP communication."}
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={"description": "The encryption type used for secure communication."}
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={"description": "The username for authentication with the SMTP server."}
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={"description": "The password for authentication with the SMTP server."}
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={"description": "The connection timeout duration in seconds."}
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 asdict, dataclass, field, fields
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": "Database()"
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
- if not isinstance(self.database, Database):
46
- raise OrionisIntegrityException("database must be an instance of the Database class.")
47
-
48
- def toDict(self) -> dict:
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 asdict, dataclass, field, fields
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": "Strategy.FIFO",
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