mirror of
https://github.com/koloideal/Argenta.git
synced 2026-06-10 18:15:28 +03:00
impl di in handlers with support custom provider
This commit is contained in:
@@ -1,18 +1,19 @@
|
||||
from collections.abc import Iterator
|
||||
from typing import Callable
|
||||
import inspect
|
||||
|
||||
from argenta.command import Command
|
||||
from argenta.response import Response
|
||||
|
||||
|
||||
class CommandHandler:
|
||||
def __init__(self, handler_as_func: Callable[[Response], None], handled_command: Command):
|
||||
def __init__(self, handler_as_func: Callable[..., None], handled_command: Command):
|
||||
"""
|
||||
Private. Entity of the model linking the handler and the command being processed
|
||||
:param handler: the handler being called
|
||||
:param handled_command: the command being processed
|
||||
"""
|
||||
self.handler_as_func: Callable[[Response], None] = handler_as_func
|
||||
self.handler_as_func: Callable[..., None] = handler_as_func
|
||||
self.handled_command: Command = handled_command
|
||||
|
||||
def handling(self, response: Response) -> None:
|
||||
@@ -30,7 +31,9 @@ class CommandHandlers:
|
||||
Private. The model that unites all CommandHandler of the routers
|
||||
:param command_handlers: list of CommandHandlers for register
|
||||
"""
|
||||
self.command_handlers: list[CommandHandler] = command_handlers if command_handlers else []
|
||||
self.command_handlers: list[CommandHandler] = (
|
||||
command_handlers if command_handlers else []
|
||||
)
|
||||
|
||||
def add_handler(self, command_handler: CommandHandler) -> None:
|
||||
"""
|
||||
|
||||
@@ -6,25 +6,23 @@ from argenta.command import Command, InputCommand
|
||||
from argenta.command.flag import ValidationStatus
|
||||
from argenta.response import Response, ResponseStatus
|
||||
from argenta.router.command_handler.entity import CommandHandlers, CommandHandler
|
||||
from argenta.command.flag.flags import (
|
||||
Flags,
|
||||
InputFlags
|
||||
)
|
||||
from argenta.command.flag.flags import Flags, InputFlags
|
||||
from argenta.router.exceptions import (
|
||||
RepeatedFlagNameException,
|
||||
TooManyTransferredArgsException,
|
||||
RequiredArgumentNotPassedException,
|
||||
TriggerContainSpacesException,
|
||||
)
|
||||
|
||||
|
||||
HandlerFunc: TypeAlias = Callable[[Response], None]
|
||||
HandlerFunc: TypeAlias = Callable[..., None]
|
||||
|
||||
|
||||
class Router:
|
||||
def __init__(
|
||||
self, *, title: str | None = "Default title",
|
||||
disable_redirect_stdout: bool = False
|
||||
self,
|
||||
*,
|
||||
title: str | None = "Default title",
|
||||
disable_redirect_stdout: bool = False,
|
||||
):
|
||||
"""
|
||||
Public. Directly configures and manages handlers
|
||||
@@ -58,7 +56,6 @@ class Router:
|
||||
def decorator(func: HandlerFunc) -> HandlerFunc:
|
||||
_validate_func_args(func)
|
||||
self.command_handlers.add_handler(CommandHandler(func, redefined_command))
|
||||
|
||||
return func
|
||||
|
||||
return decorator
|
||||
@@ -91,7 +88,9 @@ class Router:
|
||||
handle_command = command_handler.handled_command
|
||||
if handle_command.registered_flags.flags:
|
||||
if input_command_flags.flags:
|
||||
response: Response = _structuring_input_flags(handle_command, input_command_flags)
|
||||
response: Response = _structuring_input_flags(
|
||||
handle_command, input_command_flags
|
||||
)
|
||||
command_handler.handling(response)
|
||||
else:
|
||||
response = Response(ResponseStatus.ALL_FLAGS_VALID)
|
||||
@@ -102,7 +101,9 @@ class Router:
|
||||
for input_flag in input_command_flags:
|
||||
input_flag.status = ValidationStatus.UNDEFINED
|
||||
undefined_flags.add_flag(input_flag)
|
||||
response = Response(ResponseStatus.UNDEFINED_FLAGS, input_flags=undefined_flags)
|
||||
response = Response(
|
||||
ResponseStatus.UNDEFINED_FLAGS, input_flags=undefined_flags
|
||||
)
|
||||
command_handler.handling(response)
|
||||
else:
|
||||
response = Response(ResponseStatus.ALL_FLAGS_VALID)
|
||||
@@ -137,14 +138,17 @@ class CommandDecorator:
|
||||
self.router: Router = router_instance
|
||||
self.command: Command = command
|
||||
|
||||
def __call__(self, handler_func: Callable[[Response], None]) -> Callable[[Response], None]:
|
||||
def __call__(self, handler_func: Callable[..., None]) -> Callable[..., None]:
|
||||
_validate_func_args(handler_func)
|
||||
self.router.command_handlers.add_handler(CommandHandler(handler_func, self.command))
|
||||
self.router.command_handlers.add_handler(
|
||||
CommandHandler(handler_func, self.command)
|
||||
)
|
||||
return handler_func
|
||||
|
||||
|
||||
def _structuring_input_flags(handled_command: Command,
|
||||
input_flags: InputFlags) -> Response:
|
||||
def _structuring_input_flags(
|
||||
handled_command: Command, input_flags: InputFlags
|
||||
) -> Response:
|
||||
"""
|
||||
Private. Validates flags of input command
|
||||
:param handled_command: entity of the handled command
|
||||
@@ -154,45 +158,42 @@ def _structuring_input_flags(handled_command: Command,
|
||||
invalid_value_flags, undefined_flags = False, False
|
||||
|
||||
for flag in input_flags:
|
||||
flag_status: ValidationStatus = (handled_command.validate_input_flag(flag))
|
||||
flag_status: ValidationStatus = handled_command.validate_input_flag(flag)
|
||||
flag.status = flag_status
|
||||
if flag_status == ValidationStatus.INVALID:
|
||||
invalid_value_flags = True
|
||||
elif flag_status == ValidationStatus.UNDEFINED:
|
||||
undefined_flags = True
|
||||
|
||||
status = ResponseStatus.from_flags(has_invalid_value_flags=invalid_value_flags,
|
||||
has_undefined_flags=undefined_flags)
|
||||
|
||||
return Response(
|
||||
status=status,
|
||||
input_flags=input_flags
|
||||
status = ResponseStatus.from_flags(
|
||||
has_invalid_value_flags=invalid_value_flags, has_undefined_flags=undefined_flags
|
||||
)
|
||||
|
||||
def _validate_func_args(func: Callable[[Response], None]) -> None:
|
||||
return Response(status=status, input_flags=input_flags)
|
||||
|
||||
|
||||
def _validate_func_args(func: Callable[..., None]) -> None:
|
||||
"""
|
||||
Private. Validates the arguments of the handler
|
||||
:param func: entity of the handler func
|
||||
:return: None if func is valid else raise exception
|
||||
"""
|
||||
transferred_args = getfullargspec(func).args
|
||||
if len(transferred_args) > 1:
|
||||
raise TooManyTransferredArgsException()
|
||||
elif len(transferred_args) == 0:
|
||||
if len(transferred_args) == 0:
|
||||
raise RequiredArgumentNotPassedException()
|
||||
|
||||
transferred_arg: str = transferred_args[0]
|
||||
response_arg: str = transferred_args[0]
|
||||
func_annotations: dict[str, None] = get_annotations(func)
|
||||
|
||||
arg_annotation = func_annotations.get(transferred_arg)
|
||||
response_arg_annotation = func_annotations.get(response_arg)
|
||||
|
||||
if arg_annotation is not None:
|
||||
if arg_annotation is not Response:
|
||||
if response_arg_annotation is not None:
|
||||
if response_arg_annotation is not Response:
|
||||
source_line: int = getsourcelines(func)[1]
|
||||
Console().print(
|
||||
f'\nFile "{getsourcefile(func)}", line {source_line}\n[b red]WARNING:[/b red] [i]The typehint ' +
|
||||
f"of argument([green]{transferred_arg}[/green]) passed to the handler must be [/i][bold blue]{Response}[/bold blue]," +
|
||||
f" [i]but[/i] [bold blue]{arg_annotation}[/bold blue] [i]is specified[/i]",
|
||||
f'\nFile "{getsourcefile(func)}", line {source_line}\n[b red]WARNING:[/b red] [i]The typehint '
|
||||
+ f"of argument([green]{response_arg}[/green]) passed to the handler must be [/i][bold blue]{Response}[/bold blue],"
|
||||
+ f" [i]but[/i] [bold blue]{response_arg_annotation}[/bold blue] [i]is specified[/i]",
|
||||
highlight=False,
|
||||
)
|
||||
|
||||
|
||||
@@ -5,24 +5,17 @@ class RepeatedFlagNameException(Exception):
|
||||
"""
|
||||
Private. Raised when a repeated flag name is registered
|
||||
"""
|
||||
|
||||
@override
|
||||
def __str__(self) -> str:
|
||||
return "Repeated registered flag names in register command"
|
||||
|
||||
|
||||
class TooManyTransferredArgsException(Exception):
|
||||
"""
|
||||
Private. Raised when too many arguments are passed
|
||||
"""
|
||||
@override
|
||||
def __str__(self) -> str:
|
||||
return "Too many transferred arguments"
|
||||
|
||||
|
||||
class RequiredArgumentNotPassedException(Exception):
|
||||
"""
|
||||
Private. Raised when a required argument is not passed
|
||||
"""
|
||||
|
||||
@override
|
||||
def __str__(self) -> str:
|
||||
return "Required argument not passed"
|
||||
@@ -32,6 +25,7 @@ class TriggerContainSpacesException(Exception):
|
||||
"""
|
||||
Private. Raised when there is a space in the trigger being registered
|
||||
"""
|
||||
|
||||
@override
|
||||
def __str__(self) -> str:
|
||||
return "Command trigger cannot contain spaces"
|
||||
|
||||
Reference in New Issue
Block a user