orionis 0.616.0__py3-none-any.whl → 0.618.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.
@@ -24,34 +24,6 @@ class BaseCommand(Console, ProgressBar, IBaseCommand):
24
24
 
25
25
  The class integrates with the framework's console and progress bar systems,
26
26
  allowing commands to provide rich user feedback during execution.
27
-
28
- Attributes
29
- ----------
30
- timestamps : bool, default True
31
- Controls whether timestamps are included in console output messages.
32
- When True, all console output will be prefixed with timestamp information.
33
- signature : str
34
- Defines the command signature string used for command registration and
35
- automatic help text generation. This should follow the framework's
36
- signature format conventions.
37
- description : str
38
- Human-readable description of the command's purpose and functionality.
39
- Used in help documentation and command listing interfaces.
40
- _args : Dict[str, Any], default {}
41
- Dictionary containing parsed command-line arguments and options.
42
- Populated automatically by the command parser before handle() execution.
43
- arguments : List[CLIArgument], default []
44
- List of CLIArgument instances defining the command's accepted arguments
45
- and options. Used for argument parsing and validation.
46
-
47
- Methods
48
- -------
49
- handle()
50
- Abstract method that must be implemented by subclasses to define the
51
- main command execution logic.
52
- argument(key: str)
53
- Safely retrieves argument values from the parsed arguments dictionary
54
- with type validation and error handling.
55
27
  """
56
28
 
57
29
  # Enable timestamps in console output by default
@@ -64,12 +36,43 @@ class BaseCommand(Console, ProgressBar, IBaseCommand):
64
36
  description: str
65
37
 
66
38
  # Dictionary to store parsed command-line arguments and options
67
- _args: Dict[str, Any] = {}
39
+ __args: Dict[str, Any] = {}
40
+
41
+ async def options(self) -> List[CLIArgument]:
42
+ """
43
+ Defines the command-line arguments and options accepted by the command.
44
+
45
+ This asynchronous method should be overridden by subclasses to specify the list of
46
+ command-line arguments and options that the command supports. Each argument or option
47
+ should be represented as a CLIArgument object, which encapsulates details such as the
48
+ argument's name, type, default value, and help description.
49
+
50
+ This method enables the framework to automatically parse, validate, and document
51
+ the available arguments for each command, ensuring consistent user experience
52
+ across all commands.
53
+
54
+ Parameters
55
+ ----------
56
+ None
57
+
58
+ Returns
59
+ -------
60
+ List
61
+ A list of CLIArgument objects, where each object describes a single
62
+ command-line argument or option accepted by the command. If the command
63
+ does not accept any arguments or options, an empty list is returned.
68
64
 
69
- # List of CLIArgument instances defining command arguments
70
- arguments: List[CLIArgument] = []
65
+ Notes
66
+ -----
67
+ Subclasses should override this method to declare their specific arguments.
68
+ The returned list is used by the framework for argument parsing and help
69
+ text generation.
70
+ """
71
71
 
72
- def handle(self):
72
+ # Return an empty list by default; subclasses should override to provide arguments
73
+ return []
74
+
75
+ async def handle(self):
73
76
  """
74
77
  Execute the main command logic.
75
78
 
@@ -99,6 +102,70 @@ class BaseCommand(Console, ProgressBar, IBaseCommand):
99
102
  # Raise an error to enforce implementation in subclasses
100
103
  raise NotImplementedError("The 'handle' method must be implemented in the subclass.")
101
104
 
105
+ def setArguments(self, args: Dict[str, Any]) -> None:
106
+ """
107
+ Populate the internal arguments dictionary with parsed command-line arguments and options.
108
+
109
+ This method is intended for internal use by the command parsing mechanism to initialize
110
+ the internal arguments state before command execution. It assigns the provided dictionary
111
+ of arguments and options to the internal storage, making them accessible via the
112
+ `argument()` and `arguments()` methods.
113
+
114
+ Parameters
115
+ ----------
116
+ args : Dict[str, Any]
117
+ Dictionary containing parsed command-line arguments and options, where each key
118
+ represents an argument name and each value is the corresponding argument value.
119
+
120
+ Returns
121
+ -------
122
+ None
123
+ This method does not return any value. It updates the internal state of the command
124
+ instance to reflect the provided arguments.
125
+
126
+ Raises
127
+ ------
128
+ ValueError
129
+ If the provided `args` parameter is not a dictionary.
130
+
131
+ Notes
132
+ -----
133
+ This method is automatically invoked by the command framework prior to the execution
134
+ of the `handle()` method. It should not be called directly by command implementations.
135
+ """
136
+
137
+ # Ensure the provided arguments are in dictionary form
138
+ if not isinstance(args, dict):
139
+ raise ValueError(f"Arguments must be a dictionary, got '{type(args).__name__}' instead.")
140
+
141
+ # Store the parsed arguments internally for later retrieval
142
+ self.__args = args
143
+
144
+ def arguments(self) -> Dict[str, Any]:
145
+ """
146
+ Retrieve the entire dictionary of parsed command-line arguments and options.
147
+
148
+ This method provides access to all arguments and options that have been parsed
149
+ and stored internally for the current command execution. It is useful for
150
+ scenarios where bulk access to all argument values is required, such as
151
+ dynamic processing or debugging.
152
+
153
+ Returns
154
+ -------
155
+ Dict[str, Any]
156
+ A dictionary containing all parsed command-line arguments and options,
157
+ where each key is the argument name and each value is the corresponding
158
+ argument value.
159
+
160
+ Notes
161
+ -----
162
+ The returned dictionary reflects the current state of the command's arguments.
163
+ Modifying the returned dictionary will affect the internal state of the command.
164
+ """
165
+
166
+ # Return the internal dictionary containing all parsed arguments and options
167
+ return self.__args
168
+
102
169
  def argument(self, key: str, default: Any = None) -> Any:
103
170
  """
104
171
  Retrieve the value of a specific command-line argument by key with optional default fallback.
@@ -131,7 +198,7 @@ class BaseCommand(Console, ProgressBar, IBaseCommand):
131
198
  ValueError
132
199
  If the provided key parameter is not of string type.
133
200
  ValueError
134
- If the internal _args attribute is not of dictionary type, indicating
201
+ If the internal __args attribute is not of dictionary type, indicating
135
202
  a corrupted or improperly initialized command state.
136
203
  """
137
204
 
@@ -140,8 +207,8 @@ class BaseCommand(Console, ProgressBar, IBaseCommand):
140
207
  raise ValueError(f"Argument key must be a string, got '{type(key).__name__}' instead.")
141
208
 
142
209
  # Ensure the internal args attribute is a valid dictionary
143
- if not isinstance(self._args, dict):
144
- raise ValueError(f"Arguments must be a dictionary, got '{type(self._args).__name__}' instead.")
210
+ if not isinstance(self.__args, dict):
211
+ raise ValueError(f"Arguments must be a dictionary, got '{type(self.__args).__name__}' instead.")
145
212
 
146
213
  # Safely retrieve the argument value with optional default fallback
147
- return self._args.get(key, default)
214
+ return self.__args.get(key, default)
@@ -15,51 +15,6 @@ class IBaseCommand(ABC):
15
15
  ensuring all commands follow a uniform pattern for registration, execution,
16
16
  and user interaction while maintaining flexibility for specific command logic
17
17
  implementation.
18
-
19
- Attributes
20
- ----------
21
- timestamps : bool, default=True
22
- Controls whether timestamps are displayed in console output. When enabled,
23
- all console messages will include timestamp prefixes for better debugging
24
- and logging capabilities.
25
- signature : str
26
- The command signature string that defines the command name and expected
27
- arguments format. Used for command registration in the console system
28
- and automatic help text generation. Must follow the framework's signature
29
- format conventions.
30
- description : str
31
- Human-readable description explaining the command's purpose and functionality.
32
- This text is displayed in help documentation, command listings, and usage
33
- instructions to assist users in understanding the command's capabilities.
34
- _args : Dict[str, Any]
35
- Dictionary containing parsed command-line arguments and options passed to
36
- the command during execution. Populated automatically by the command parser
37
- before the handle() method is called, providing structured access to all
38
- user-provided input parameters.
39
- arguments : List[CLIArgument]
40
- List of CLIArgument instances defining the command's accepted arguments
41
- and options. Used for argument parsing, validation, and help text generation.
42
-
43
- Methods
44
- -------
45
- handle() -> None
46
- Abstract method that must be implemented by all concrete command subclasses.
47
- Contains the main execution logic specific to each command type and handles
48
- argument processing, business logic execution, and output generation.
49
-
50
- Notes
51
- -----
52
- - All concrete implementations must override the handle() method
53
- - Command signatures should follow framework naming conventions
54
- - Use self._args dictionary to access parsed command-line arguments
55
- - Implement proper error handling and validation within command logic
56
- - Follow single responsibility principle for maintainable command structure
57
- - Utilize framework's console output methods for consistent user experience
58
-
59
- See Also
60
- --------
61
- abc.ABC : Abstract base class functionality
62
- typing.Dict : Type hints for argument dictionary structure
63
18
  """
64
19
 
65
20
  # Enable timestamps in console output by default
@@ -72,52 +27,162 @@ class IBaseCommand(ABC):
72
27
  description: str
73
28
 
74
29
  # Dictionary to store parsed command-line arguments and options
75
- _args: Dict[str, Any] = {}
76
-
77
- # List of CLIArgument instances defining command arguments
78
- arguments: List[CLIArgument] = []
30
+ __args: Dict[str, Any] = {}
79
31
 
80
32
  @abstractmethod
81
- def handle(self) -> None:
33
+ async def options(self) -> List[CLIArgument]:
82
34
  """
83
- Execute the main logic of the console command.
35
+ Defines the command-line arguments and options accepted by the command.
84
36
 
85
- This abstract method serves as the primary entry point for command execution
86
- and must be implemented by all concrete command subclasses. The method contains
87
- the core business logic specific to each command type and is responsible for
88
- processing the parsed arguments stored in self.args and producing the desired
89
- output or side effects.
37
+ This asynchronous method should be overridden by subclasses to specify the list of
38
+ command-line arguments and options that the command supports. Each argument or option
39
+ should be represented as a CLIArgument object, which encapsulates details such as the
40
+ argument's name, type, default value, and help description.
90
41
 
91
- The implementation should access parsed command-line arguments through the
92
- self.args dictionary and utilize appropriate console output methods for
93
- user feedback and result presentation. Error handling and resource cleanup
94
- should also be managed within this method to ensure robust command execution.
42
+ This method enables the framework to automatically parse, validate, and document
43
+ the available arguments for each command, ensuring consistent user experience
44
+ across all commands.
45
+
46
+ Parameters
47
+ ----------
48
+ None
49
+
50
+ Returns
51
+ -------
52
+ List
53
+ A list of CLIArgument objects, where each object describes a single
54
+ command-line argument or option accepted by the command. If the command
55
+ does not accept any arguments or options, an empty list is returned.
56
+
57
+ Notes
58
+ -----
59
+ Subclasses should override this method to declare their specific arguments.
60
+ The returned list is used by the framework for argument parsing and help
61
+ text generation.
62
+ """
63
+ pass
64
+
65
+ @abstractmethod
66
+ async def handle(self):
67
+ """
68
+ Execute the main command logic.
69
+
70
+ This abstract method defines the entry point for command execution and must be
71
+ implemented by all concrete command subclasses. It serves as the primary interface
72
+ for running the command's core functionality after argument parsing and validation.
95
73
 
96
74
  Returns
97
75
  -------
98
76
  None
99
- This method does not return any value. All command output, results,
100
- error messages, and user feedback should be handled through console
101
- output methods, file operations, database transactions, or other
102
- side effects rather than return values.
77
+ This method does not return any value. All command output should be handled
78
+ through the inherited console methods or other side effects.
103
79
 
104
80
  Raises
105
81
  ------
106
82
  NotImplementedError
107
- Automatically raised when this method is called on the abstract base
108
- class without a concrete implementation. All subclasses must override
109
- this method with their specific command logic to avoid this exception.
83
+ Always raised when called on the base class, indicating that subclasses
84
+ must provide their own implementation of this method.
85
+
86
+ Notes
87
+ -----
88
+ Subclasses should override this method to implement their specific command
89
+ behavior. The method will be called after all command-line arguments have
90
+ been parsed and stored in the _args dictionary.
91
+ """
92
+ pass
93
+
94
+ @abstractmethod
95
+ def setArguments(self, args: Dict[str, Any]) -> None:
96
+ """
97
+ Populate the internal arguments dictionary with parsed command-line arguments and options.
98
+
99
+ This method is intended for internal use by the command parsing mechanism to initialize
100
+ the internal arguments state before command execution. It assigns the provided dictionary
101
+ of arguments and options to the internal storage, making them accessible via the
102
+ `argument()` and `arguments()` methods.
103
+
104
+ Parameters
105
+ ----------
106
+ args : Dict[str, Any]
107
+ Dictionary containing parsed command-line arguments and options, where each key
108
+ represents an argument name and each value is the corresponding argument value.
109
+
110
+ Returns
111
+ -------
112
+ None
113
+ This method does not return any value. It updates the internal state of the command
114
+ instance to reflect the provided arguments.
115
+
116
+ Raises
117
+ ------
118
+ ValueError
119
+ If the provided `args` parameter is not a dictionary.
110
120
 
111
121
  Notes
112
122
  -----
113
- - Access command arguments and options via the self.args dictionary
114
- - Use framework's console output methods for consistent user interaction
115
- - Implement comprehensive error handling and input validation
116
- - Ensure proper cleanup of resources (files, connections, etc.) if needed
117
- - Follow the single responsibility principle for maintainable command logic
118
- - Handle both success and failure scenarios appropriately
123
+ This method is automatically invoked by the command framework prior to the execution
124
+ of the `handle()` method. It should not be called directly by command implementations.
125
+ """
126
+ pass
127
+
128
+ @abstractmethod
129
+ def arguments(self) -> Dict[str, Any]:
119
130
  """
131
+ Retrieve the entire dictionary of parsed command-line arguments and options.
120
132
 
121
- # Abstract method placeholder - concrete implementations must override this method
122
- # Each subclass should replace this pass statement with specific command logic
133
+ This method provides access to all arguments and options that have been parsed
134
+ and stored internally for the current command execution. It is useful for
135
+ scenarios where bulk access to all argument values is required, such as
136
+ dynamic processing or debugging.
137
+
138
+ Returns
139
+ -------
140
+ Dict[str, Any]
141
+ A dictionary containing all parsed command-line arguments and options,
142
+ where each key is the argument name and each value is the corresponding
143
+ argument value.
144
+
145
+ Notes
146
+ -----
147
+ The returned dictionary reflects the current state of the command's arguments.
148
+ Modifying the returned dictionary will affect the internal state of the command.
149
+ """
150
+ pass
151
+
152
+ @abstractmethod
153
+ def argument(self, key: str, default: Any = None) -> Any:
154
+ """
155
+ Retrieve the value of a specific command-line argument by key with optional default fallback.
156
+
157
+ This method provides safe and validated access to command-line arguments stored in the
158
+ internal arguments dictionary. It performs type checking on both the key parameter and
159
+ the internal _args attribute to ensure data integrity before attempting retrieval.
160
+
161
+ The method follows a fail-safe approach by returning a default value when the requested
162
+ argument key is not found, preventing KeyError exceptions during command execution.
163
+
164
+ Parameters
165
+ ----------
166
+ key : str
167
+ The string identifier used to locate the desired argument in the arguments
168
+ dictionary. Must be a non-empty string that corresponds to a valid argument name.
169
+ default : Any, optional
170
+ The fallback value to return if the specified key is not found in the arguments
171
+ dictionary. Defaults to None if not provided.
172
+
173
+ Returns
174
+ -------
175
+ Any
176
+ The value associated with the specified key if it exists in the arguments
177
+ dictionary. If the key is not found, returns the provided default value
178
+ or None if no default was specified.
179
+
180
+ Raises
181
+ ------
182
+ ValueError
183
+ If the provided key parameter is not of string type.
184
+ ValueError
185
+ If the internal __args attribute is not of dictionary type, indicating
186
+ a corrupted or improperly initialized command state.
187
+ """
123
188
  pass
@@ -15,6 +15,7 @@ from orionis.console.contracts.executor import IExecutor
15
15
  from orionis.console.exceptions import CLIOrionisTypeError
16
16
  from orionis.console.request.cli_request import CLIRequest
17
17
  from orionis.foundation.contracts.application import IApplication
18
+ from orionis.services.introspection.concretes.reflection import ReflectionConcrete
18
19
  from orionis.services.introspection.modules.reflection import ReflectionModule
19
20
  from orionis.services.log.contracts.log_service import ILogger
20
21
  from orionis.support.performance.contracts.counter import IPerformanceCounter
@@ -87,6 +88,8 @@ class Reactor(IReactor):
87
88
  self.__loadFluentCommands()
88
89
  self.__load_fluent_commands: bool = True
89
90
 
91
+ print("Clase inicializada reactor")
92
+
90
93
  def __loadCommands(self) -> None:
91
94
  """
92
95
  Loads all available commands into the reactor's internal registry.
@@ -317,7 +320,7 @@ class Reactor(IReactor):
317
320
  for obj in core_commands:
318
321
 
319
322
  # Get the signature attribute from the command class
320
- signature = getattr(obj, 'signature', None)
323
+ signature = ReflectionConcrete(obj).getAttribute('signature')
321
324
 
322
325
  # Skip if signature is not defined
323
326
  if signature is None:
@@ -501,7 +504,9 @@ class Reactor(IReactor):
501
504
 
502
505
  # Validate the signature against the required pattern
503
506
  if not re.match(pattern, obj.signature):
504
- raise CLIOrionisValueError(f"Command class {obj.__name__} 'signature' must contain only alphanumeric characters, underscores (_) and colons (:), cannot start or end with underscore or colon, and cannot start with a number.")
507
+ raise CLIOrionisValueError(
508
+ f"Command class {obj.__name__} 'signature' must contain only alphanumeric characters, underscores (_) and colons (:), cannot start or end with underscore or colon, and cannot start with a number."
509
+ )
505
510
 
506
511
  # Return signature
507
512
  return obj.signature.strip()
@@ -553,8 +558,8 @@ class Reactor(IReactor):
553
558
  """
554
559
  Validates and processes command arguments for a command class.
555
560
 
556
- This method ensures that the command class has properly formatted arguments
557
- and creates an ArgumentParser instance configured with those arguments.
561
+ Ensures the command class provides a valid list of CLIArgument instances via its 'options' method,
562
+ and constructs an ArgumentParser accordingly.
558
563
 
559
564
  Parameters
560
565
  ----------
@@ -570,43 +575,53 @@ class Reactor(IReactor):
570
575
  Raises
571
576
  ------
572
577
  CLIOrionisTypeError
573
- If the 'arguments' attribute is not a list or contains non-CLIArgument instances.
578
+ If the 'options' method does not return a list or contains non-CLIArgument instances.
574
579
  """
575
580
 
576
- # Check if the command class has an arguments attribute
577
- if not hasattr(obj, 'arguments'):
578
- return None
581
+ # Instantiate the command and retrieve its options
582
+ instance = self.__app.make(obj)
583
+ options: List[CLIArgument] = self.__app.call(instance, 'options')
579
584
 
580
- # Ensure the arguments attribute is a list type
581
- if not isinstance(obj.arguments, list):
582
- raise CLIOrionisTypeError(f"Command class {obj.__name__} 'arguments' must be a list.")
585
+ # Validate that options is a list
586
+ if not isinstance(options, list):
587
+ raise CLIOrionisTypeError(
588
+ f"Command class {obj.__name__} 'options' must return a list."
589
+ )
583
590
 
584
- # If arguments is empty, return None
585
- if len(obj.arguments) == 0:
591
+ # Return None if there are no arguments
592
+ if not options:
586
593
  return None
587
594
 
588
- # Validate that all items in the arguments list are CLIArgument instances
589
- for index, value in enumerate(obj.arguments):
590
- if not isinstance(value, CLIArgument):
591
- raise CLIOrionisTypeError(f"Command class {obj.__name__} 'arguments' must contain only CLIArgument instances, found '{type(value).__name__}' at index {index}.")
595
+ # Validate all items are CLIArgument instances
596
+ for idx, arg in enumerate(options):
597
+ if not isinstance(arg, CLIArgument):
598
+ raise CLIOrionisTypeError(
599
+ f"Command class {obj.__name__} 'options' must contain only CLIArgument instances, "
600
+ f"found '{type(arg).__name__}' at index {idx}."
601
+ )
602
+
592
603
 
593
- # Build the arguments dictionary from the CLIArgument instances
594
- required_args: List[CLIArgument] = obj.arguments
604
+ # Get the Signature attribute from the command class
605
+ rf_concrete = ReflectionConcrete(obj)
606
+ signature = rf_concrete.getAttribute('signature', '<unknown>')
607
+ description = rf_concrete.getAttribute('description', '')
595
608
 
596
- # Create an ArgumentParser instance to handle the command arguments
609
+ # Build the ArgumentParser
597
610
  arg_parser = argparse.ArgumentParser(
598
- usage=f"python -B reactor {obj.signature} [options]",
599
- description=f"Command [{obj.signature}] : {obj.description}",
611
+ usage=f"python -B reactor {signature} [options]",
612
+ description=f"Command [{signature}] : {description}",
600
613
  formatter_class=argparse.RawTextHelpFormatter,
601
614
  add_help=True,
602
615
  allow_abbrev=False,
603
616
  exit_on_error=True,
604
- prog=obj.signature
617
+ prog=signature
605
618
  )
606
- for arg in required_args:
619
+
620
+ # Add each CLIArgument to the ArgumentParser
621
+ for arg in options:
607
622
  arg.addToParser(arg_parser)
608
623
 
609
- # Return the configured ArgumentParser
624
+ # Return the constructed ArgumentParser
610
625
  return arg_parser
611
626
 
612
627
  def __parseArgs(
@@ -646,13 +661,17 @@ class Reactor(IReactor):
646
661
 
647
662
  # If the command expects arguments, parse them using its ArgumentParser
648
663
  if command.args is not None and isinstance(command.args, argparse.ArgumentParser):
664
+
665
+ # If no args provided, use an empty list
649
666
  if args is None:
650
667
  args = []
668
+
669
+ # Parse the provided arguments using the command's ArgumentParser
651
670
  try:
652
- # Parse the provided arguments using the command's ArgumentParser
653
671
  parsed_args = command.args.parse_args(args)
672
+
673
+ # Raise a CLIOrionisRuntimeError with the help message included in the exception
654
674
  except SystemExit:
655
- # Raise a CLIOrionisRuntimeError with the help message included in the exception
656
675
  raise CLIOrionisRuntimeError(
657
676
  f"Failed to parse arguments for command '{command.signature}'.\n"
658
677
  f"{command.args.format_help()}\n"
@@ -662,10 +681,13 @@ class Reactor(IReactor):
662
681
  # Convert the parsed arguments to a dictionary and return
663
682
  if isinstance(parsed_args, argparse.Namespace):
664
683
  return vars(parsed_args)
684
+
685
+ # If parsed_args is already a dictionary, return it directly
665
686
  elif isinstance(parsed_args, dict):
666
687
  return parsed_args
688
+
689
+ # Return an empty dictionary if no arguments were parsed
667
690
  else:
668
- # Return an empty dictionary if no arguments were parsed
669
691
  return {}
670
692
 
671
693
  def command(
@@ -837,13 +859,13 @@ class Reactor(IReactor):
837
859
  command_instance: IBaseCommand = self.__app.make(command.obj)
838
860
 
839
861
  # Inject parsed arguments into the command instance
840
- _args = self.__parseArgs(command, args)
841
- command_instance._args = _args.copy()
862
+ dict_args = self.__parseArgs(command, args)
863
+ command_instance.setArguments(dict_args.copy())
842
864
 
843
865
  # Inject a scoped CLIRequest instance into the application container for the command's context
844
866
  self.__app.scopedInstance(ICLIRequest, CLIRequest(
845
867
  command=signature,
846
- args=_args.copy()
868
+ args=dict_args.copy()
847
869
  ))
848
870
 
849
871
  # Execute the command's handle method and capture its output
@@ -940,13 +962,13 @@ class Reactor(IReactor):
940
962
  command_instance: IBaseCommand = self.__app.make(command.obj)
941
963
 
942
964
  # Inject parsed arguments into the command instance
943
- _args = self.__parseArgs(command, args)
944
- command_instance._args = _args.copy()
965
+ dict_args = self.__parseArgs(command, args)
966
+ command_instance.setArguments(dict_args.copy())
945
967
 
946
968
  # Inject a scoped CLIRequest instance into the application container for the command's context
947
969
  self.__app.scopedInstance(ICLIRequest, CLIRequest(
948
970
  command=signature,
949
- args=_args.copy()
971
+ args=dict_args.copy()
950
972
  ))
951
973
 
952
974
  # Execute the command's handle method asynchronously and capture its output
@@ -2118,6 +2118,7 @@ class Application(Container, IApplication):
2118
2118
  duplicate initialization. The startup time is calculated and logged
2119
2119
  for performance monitoring purposes.
2120
2120
  """
2121
+
2121
2122
  # Check if already booted
2122
2123
  if not self.__booted:
2123
2124
 
@@ -2125,7 +2126,7 @@ class Application(Container, IApplication):
2125
2126
  self.instance(
2126
2127
  IApplication,
2127
2128
  self,
2128
- alias=f"x-{IApplication.__module__}.{IApplication.__name__}",
2129
+ alias=f"x-orionis.foundation.contracts.application.IApplication",
2129
2130
  enforce_decoupling=None
2130
2131
  )
2131
2132
 
@@ -2149,11 +2150,8 @@ class Application(Container, IApplication):
2149
2150
  # Calculate elapsed time in milliseconds since application start
2150
2151
  elapsed_ms = (time.time_ns() - self.startAt) // 1_000_000
2151
2152
 
2152
- # Compose the boot message
2153
- boot_message = f"Orionis Framework has been successfully booted. Startup time: {elapsed_ms} ms. Started at: {self.startAt} ns"
2154
-
2155
2153
  # Log message to the logger
2156
- logger.info(boot_message)
2154
+ logger.info(f"Orionis Framework has been successfully booted. Startup time: {elapsed_ms} ms. Started at: {self.startAt} ns")
2157
2155
 
2158
2156
  # Return the application instance for method chaining
2159
2157
  return self
@@ -5,7 +5,7 @@
5
5
  NAME = "orionis"
6
6
 
7
7
  # Current version of the framework
8
- VERSION = "0.616.0"
8
+ VERSION = "0.618.0"
9
9
 
10
10
  # Full name of the author or maintainer of the project
11
11
  AUTHOR = "Raul Mauricio Uñate Castro"
@@ -1,4 +1,3 @@
1
- import inspect
2
1
  import io
3
2
  import json
4
3
  import logging
@@ -118,18 +117,6 @@ class UnitTest(IUnitTest):
118
117
  # Use live console output during test execution
119
118
  self.__live_console: bool = True
120
119
 
121
- # Load and set internal paths for test discovery and result storage
122
- self.__loadPaths()
123
-
124
- # Load and validate the testing configuration from the application
125
- self.__loadConfig()
126
-
127
- # Discover and import test modules based on the configuration
128
- self.__loadModules()
129
-
130
- # Discover and load all test cases from the imported modules into the suite
131
- self.__loadTests()
132
-
133
120
  def __loadPaths(
134
121
  self
135
122
  ) -> None:
@@ -737,6 +724,18 @@ class UnitTest(IUnitTest):
737
724
  # Record the start time in seconds
738
725
  performance_counter.start()
739
726
 
727
+ # Load and set internal paths for test discovery and result storage
728
+ self.__loadPaths()
729
+
730
+ # Load and validate the testing configuration from the application
731
+ self.__loadConfig()
732
+
733
+ # Discover and import test modules based on the configuration
734
+ self.__loadModules()
735
+
736
+ # Discover and load all test cases from the imported modules into the suite
737
+ self.__loadTests()
738
+
740
739
  # Length of all tests in the suite
741
740
  total_tests = self.getTestCount()
742
741
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: orionis
3
- Version: 0.616.0
3
+ Version: 0.618.0
4
4
  Summary: Orionis Framework – Elegant, Fast, and Powerful.
5
5
  Home-page: https://github.com/orionis-framework/framework
6
6
  Author: Raul Mauricio Uñate Castro
@@ -4,7 +4,7 @@ orionis/console/kernel.py,sha256=NVWA20xasC8xE_fIoX5aKBy7dsrjgownQYarEOYiGKA,375
4
4
  orionis/console/args/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
5
  orionis/console/args/argument.py,sha256=QkdTrIYfG6CqDEMVBlQvNzRVHlBAcJOinVjq5Lz-wl8,20331
6
6
  orionis/console/base/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
7
- orionis/console/base/command.py,sha256=jdUPc7MoJs9QWo_WEPV0Mb_7f6G563OWFTh7DJeUfM8,6642
7
+ orionis/console/base/command.py,sha256=tAO_EVy1aNWneNSKYYMAf9yDTfbvHAqSJnZZ6pOR4tE,9318
8
8
  orionis/console/base/scheduler.py,sha256=IKNhpI_lPbI8H3YruD9z7eNdjuqNYceaclx_Hr5BHfY,8065
9
9
  orionis/console/base/scheduler_event_listener.py,sha256=X2mZBAYLBCtLOH7QSrCEaLeJ5m8Hq5UtGxaWRRvWbfo,4421
10
10
  orionis/console/commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -18,7 +18,7 @@ orionis/console/commands/test.py,sha256=-EmQwFwMBuby3OI9HwqMIwuJzd2CGbWbOqmwrR25
18
18
  orionis/console/commands/version.py,sha256=u2f7SetqEX__ufG6c37Ga-CylT4FGvy6wgld6RPBZGc,3589
19
19
  orionis/console/commands/workflow.py,sha256=NYOmjTSvm2o6AE4h9LSTZMFSYPQreNmEJtronyOxaYk,2451
20
20
  orionis/console/contracts/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
21
- orionis/console/contracts/base_command.py,sha256=vmAJD0yMQ5-AD_s9_xCFEAl64sKk65z7U2E196dALQM,5760
21
+ orionis/console/contracts/base_command.py,sha256=UlDN41Ts0ulxM-B2kgeKNr9_gNv_0LCth_pon1os-8U,7617
22
22
  orionis/console/contracts/base_scheduler.py,sha256=RSxEW57MoMU3pXfliIrQw9WuMk95p-xHXi1yACp1qsU,7728
23
23
  orionis/console/contracts/cli_request.py,sha256=qIV8ig8PG39LYp1acnUD8GYsNRSHncxIxGjO3B3YsUo,6755
24
24
  orionis/console/contracts/command.py,sha256=BOfRGpLRMsRS_a58584uO-MPK1UZGkmefLbFDtbk8ME,2911
@@ -32,7 +32,7 @@ orionis/console/contracts/reactor.py,sha256=iT6ShoCutAWEeJzOf_PK7CGXi9TgrOD5tewH
32
32
  orionis/console/contracts/schedule.py,sha256=N-AYUa1CJY7a4CV9L1EX_EUDtGlDJMg4y0aV9EDby1Q,16090
33
33
  orionis/console/contracts/schedule_event_listener.py,sha256=h06qsBxuEMD3KLSyu0JXdUDHlQW19BX9lA09Qrh2QXg,3818
34
34
  orionis/console/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
35
- orionis/console/core/reactor.py,sha256=AjusZMznUmrfIlUWlFGPaTNZi5fQ2FHCedQOmgHetfM,43222
35
+ orionis/console/core/reactor.py,sha256=vD1R9bocjhqYtxT93cSh6kcsWDkQd6sVPHvjJp9RVB8,43744
36
36
  orionis/console/dumper/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
37
37
  orionis/console/dumper/debug.py,sha256=p8uflSXeDJDrVM9mZY4JMYEus73Z6TsLnQQtgP0QUak,22427
38
38
  orionis/console/dynamic/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -103,7 +103,7 @@ orionis/failure/contracts/handler.py,sha256=AeJfkJfD3hTkOIYAtADq6GnQfq-qWgDfUc7b
103
103
  orionis/failure/entities/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
104
104
  orionis/failure/entities/throwable.py,sha256=1zD-awcuAyEtlR-L7V7ZIfPSF4GpXkf-neL5sXul7dc,1240
105
105
  orionis/foundation/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
106
- orionis/foundation/application.py,sha256=frdnW4Rt21_FEHDu89f47I-oi4sAKtzI8l9ebWRrRAk,90479
106
+ orionis/foundation/application.py,sha256=5gIuC5CxSdXaIuya47d_fAx3VODRTdtd9yn46DkoM9M,90402
107
107
  orionis/foundation/config/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
108
108
  orionis/foundation/config/startup.py,sha256=btqvryeIf9lLNQ9fBff7bJMrfraEY8qrWi4y_5YAR0Q,9681
109
109
  orionis/foundation/config/app/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -216,7 +216,7 @@ orionis/foundation/providers/scheduler_provider.py,sha256=IrPQJwvQVLRm5Qnz0Cxon4
216
216
  orionis/foundation/providers/testing_provider.py,sha256=eI1p2lUlxl25b5Z487O4nmqLE31CTDb4c3Q21xFadkE,1615
217
217
  orionis/foundation/providers/workers_provider.py,sha256=GdHENYV_yGyqmHJHn0DCyWmWId5xWjD48e6Zq2PGCWY,1674
218
218
  orionis/metadata/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
219
- orionis/metadata/framework.py,sha256=ENwcEbiue5W7lf1_fiyBZlKZKY7zAZH1tMrHLkGCAb8,4109
219
+ orionis/metadata/framework.py,sha256=9hzxpLNKGeHX8nD4qYpk_VAwNdd-Am_7SvUj-9mCLW4,4109
220
220
  orionis/metadata/package.py,sha256=k7Yriyp5aUcR-iR8SK2ec_lf0_Cyc-C7JczgXa-I67w,16039
221
221
  orionis/services/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
222
222
  orionis/services/asynchrony/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -370,7 +370,7 @@ orionis/test/contracts/render.py,sha256=wpDQzUtT0r8KFZ7zPcxWHXQ1EVNKxzA_rZ6ZKUcZ
370
370
  orionis/test/contracts/test_result.py,sha256=SNXJ2UerkweYn7uCT0i0HmMGP0XBrL_9KJs-0ZvIYU4,4002
371
371
  orionis/test/contracts/unit_test.py,sha256=EyidHoOPJItwgkBWGYY1TymbNklyn2EUXnghVvW4htc,4652
372
372
  orionis/test/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
373
- orionis/test/core/unit_test.py,sha256=P7AKazQWa-2TNjfqdiVEgVMpTgVn7k3l8RwO1C6Uq3w,71671
373
+ orionis/test/core/unit_test.py,sha256=Xe5110bWZcnHfo3LmGKfvLQobX37rjCZgRiTS08QL2I,71655
374
374
  orionis/test/entities/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
375
375
  orionis/test/entities/result.py,sha256=eZ6UIqGmFW8FZ9x8PB_MZbLAc-SAuUyi4FUcMYIZzGo,4777
376
376
  orionis/test/enums/__init__.py,sha256=M3imAgMvKFTKg55FbtVoY3zxj7QRY9AfaUWxiSZVvn4,66
@@ -403,8 +403,8 @@ orionis/test/validators/workers.py,sha256=rWcdRexINNEmGaO7mnc1MKUxkHKxrTsVuHgbnI
403
403
  orionis/test/view/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
404
404
  orionis/test/view/render.py,sha256=R55ykeRs0wDKcdTf4O1YZ8GDHTFmJ0IK6VQkbJkYUvo,5571
405
405
  orionis/test/view/report.stub,sha256=QLqqCdRoENr3ECiritRB3DO_MOjRQvgBh5jxZ3Hs1r0,28189
406
- orionis-0.616.0.dist-info/licenses/LICENCE,sha256=JhC-z_9mbpUrCfPjcl3DhDA8trNDMzb57cvRSam1avc,1463
407
- orionis-0.616.0.dist-info/METADATA,sha256=NxR2i-XdAdF0_Mfkoa2987cSMOoHNEQlvaq2vZI7oN4,4801
408
- orionis-0.616.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
409
- orionis-0.616.0.dist-info/top_level.txt,sha256=lyXi6jArpqJ-0zzNqd_uwsH-z9TCEBVBL-pC3Ekv7hU,8
410
- orionis-0.616.0.dist-info/RECORD,,
406
+ orionis-0.618.0.dist-info/licenses/LICENCE,sha256=JhC-z_9mbpUrCfPjcl3DhDA8trNDMzb57cvRSam1avc,1463
407
+ orionis-0.618.0.dist-info/METADATA,sha256=uUFuSeGcoS3u6GH1y99DAqbu-jQx7ZQ9P57Djm1uFnY,4801
408
+ orionis-0.618.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
409
+ orionis-0.618.0.dist-info/top_level.txt,sha256=lyXi6jArpqJ-0zzNqd_uwsH-z9TCEBVBL-pC3Ekv7hU,8
410
+ orionis-0.618.0.dist-info/RECORD,,