diff --git a/docs/code_snippets/argparser/snippet.py b/docs/code_snippets/argparser/snippet.py index 4b4fab5..4553e7c 100644 --- a/docs/code_snippets/argparser/snippet.py +++ b/docs/code_snippets/argparser/snippet.py @@ -1,13 +1,17 @@ from argenta import App, Orchestrator -from argenta.orchestrator.argparser import ArgParser, BooleanArgument, ValueArgument +from argenta.orchestrator.argparser import ArgParser, BooleanArgument -arg_parser = ArgParser(processed_args=[BooleanArgument("dev"), ValueArgument('some', possible_values=['fuck', 'cruck'])]) +arg_parser = ArgParser( + processed_args=[ + BooleanArgument("dev") + ] +) orchestrator = Orchestrator( arg_parser=arg_parser, ) if __name__ == "__main__": - if arg_parser.parsed_argspace.get_by_name('dev'): - orchestrator.start_polling(App(initial_message='ArgentaDev')) + if arg_parser.parsed_argspace.get_by_name("dev"): + orchestrator.start_polling(App(initial_message="ArgentaDev")) else: orchestrator.start_polling(App()) diff --git a/docs/code_snippets/argspace/snippet.py b/docs/code_snippets/argspace/snippet.py index f7f8e40..3c22275 100644 --- a/docs/code_snippets/argspace/snippet.py +++ b/docs/code_snippets/argspace/snippet.py @@ -6,11 +6,7 @@ arguments = [ ValueArgument("port", help="Server port", is_required=True), ] -argparser = ArgParser( - processed_args=arguments, - name="WebServer", - description="Simple web server" -) +argparser = ArgParser(processed_args=arguments, name="WebServer", description="Simple web server") app = App() orchestrator = Orchestrator(argparser) diff --git a/docs/code_snippets/argspace/snippet4.py b/docs/code_snippets/argspace/snippet4.py index efb3180..8fc26b2 100644 --- a/docs/code_snippets/argspace/snippet4.py +++ b/docs/code_snippets/argspace/snippet4.py @@ -1,11 +1,20 @@ -config_arg = argspace.get_by_name("config") -if config_arg: - print(f"Config path: {config_arg.value}") +from argenta import Response, Router +from argenta.di import FromDishka +from argenta.orchestrator.argparser import ArgSpace -verbose_arg = argspace.get_by_name("verbose") -if verbose_arg and verbose_arg.value: - print("Verbose mode enabled") +router = Router() -unknown_arg = argspace.get_by_name("nonexistent") -if unknown_arg is None: - print("Argument not found") + +@router.command("get_args") +def get_args(response: Response, argspace: FromDishka[ArgSpace]): + config_arg = argspace.get_by_name("config") + if config_arg: + print(f"Config path: {config_arg.value}") + + verbose_arg = argspace.get_by_name("verbose") + if verbose_arg and verbose_arg.value: + print("Verbose mode enabled") + + unknown_arg = argspace.get_by_name("nonexistent") + if unknown_arg is None: + print("Argument not found") diff --git a/docs/code_snippets/arguments/snippet.py b/docs/code_snippets/arguments/snippet.py index 6e8f8e0..c49600a 100644 --- a/docs/code_snippets/arguments/snippet.py +++ b/docs/code_snippets/arguments/snippet.py @@ -1,28 +1,20 @@ from argenta.orchestrator.argparser import ArgParser, ValueArgument # Create arguments -config_arg = ValueArgument( - "config", - help="Path to configuration file", - default="config.yaml" -) +config_arg = ValueArgument("config", help="Path to configuration file", default="config.yaml") log_level_arg = ValueArgument( "log-level", help="Logging level", possible_values=["DEBUG", "INFO", "WARNING", "ERROR"], - default="INFO" + default="INFO", ) -host_arg = ValueArgument( - "host", - help="Server host address", - is_required=True -) +host_arg = ValueArgument("host", help="Server host address", is_required=True) # Register in ArgParser parser = ArgParser( processed_args=[config_arg, log_level_arg, host_arg], name="MyApp", - description="My application with CLI arguments" + description="My application with CLI arguments", ) \ No newline at end of file diff --git a/docs/code_snippets/arguments/snippet2.py b/docs/code_snippets/arguments/snippet2.py index 254ed82..b63477d 100644 --- a/docs/code_snippets/arguments/snippet2.py +++ b/docs/code_snippets/arguments/snippet2.py @@ -1,23 +1,9 @@ from argenta.orchestrator.argparser import ArgParser, BooleanArgument # Create boolean arguments -verbose_arg = BooleanArgument( - "verbose", - help="Enable verbose output" -) - -debug_arg = BooleanArgument( - "debug", - help="Enable debug mode" -) - -no_cache_arg = BooleanArgument( - "no-cache", - help="Disable caching" -) +verbose_arg = BooleanArgument("verbose", help="Enable verbose output") +debug_arg = BooleanArgument("debug", help="Enable debug mode") +no_cache_arg = BooleanArgument("no-cache", help="Disable caching") # Register in ArgParser -parser = ArgParser( - processed_args=[verbose_arg, debug_arg, no_cache_arg], - name="MyApp" -) \ No newline at end of file +parser = ArgParser(processed_args=[verbose_arg, debug_arg, no_cache_arg], name="MyApp") \ No newline at end of file diff --git a/docs/code_snippets/command/snippet5.py b/docs/code_snippets/command/snippet5.py index 4939f95..c088457 100644 --- a/docs/code_snippets/command/snippet5.py +++ b/docs/code_snippets/command/snippet5.py @@ -2,10 +2,13 @@ from argenta import Router, Command, Response router = Router(title="System") -@router.command(Command( - "shutdown", - description="Shutdown the system", - aliases=["poweroff", "halt", "stop"] -)) + +@router.command( + Command( + "shutdown", + description="Shutdown the system", + aliases=["poweroff", "halt", "stop"] + ) +) def handle_shutdown(response: Response): print("Shutting down the system...") \ No newline at end of file diff --git a/docs/code_snippets/flags/deploy_handler.py b/docs/code_snippets/flags/deploy_handler.py index d0f2e2b..8c09d09 100644 --- a/docs/code_snippets/flags/deploy_handler.py +++ b/docs/code_snippets/flags/deploy_handler.py @@ -5,10 +5,7 @@ from argenta.command.flag import ValidationStatus router = Router() -@router.command(Command( - "deploy", - flags=Flag("verbose", possible_values=PossibleValues.NEITHER) -)) +@router.command(Command("deploy", flags=Flag("verbose", possible_values=PossibleValues.NEITHER))) def deploy_handler(response: Response): # Check for toggle flag presence verbose_flag = response.input_flags.get_flag_by_name("verbose") diff --git a/docs/code_snippets/input_flags/snippet1.py b/docs/code_snippets/input_flags/snippet1.py index 93d528f..100b557 100644 --- a/docs/code_snippets/input_flags/snippet1.py +++ b/docs/code_snippets/input_flags/snippet1.py @@ -8,10 +8,7 @@ router = Router(title="Example") Command( "example", description="Example command with flags", - flags=Flags([ - Flag("name"), - Flag("age") - ]), + flags=Flags([Flag("name"), Flag("age")]), ) ) def example_handler(response: Response): diff --git a/docs/code_snippets/input_flags/snippet2.py b/docs/code_snippets/input_flags/snippet2.py index 6d059b8..5686f86 100644 --- a/docs/code_snippets/input_flags/snippet2.py +++ b/docs/code_snippets/input_flags/snippet2.py @@ -8,11 +8,7 @@ router = Router(title="Get Flag Example") Command( "config", description="Configure settings", - flags=Flags([ - Flag("host"), - Flag("port"), - Flag("debug") - ]), + flags=Flags([Flag("host"), Flag("port"), Flag("debug")]), ) ) def config_handler(response: Response): diff --git a/docs/code_snippets/input_flags/snippet4.py b/docs/code_snippets/input_flags/snippet4.py index 5d143ad..366f4c3 100644 --- a/docs/code_snippets/input_flags/snippet4.py +++ b/docs/code_snippets/input_flags/snippet4.py @@ -5,17 +5,11 @@ from argenta.command import InputFlags flags = InputFlags() # Create several flags -flag1 = InputFlag( - name="option1", prefix="--", input_value="value1", status=ValidationStatus.VALID -) +flag1 = InputFlag(name="option1", prefix="--", input_value="value1", status=ValidationStatus.VALID) -flag2 = InputFlag( - name="option2", prefix="--", input_value="value2", status=ValidationStatus.VALID -) +flag2 = InputFlag(name="option2", prefix="--", input_value="value2", status=ValidationStatus.VALID) -flag3 = InputFlag( - name="option3", prefix="---", input_value="value3", status=ValidationStatus.VALID -) +flag3 = InputFlag(name="option3", prefix="---", input_value="value3", status=ValidationStatus.VALID) # Add all flags in one call flags.add_flags([flag1, flag2, flag3]) diff --git a/docs/code_snippets/input_flags/snippet8.py b/docs/code_snippets/input_flags/snippet8.py index fffd022..05fc9d3 100644 --- a/docs/code_snippets/input_flags/snippet8.py +++ b/docs/code_snippets/input_flags/snippet8.py @@ -26,12 +26,8 @@ flags3 = InputFlags( ) print(f"flags1 == flags2: {flags1 == flags2}") # True (same names) -print( - f"flags1 == flags3: {flags1 == flags3}" -) # True (same names, values are not considered) +print(f"flags1 == flags3: {flags1 == flags3}") # True (same names, values are not considered) # Different collections -flags4 = InputFlags( - [InputFlag(name="flag3", input_value="value3", status=ValidationStatus.VALID)] -) +flags4 = InputFlags([InputFlag(name="flag3", input_value="value3", status=ValidationStatus.VALID)]) print(f"flags1 == flags4: {flags1 == flags4}") # False (different flags) diff --git a/docs/code_snippets/quickstart/calculator_app.py b/docs/code_snippets/quickstart/calculator_app.py index 38a42f6..b48b7a9 100644 --- a/docs/code_snippets/quickstart/calculator_app.py +++ b/docs/code_snippets/quickstart/calculator_app.py @@ -8,11 +8,8 @@ from argenta.response.status import ResponseStatus router = Router("Calculator") -operations = { - 'mul': operator.mul, - 'sub': operator.sub, - 'add': operator.add -} +operations = {"mul": operator.mul, "sub": operator.sub, "add": operator.add} + @router.command( Command( @@ -22,7 +19,9 @@ operations = { [ Flag("a", possible_values=re.compile(r"^\d{,5}$")), # First number Flag("b", possible_values=re.compile(r"^\d{,5}$")), # Second number - Flag("operation", possible_values=["add", "sub", "mul"]), # Operation: add, sub, mul + Flag( + "operation", possible_values=["add", "sub", "mul"] + ), # Operation: add, sub, mul ] ), ) diff --git a/docs/code_snippets/quickstart/simple_app.py b/docs/code_snippets/quickstart/simple_app.py index a46090e..96c7179 100644 --- a/docs/code_snippets/quickstart/simple_app.py +++ b/docs/code_snippets/quickstart/simple_app.py @@ -6,7 +6,7 @@ app = App( prompt=">> ", initial_message="Simple App", farewell_message="Goodbye!", - repeat_command_groups_printing=False + repeat_command_groups_printing=False, ) orchestrator = Orchestrator() @@ -15,11 +15,7 @@ main_router = Router(title="Main commands") # 3. Define command and its handler -@main_router.command(Command( - "hello", - description="Prints greeting message", - flags=Flag("name") -)) +@main_router.command(Command("hello", description="Prints greeting message", flags=Flag("name"))) def hello_handler(response: Response): """This handler will be called for 'hello' command.""" name = response.input_flags.get_flag_by_name("name") diff --git a/docs/code_snippets/quickstart/task_manager/handlers.py b/docs/code_snippets/quickstart/task_manager/handlers.py index 90e17f4..9d4e116 100644 --- a/docs/code_snippets/quickstart/task_manager/handlers.py +++ b/docs/code_snippets/quickstart/task_manager/handlers.py @@ -10,25 +10,29 @@ from .repository import Priority, Task, TaskRepository router = Router(title="Task Manager") -@router.command(Command( +@router.command( + Command( "add-task", description="Add a new task", - flags=Flags([ + flags=Flags( + [ Flag("description"), Flag("priority", possible_values=["low", "medium", "high"]), - ]), - )) + ] + ), + ) +) def add_task(response: Response, repo: FromDishka[TaskRepository]): description_flag = response.input_flags.get_flag_by_name("description") - + if not description_flag or not description_flag.status == ValidationStatus.VALID: print("Error: --description flag is required.") return - + task_description = description_flag.input_value or "" priority_flag = response.input_flags.get_flag_by_name("priority") - + if priority_flag and priority_flag.status == ValidationStatus.VALID: priority_value = priority_flag.input_value else: @@ -38,14 +42,14 @@ def add_task(response: Response, repo: FromDishka[TaskRepository]): task = Task(description=task_description, priority=priority) repo.add_task(task) - + print(f"Added task: '{task.description}' with priority '{task.priority}'") @router.command(Command("list-tasks", description="List all tasks")) def list_tasks(response: Response, repo: FromDishka[TaskRepository]): tasks = repo.get_all_tasks() - + if not tasks: print("No tasks found.") return diff --git a/docs/code_snippets/response/data_sharing.py b/docs/code_snippets/response/data_sharing.py index 5f0ae54..8fdaf8d 100644 --- a/docs/code_snippets/response/data_sharing.py +++ b/docs/code_snippets/response/data_sharing.py @@ -4,6 +4,7 @@ from argenta.di import FromDishka router = Router(title="Authentication") + def authenticate_user(username: str) -> str: return f"token_for_{username}" diff --git a/docs/code_snippets/response/snippet2.py b/docs/code_snippets/response/snippet2.py deleted file mode 100644 index 4342302..0000000 --- a/docs/code_snippets/response/snippet2.py +++ /dev/null @@ -1,25 +0,0 @@ -from argenta import Command, Response, Router - -router = Router(title="Data Example") - - -@router.command(Command("set", description="Set data")) -def set_handler(response: Response): - # Update global data storage - response.update_data( - { - "user_name": "John", - "timestamp": "2024-01-01", - "settings": {"theme": "dark", "language": "ru"}, - } - ) - print("Data updated successfully") - - -@router.command(Command("show", description="Show data")) -def show_handler(response: Response): - # Get data from global storage - data = response.get_data() - if "user_name" in data: - print(f"User: {data['user_name']}") - print(f"Settings: {data.get('settings', {})}") diff --git a/docs/code_snippets/response/snippet3.py b/docs/code_snippets/response/snippet3.py deleted file mode 100644 index 2385169..0000000 --- a/docs/code_snippets/response/snippet3.py +++ /dev/null @@ -1,16 +0,0 @@ -from argenta import Command, Response, Router - -router = Router(title="Get Data Example") - - -@router.command(Command("info", description="Show all stored data")) -def info_handler(response: Response): - # Get all data from global storage - all_data = response.get_data() - - if all_data: - print("Stored data:") - for key, value in all_data.items(): - print(f" {key}: {value}") - else: - print("No data stored") diff --git a/docs/code_snippets/response/snippet4.py b/docs/code_snippets/response/snippet4.py deleted file mode 100644 index 59c7947..0000000 --- a/docs/code_snippets/response/snippet4.py +++ /dev/null @@ -1,19 +0,0 @@ -from argenta import Command, Response, Router - -router = Router(title="Clear Data Example") - - -@router.command(Command("clear", description="Clear all stored data")) -def clear_handler(response: Response): - # Clear all data storage - response.clear_data() - print("All data cleared") - - -@router.command(Command("check", description="Check if data exists")) -def check_handler(response: Response): - data = response.get_data() - if data: - print(f"Storage contains {len(data)} item(s)") - else: - print("Storage is empty") diff --git a/docs/code_snippets/response/snippet5.py b/docs/code_snippets/response/snippet5.py deleted file mode 100644 index b0bde42..0000000 --- a/docs/code_snippets/response/snippet5.py +++ /dev/null @@ -1,29 +0,0 @@ -from argenta import Command, Response, Router - -router = Router(title="Delete Data Example") - - -@router.command(Command("store", description="Store data")) -def store_handler(response: Response): - response.update_data( - { - "temp_key": "temporary value", - "important_key": "important value", - "another_key": "another value", - } - ) - print("Data stored") - - -@router.command(Command("remove", description="Remove specific key")) -def remove_handler(response: Response): - # Delete specific key from storage - try: - response.delete_from_data("temp_key") - print("Key 'temp_key' deleted") - - # Check what remains - remaining = response.get_data() - print(f"Remaining keys: {list(remaining.keys())}") - except KeyError: - print("Key not found") diff --git a/docs/code_snippets/response/snippet6.py b/docs/code_snippets/response/snippet6.py index 2f4751c..1c6dff6 100644 --- a/docs/code_snippets/response/snippet6.py +++ b/docs/code_snippets/response/snippet6.py @@ -10,10 +10,7 @@ router = Router(title="Flags Example") Command( "process", description="Process with flags", - flags=Flags([ - Flag("format", possible_values=["json", "xml"]), - Flag("verbose") - ]), + flags=Flags([Flag("format", possible_values=["json", "xml"]), Flag("verbose")]), ) ) def process_handler(response: Response): diff --git a/docs/code_snippets/testing/app_e2e_test.py b/docs/code_snippets/testing/app_e2e_test.py index 10a3be7..d209d6f 100644 --- a/docs/code_snippets/testing/app_e2e_test.py +++ b/docs/code_snippets/testing/app_e2e_test.py @@ -8,22 +8,21 @@ from argenta import App, Orchestrator, Router, Command, Response @pytest.fixture(autouse=True) def patched_argv(): - with patch.object(sys, 'argv', ['program.py']): + with patch.object(sys, "argv", ["program.py"]): yield + def test_input_incorrect_command(capsys: CaptureFixture[str]): router = Router() orchestrator = Orchestrator() - @router.command(Command('test')) + @router.command(Command("test")) def test(response: Response) -> None: - print('test command') + print("test command") app = App(override_system_messages=True, printer=print) app.include_router(router) - app.set_unknown_command_handler( - lambda command: print(f'Unknown command: {command.trigger}') - ) + app.set_unknown_command_handler(lambda command: print(f"Unknown command: {command.trigger}")) with patch("builtins.input", side_effect=["help", "q"]): orchestrator.start_polling(app) diff --git a/docs/code_snippets/testing/app_integration_unittest.py b/docs/code_snippets/testing/app_integration_unittest.py index f3a0caf..6cbd2f7 100644 --- a/docs/code_snippets/testing/app_integration_unittest.py +++ b/docs/code_snippets/testing/app_integration_unittest.py @@ -17,5 +17,5 @@ def test_simple_app() -> None: with redirect_stdout(io.StringIO()) as stdout: router.finds_appropriate_handler(InputCommand.parse("HELP")) - + assert "Available commands:" in stdout.getvalue() diff --git a/docs/code_snippets/testing/di_handler_unittest.py b/docs/code_snippets/testing/di_handler_unittest.py index 62b897c..3fb4b53 100644 --- a/docs/code_snippets/testing/di_handler_unittest.py +++ b/docs/code_snippets/testing/di_handler_unittest.py @@ -11,18 +11,20 @@ from argenta.di.integration import setup_dishka, FromDishka class Service: def hello(self) -> str: return "world" - + + def get_service() -> Service: return Service() - + router = Router(title="DI") + @router.command("HELLO") def hello(response: Response, service: FromDishka[Service]) -> None: print(f"hello {service.hello()}") - - + + class _FakeApp: # Minimal stub for setup_dishka; app object is not used in unit tests registered_routers = [router] @@ -31,12 +33,12 @@ class _FakeApp: def test_hello_uses_service(): provider = Provider(scope=Scope.APP) provider.provide(get_service) - + container = make_container(provider) setup_dishka(app=_FakeApp(), container=container, auto_inject=True) # Call handler with redirect_stdout(io.StringIO()) as stdout: - router.finds_appropriate_handler(InputCommand.parse('HELLO')) + router.finds_appropriate_handler(InputCommand.parse("HELLO")) assert "hello world" in stdout.getvalue() diff --git a/docs/code_snippets/testing/simple_handler_unittest.py b/docs/code_snippets/testing/simple_handler_unittest.py index 176b5e6..9ade881 100644 --- a/docs/code_snippets/testing/simple_handler_unittest.py +++ b/docs/code_snippets/testing/simple_handler_unittest.py @@ -7,6 +7,7 @@ from argenta.command import InputCommand router = Router(title="Demo") + @router.command(Command("PING", description="Ping command")) def ping(response: Response): print("PONG") diff --git a/docs/root/api/app/index.rst b/docs/root/api/app/index.rst index 9646edc..cc4462a 100644 --- a/docs/root/api/app/index.rst +++ b/docs/root/api/app/index.rst @@ -10,29 +10,23 @@ App Инициализация ------------- -.. code-block:: python - :linenos: - - AVAILABLE_DIVIDING_LINES: TypeAlias = StaticDividingLine | DynamicDividingLine - DEFAULT_DIVIDING_LINE: StaticDividingLine = StaticDividingLine() - - DEFAULT_PRINT_FUNC: Printer = Console().print - DEFAULT_AUTOCOMPLETER: AutoCompleter = AutoCompleter() - DEFAULT_EXIT_COMMAND: Command = Command("Q", description="Exit command") - .. code-block:: python :linenos: - def __init__(self, *, prompt: str = "What do you want to do?\n\n", - initial_message: str = "Argenta\n", - farewell_message: str = "\nSee you\n", - exit_command: Command = DEFAULT_EXIT_COMMAND, - system_router_title: str | None = "System points:", - dividing_line: AVAILABLE_DIVIDING_LINES = DEFAULT_DIVIDING_LINE, - repeat_command_groups_printing: bool = False, - override_system_messages: bool = False, - autocompleter: AutoCompleter = DEFAULT_AUTOCOMPLETER, - print_func: Printer = DEFAULT_PRINT_FUNC) -> None + def __init__( + self, + *, + prompt: str = ">>> ", + initial_message: str = "Argenta", + farewell_message: str = "See you", + exit_command: Command = Command("q", description="Exit command"), + system_router_title: str = "System points:", + dividing_line: StaticDividingLine | DynamicDividingLine | None = None, + repeat_command_groups_printing: bool = False, + override_system_messages: bool = False, + autocompleter: AutoCompleter | None = None, + printer: Printer = Console().print, + ) -> None: Создаёт и настраивает экземпляр приложения. @@ -45,7 +39,7 @@ App * ``repeat_command_groups_printing``: Если ``True``, список доступных команд выводится перед каждым вводом. * ``override_system_messages``: Если ``True``, стандартное форматирование (цвета, ASCII-арт) отключается. * ``autocompleter``: Экземпляр класса :ref:`AutoCompleter `, отвечающий за автодополнение команд. - * ``print_func``: Функция для вывода всех системных сообщений (по умолчанию ``rich.Console().print``). + * ``printer``: Функция для вывода всех системных сообщений. ----- diff --git a/docs/root/api/orchestrator/argparser.rst b/docs/root/api/orchestrator/argparser.rst index 60eb582..e28c097 100644 --- a/docs/root/api/orchestrator/argparser.rst +++ b/docs/root/api/orchestrator/argparser.rst @@ -84,3 +84,8 @@ ArgParser $ python app.py --old-param value Warning: argument --old-param is deprecated + +.. warning:: + + Параметр поддерживается начиная с версии CPython 3.13, если версия ниже, то параметр будет игнорироваться. + diff --git a/docs/root/overriding_formatting.rst b/docs/root/overriding_formatting.rst index 1d279af..f67a92c 100644 --- a/docs/root/overriding_formatting.rst +++ b/docs/root/overriding_formatting.rst @@ -29,9 +29,9 @@ Кастомизация вывода ------------------- -Для полной замены логики вывода текста в конструкторе ``App`` предусмотрен параметр ``print_func``. +Для полной замены логики вывода текста в конструкторе ``App`` предусмотрен параметр ``printer``. -* **print_func**: ``Callable[[str], None]`` +* **printer**: ``Callable[[str], None]`` Этот параметр позволяет передать любую вызываемую сущность (например, функцию), которая будет использоваться для вывода всех системных сообщений. По умолчанию это ``rich.console.Console().print``. Вы можете передать сюда свою функцию, чтобы, например, логировать вывод в файл или отправлять его по сети. .. important::