From 19906c1b1bd68a0f0996af9b4a2ab6d9914497ba Mon Sep 17 00:00:00 2001 From: kolo Date: Tue, 2 Dec 2025 10:51:44 +0300 Subject: [PATCH] Update documentation and code snippets --- docs/code_snippets/flags/snippet.py | 10 +- docs/code_snippets/flags/snippet2.py | 4 +- docs/code_snippets/flags/snippet3.py | 5 +- docs/code_snippets/flags/snippet4.py | 3 +- docs/code_snippets/flags/snippet5.py | 12 -- docs/code_snippets/flags/snippet6.py | 12 -- docs/code_snippets/input_flags/snippet1.py | 11 +- docs/code_snippets/input_flags/snippet10.py | 11 +- docs/code_snippets/input_flags/snippet2.py | 8 +- docs/code_snippets/input_flags/snippet5.py | 26 ---- docs/code_snippets/input_flags/snippet6.py | 29 ---- docs/code_snippets/response/data_sharing.py | 25 +--- docs/code_snippets/response/snippet1.py | 4 - docs/code_snippets/response/snippet6.py | 13 +- .../validation_status/comprehensive.py | 39 ----- .../validation_status/input_flag.py | 18 --- .../validation_status/invalid.py | 15 -- .../validation_status/processing.py | 35 ----- .../validation_status/undefined.py | 15 -- docs/code_snippets/validation_status/valid.py | 13 -- docs/root/api/bridge.rst | 20 +-- docs/root/api/command/flags.rst | 62 ++------ docs/root/api/command/input_flags.rst | 134 +----------------- docs/root/api/command/validation_status.rst | 49 ++----- docs/root/api/response.rst | 20 ++- mock/mock_app/routers.py | 18 +-- pyproject.toml | 2 +- src/argenta/command/flag/flags/models.py | 3 + 28 files changed, 85 insertions(+), 531 deletions(-) delete mode 100644 docs/code_snippets/flags/snippet5.py delete mode 100644 docs/code_snippets/flags/snippet6.py delete mode 100644 docs/code_snippets/input_flags/snippet5.py delete mode 100644 docs/code_snippets/input_flags/snippet6.py delete mode 100644 docs/code_snippets/validation_status/comprehensive.py delete mode 100644 docs/code_snippets/validation_status/input_flag.py delete mode 100644 docs/code_snippets/validation_status/invalid.py delete mode 100644 docs/code_snippets/validation_status/processing.py delete mode 100644 docs/code_snippets/validation_status/undefined.py delete mode 100644 docs/code_snippets/validation_status/valid.py diff --git a/docs/code_snippets/flags/snippet.py b/docs/code_snippets/flags/snippet.py index 304ff65..5870f86 100644 --- a/docs/code_snippets/flags/snippet.py +++ b/docs/code_snippets/flags/snippet.py @@ -1,17 +1,11 @@ import re +from argenta.command import Command, Flag, Flags -from argenta import Command -from argenta.command import Flag, Flags - -# Создание коллекции с флагами flags = Flags( [ - Flag( - "host", possible_values=re.compile(r"^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$") - ), + Flag("host", possible_values=re.compile(r"^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$")), Flag("port", possible_values=re.compile(r"^\d{1,5}$")), ] ) -# Использование в команде cmd = Command("start", description="Start the server", flags=flags) diff --git a/docs/code_snippets/flags/snippet2.py b/docs/code_snippets/flags/snippet2.py index 6c3e6af..dd264d8 100644 --- a/docs/code_snippets/flags/snippet2.py +++ b/docs/code_snippets/flags/snippet2.py @@ -1,11 +1,9 @@ from argenta.command import Flag, Flags -# Создание коллекции flags: Flags = Flags() -# Динамическое добавление флагов flags.add_flag(Flag("config")) flags.add_flag(Flag("debug")) flags.add_flag(Flag("log-level", possible_values=["INFO", "DEBUG", "ERROR"])) -print(len(flags.flags)) # 3 +print(len(flags)) # 3 diff --git a/docs/code_snippets/flags/snippet3.py b/docs/code_snippets/flags/snippet3.py index 0514cb2..082247d 100644 --- a/docs/code_snippets/flags/snippet3.py +++ b/docs/code_snippets/flags/snippet3.py @@ -1,10 +1,8 @@ from argenta.command import Flag, Flags from argenta.command.flag.defaults import PredefinedFlags -# Начальная коллекция flags = Flags([PredefinedFlags.HOST]) -# Дополнительные флаги additional_flags = [ PredefinedFlags.PORT, Flag("database"), @@ -12,7 +10,6 @@ additional_flags = [ Flag("verbose"), ] -# Добавление списка флагов flags.add_flags(additional_flags) -print(len(flags.flags)) # 5 +print(len(flags)) # 5 diff --git a/docs/code_snippets/flags/snippet4.py b/docs/code_snippets/flags/snippet4.py index 30248cd..abd5a8c 100644 --- a/docs/code_snippets/flags/snippet4.py +++ b/docs/code_snippets/flags/snippet4.py @@ -1,14 +1,13 @@ from argenta.command import Flag, Flags from argenta.command.flag.defaults import PredefinedFlags + flags = Flags([PredefinedFlags.HOST, PredefinedFlags.PORT, Flag("verbose")]) -# Получение флага по имени host_flag = flags.get_flag_by_name("host") if host_flag: print(f"Found flag: {host_flag.name}") -# Поиск несуществующего флага unknown_flag = flags.get_flag_by_name("nonexistent") if unknown_flag is None: print("Flag not found") diff --git a/docs/code_snippets/flags/snippet5.py b/docs/code_snippets/flags/snippet5.py deleted file mode 100644 index b6577ab..0000000 --- a/docs/code_snippets/flags/snippet5.py +++ /dev/null @@ -1,12 +0,0 @@ -from argenta.command import Flag, Flags -from argenta.command.flag.defaults import PredefinedFlags - -flags = Flags([PredefinedFlags.HOST, PredefinedFlags.PORT, Flag("verbose")]) - -# Итерация по всем флагам -for flag in flags: - print(f"Flag: {flag.name} (type: {type(flag).__name__})") - -# Использование в list comprehension -flag_names = [flag.name for flag in flags] -print(f"All flags: {flag_names}") diff --git a/docs/code_snippets/flags/snippet6.py b/docs/code_snippets/flags/snippet6.py deleted file mode 100644 index 49645f9..0000000 --- a/docs/code_snippets/flags/snippet6.py +++ /dev/null @@ -1,12 +0,0 @@ -from argenta.command import Flag, Flags - -flags = Flags([Flag("first"), Flag("second"), Flag("third")]) - -print(flags[0].name) -# first - -print(flags[1].name) -# second - -print(flags[2].name) -# third diff --git a/docs/code_snippets/input_flags/snippet1.py b/docs/code_snippets/input_flags/snippet1.py index 99826cb..93d528f 100644 --- a/docs/code_snippets/input_flags/snippet1.py +++ b/docs/code_snippets/input_flags/snippet1.py @@ -1,22 +1,23 @@ from argenta import Command, Response, Router from argenta.command import Flag, Flags -router = Router(title="Example") +router = Router(title="Example") @router.command( Command( "example", description="Example command with flags", - flags=Flags([Flag("name"), Flag("age")]), + flags=Flags([ + Flag("name"), + Flag("age") + ]), ) ) def example_handler(response: Response): - # response.input_flags содержит коллекцию InputFlags input_flags = response.input_flags - # Проверяем наличие флагов if input_flags: - print(f"Received {len(input_flags.flags)} flag(s)") + print(f"Received {len(input_flags)} flag(s)") else: print("No flags provided") diff --git a/docs/code_snippets/input_flags/snippet10.py b/docs/code_snippets/input_flags/snippet10.py index 955a8c0..bf69913 100644 --- a/docs/code_snippets/input_flags/snippet10.py +++ b/docs/code_snippets/input_flags/snippet10.py @@ -1,5 +1,5 @@ from argenta import Command, Response, Router -from argenta.command import Flag, Flags +from argenta.command import Flag, Flags, InputFlag from argenta.command.flag import ValidationStatus router = Router(title="Comprehensive Example") @@ -21,12 +21,11 @@ router = Router(title="Comprehensive Example") def validate_handler(response: Response): input_flags = response.input_flags - # Итерируемся по всем флагам и проверяем их статусы print("Flag validation results:") - valid_flags = [] - invalid_flags = [] - undefined_flags = [] + valid_flags: list[InputFlag] = [] + invalid_flags: list[InputFlag] = [] + undefined_flags: list[InputFlag] = [] for flag in input_flags: if flag.status == ValidationStatus.VALID: @@ -39,13 +38,11 @@ def validate_handler(response: Response): undefined_flags.append(flag) print(f" ? {flag.string_entity}: {flag.input_value} (UNDEFINED)") - # Выводим сводку print("\nSummary:") print(f" Valid flags: {len(valid_flags)}") print(f" Invalid flags: {len(invalid_flags)}") print(f" Undefined flags: {len(undefined_flags)}") - # Обрабатываем только валидные флаги if valid_flags: print("\nProcessing valid flags:") for flag in valid_flags: diff --git a/docs/code_snippets/input_flags/snippet2.py b/docs/code_snippets/input_flags/snippet2.py index eeb2554..6d059b8 100644 --- a/docs/code_snippets/input_flags/snippet2.py +++ b/docs/code_snippets/input_flags/snippet2.py @@ -8,13 +8,16 @@ 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): input_flags = response.input_flags - # Получаем флаг по имени host_flag = input_flags.get_flag_by_name("host") port_flag = input_flags.get_flag_by_name("port") debug_flag = input_flags.get_flag_by_name("debug") @@ -28,7 +31,6 @@ def config_handler(response: Response): if debug_flag: print("Debug mode enabled") - # Если флаг не найден, get_flag_by_name вернёт None missing_flag = input_flags.get_flag_by_name("nonexistent") if missing_flag is None: print("Flag 'nonexistent' not found") diff --git a/docs/code_snippets/input_flags/snippet5.py b/docs/code_snippets/input_flags/snippet5.py deleted file mode 100644 index 6c69c68..0000000 --- a/docs/code_snippets/input_flags/snippet5.py +++ /dev/null @@ -1,26 +0,0 @@ -from argenta import Command, Response, Router -from argenta.command import Flag, Flags - -router = Router(title="Iterate Example") - - -@router.command( - Command( - "process", - description="Process with multiple flags", - flags=Flags([Flag("file"), Flag("format"), Flag("output")]), - ) -) -def process_handler(response: Response): - input_flags = response.input_flags - - # Итерируемся по всем введённым флагам - print("All flags:") - for flag in input_flags: - status_str = flag.status.name if flag.status else "None" - print(f" {flag.string_entity}: {flag.input_value} (status: {status_str})") - - # Также можно использовать enumerate для получения индексов - print("\nFlags with indices:") - for index, flag in enumerate(input_flags): - print(f" [{index}] {flag.name}: {flag.input_value}") diff --git a/docs/code_snippets/input_flags/snippet6.py b/docs/code_snippets/input_flags/snippet6.py deleted file mode 100644 index ff8481f..0000000 --- a/docs/code_snippets/input_flags/snippet6.py +++ /dev/null @@ -1,29 +0,0 @@ -from argenta import Command, Response, Router -from argenta.command import Flag, Flags - -router = Router(title="Index Access Example") - - -@router.command( - Command( - "example", - description="Example with indexed access", - flags=Flags([Flag("first"), Flag("second"), Flag("third")]), - ) -) -def example_handler(response: Response): - input_flags = response.input_flags - - # Получаем флаги по индексу - if len(input_flags.flags) > 0: - first_flag = input_flags[0] - print(f"First flag: {first_flag.name} = {first_flag.input_value}") - - if len(input_flags.flags) > 1: - second_flag = input_flags[1] - print(f"Second flag: {second_flag.name} = {second_flag.input_value}") - - # Можно использовать срез для получения нескольких флагов - if len(input_flags.flags) >= 2: - first_two = input_flags.flags[:2] - print(f"First two flags: {[f.name for f in first_two]}") diff --git a/docs/code_snippets/response/data_sharing.py b/docs/code_snippets/response/data_sharing.py index f9a92eb..38b6adc 100644 --- a/docs/code_snippets/response/data_sharing.py +++ b/docs/code_snippets/response/data_sharing.py @@ -2,44 +2,32 @@ from argenta import Router, Response, Command, DataBridge from argenta.command import Flag from argenta.di import FromDishka -# 1. Создаём роутер router = Router(title="Authentication") - -# 2. Определяем сервис и обработчики def authenticate_user(username: str) -> str: - """Возвращает фиктивный токен для пользователя.""" return f"token_for_{username}" @router.command(Command("login", flags=Flag("username"))) def login_handler(response: Response, data_bridge: FromDishka[DataBridge]): - """Обработчик для команды 'login'. Сохраняет токен в хранилище.""" username_flag = response.input_flags.get_flag_by_name("username") if not username_flag or not username_flag.input_value: - print( - "[red]Ошибка:[/red] необходимо указать имя пользователя с помощью флага --username." - ) + print("Ошибка необходимо указать имя пользователя с помощью флага --username.") return username = username_flag.input_value token = authenticate_user(username) - # Сохраняем токен в общем хранилище сессии data_bridge.update({"auth_token": token}) - print(f"[green]Успешный вход![/green] Пользователь '{username}' аутентифицирован.") + print(f"Успешный вход! Пользователь '{username}' аутентифицирован.") @router.command("get-profile") -def get_profile_handler(response: Response, data_bridge: FromDishka[DataBridge]): - """Обработчик для команды 'get-profile'. Использует токен из хранилища.""" - session_data = data_bridge.get_all() - token = session_data.get("auth_token") +def get_profile_handler(response: Response, data_bridge: FromDishka[DataBridge]) + token = data_bridge.get_by_key("auth_token") if not token: - print( - "[red]Ошибка:[/red] вы не аутентифицированы. Сначала выполните команду 'login'." - ) + print("Ошибка: вы не аутентифицированы. Сначала выполните команду 'login'.") return print(f"Загрузка профиля с использованием токена: [yellow]{token}[/yellow]") @@ -47,9 +35,8 @@ def get_profile_handler(response: Response, data_bridge: FromDishka[DataBridge]) @router.command("logout") def logout_handler(response: Response, data_bridge: FromDishka[DataBridge]): - """Обработчик для команды 'logout'. Очищает токен.""" try: data_bridge.delete_by_key("auth_token") - print("[green]Выход выполнен.[/green] Данные сессии очищены.") + print("Выход выполнен. Данные сессии очищены.") except KeyError: print("Вы и так не были аутентифицированы.") diff --git a/docs/code_snippets/response/snippet1.py b/docs/code_snippets/response/snippet1.py index ce605b8..90d34ad 100644 --- a/docs/code_snippets/response/snippet1.py +++ b/docs/code_snippets/response/snippet1.py @@ -6,10 +6,6 @@ router = Router(title="Example") @router.command(Command("greet", description="Greet the user")) def greet_handler(response: Response): - # response автоматически передаётся в обработчик - # response.status содержит статус валидации флагов - # response.input_flags содержит все введённые флаги - if response.status == ResponseStatus.ALL_FLAGS_VALID: print("Hello! All flags are valid.") else: diff --git a/docs/code_snippets/response/snippet6.py b/docs/code_snippets/response/snippet6.py index cc75a70..2f4751c 100644 --- a/docs/code_snippets/response/snippet6.py +++ b/docs/code_snippets/response/snippet6.py @@ -1,5 +1,6 @@ from argenta import Command, Response, Router from argenta.command import Flag, Flags +from argenta.command.flag import ValidationStatus from argenta.response import ResponseStatus router = Router(title="Flags Example") @@ -9,14 +10,15 @@ 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): - # Проверяем статус валидации флагов - print(f"Status: {response.status.value}") + print(f"Status: {response.status}") - # Работаем с флагами format_flag = response.input_flags.get_flag_by_name("format") verbose_flag = response.input_flags.get_flag_by_name("verbose") @@ -27,11 +29,10 @@ def process_handler(response: Response): if verbose_flag: print("Verbose mode enabled") - # Проверяем валидность флагов if response.status == ResponseStatus.ALL_FLAGS_VALID: print("All flags are valid, proceeding...") elif response.status == ResponseStatus.INVALID_VALUE_FLAGS: print("Warning: Some flags have invalid values") for flag in response.input_flags: - if flag.status and flag.status.name == "INVALID": + if flag.status == ValidationStatus.INVALID: print(f" Invalid flag: {flag.string_entity} = {flag.input_value}") diff --git a/docs/code_snippets/validation_status/comprehensive.py b/docs/code_snippets/validation_status/comprehensive.py deleted file mode 100644 index 7545fd1..0000000 --- a/docs/code_snippets/validation_status/comprehensive.py +++ /dev/null @@ -1,39 +0,0 @@ -import re - -from argenta.command.flag import Flag, InputFlag, PossibleValues, ValidationStatus - -# Создаём различные типы флагов -verbose_flag = Flag("verbose", possible_values=PossibleValues.NEITHER) -output_flag = Flag("output", possible_values=PossibleValues.ALL) -level_flag = Flag("level", possible_values=["1", "2", "3"]) -pattern_flag = Flag("pattern", possible_values=re.compile(r"^[a-zA-Z]+$")) - -# Создаём входные флаги с различными статусами -input_flags = [ - # Валидные флаги - InputFlag("verbose", input_value=None, status=ValidationStatus.VALID), - InputFlag("output", input_value="result.txt", status=ValidationStatus.VALID), - InputFlag("level", input_value="2", status=ValidationStatus.VALID), - InputFlag("pattern", input_value="onlyletters", status=ValidationStatus.VALID), - # Невалидные флаги - InputFlag("verbose", input_value="true", status=ValidationStatus.INVALID), - InputFlag("level", input_value="4", status=ValidationStatus.INVALID), - InputFlag("pattern", input_value="123", status=ValidationStatus.INVALID), - # Неопределённые флаги - InputFlag("unknown", input_value="value", status=ValidationStatus.UNDEFINED), -] - -# Обрабатываем все флаги -valid_count = invalid_count = undefined_count = 0 - -for flag in input_flags: - if flag.status == ValidationStatus.VALID: - valid_count += 1 - elif flag.status == ValidationStatus.INVALID: - invalid_count += 1 - elif flag.status == ValidationStatus.UNDEFINED: - undefined_count += 1 - -print(f"Валидных флагов: {valid_count}") -print(f"Невалидных флагов: {invalid_count}") -print(f"Неопределённых флагов: {undefined_count}") diff --git a/docs/code_snippets/validation_status/input_flag.py b/docs/code_snippets/validation_status/input_flag.py deleted file mode 100644 index c72a1b6..0000000 --- a/docs/code_snippets/validation_status/input_flag.py +++ /dev/null @@ -1,18 +0,0 @@ -from argenta import InputFlag, ValidationStatus - -# Создание входных флагов с различными статусами -valid_flag = InputFlag( - "output", input_value="/path/to/file.txt", status=ValidationStatus.VALID -) - -invalid_flag = InputFlag( - "count", input_value="not-a-number", status=ValidationStatus.INVALID -) - -undefined_flag = InputFlag( - "experimental", input_value="test", status=ValidationStatus.UNDEFINED -) - -flags = [valid_flag, invalid_flag, undefined_flag] -for flag in flags: - print(f"{flag.string_entity}: {flag.status.value}") diff --git a/docs/code_snippets/validation_status/invalid.py b/docs/code_snippets/validation_status/invalid.py deleted file mode 100644 index 6500364..0000000 --- a/docs/code_snippets/validation_status/invalid.py +++ /dev/null @@ -1,15 +0,0 @@ -from argenta.command.flag import Flag, InputFlag, PossibleValues, ValidationStatus - -# Создание флага без значения -help_flag = Flag("help", possible_values=PossibleValues.NEITHER) - -# Создание некорректного входного флага (передано значение, когда не должно быть) -invalid_input = InputFlag("help", input_value="please", status=ValidationStatus.INVALID) - -print(f"Флаг: {invalid_input.string_entity}") -print(f"Значение: {invalid_input.input_value}") -print(f"Статус: {invalid_input.status}") # Выведет: INVALID - -# Также невалидным будет флаг с недопустимым значением из списка -mode_flag = Flag("mode", possible_values=["fast", "slow"]) -invalid_mode = InputFlag("mode", input_value="medium", status=ValidationStatus.INVALID) diff --git a/docs/code_snippets/validation_status/processing.py b/docs/code_snippets/validation_status/processing.py deleted file mode 100644 index 6656c9a..0000000 --- a/docs/code_snippets/validation_status/processing.py +++ /dev/null @@ -1,35 +0,0 @@ -from argenta import InputFlag, ValidationStatus - - -def process_input_flag(input_flag: InputFlag) -> None: - """Обрабатывает входной флаг в зависимости от его статуса валидации""" - - if input_flag.status == ValidationStatus.VALID: - print(f"✓ Обрабатываем валидный флаг: {input_flag.string_entity}") - # Выполняем основную логику - execute_flag_logic(input_flag) - - elif input_flag.status == ValidationStatus.INVALID: - print(f"✗ Ошибка валидации флага: {input_flag.string_entity}") - # Записываем ошибку и прекращаем выполнение - log_validation_error(input_flag) - - elif input_flag.status == ValidationStatus.UNDEFINED: - print(f"? Неопределённый статус флага: {input_flag.string_entity}") - # Пытаемся провести валидацию или пропускаем - attempt_revalidation(input_flag) - - -def execute_flag_logic(flag: InputFlag) -> None: - """Выполняет логику для валидного флага""" - pass - - -def log_validation_error(flag: InputFlag) -> None: - """Записывает ошибку валидации в лог""" - pass - - -def attempt_revalidation(flag: InputFlag) -> None: - """Пытается повторно провести валидацию""" - pass diff --git a/docs/code_snippets/validation_status/undefined.py b/docs/code_snippets/validation_status/undefined.py deleted file mode 100644 index c827f04..0000000 --- a/docs/code_snippets/validation_status/undefined.py +++ /dev/null @@ -1,15 +0,0 @@ -from argenta import InputFlag, ValidationStatus - -# Создание входного флага без определения статуса -undefined_input = InputFlag( - "unknown-flag", input_value="some-value", status=ValidationStatus.UNDEFINED -) - -print(f"Флаг: {undefined_input.string_entity}") -print(f"Значение: {undefined_input.input_value}") -print(f"Статус: {undefined_input.status.value}") # Выведет: UNDEFINED - -# Или флаг, для которого валидация ещё не проводилась -pending_input = InputFlag( - "pending", input_value=None, status=ValidationStatus.UNDEFINED -) diff --git a/docs/code_snippets/validation_status/valid.py b/docs/code_snippets/validation_status/valid.py deleted file mode 100644 index c487f90..0000000 --- a/docs/code_snippets/validation_status/valid.py +++ /dev/null @@ -1,13 +0,0 @@ -from argenta.command.flag import Flag, InputFlag, ValidationStatus - -# Создание флага, который принимает только определённые значения -log_level_flag = Flag( - "log-level", possible_values=["debug", "info", "warning", "error"] -) - -# Создание корректного входного флага -valid_input = InputFlag("log-level", input_value="debug", status=ValidationStatus.VALID) - -print(f"Флаг: {valid_input.string_entity}") -print(f"Значение: {valid_input.input_value}") -print(f"Статус: {valid_input.status}") # Выведет: VALID diff --git a/docs/root/api/bridge.rst b/docs/root/api/bridge.rst index d674678..63be834 100644 --- a/docs/root/api/bridge.rst +++ b/docs/root/api/bridge.rst @@ -3,18 +3,20 @@ DataBridge ========== -`DataBridge` — это сущность, предоставляющая временное хранилище данных, которое существует в рамках одной сессии приложения (от запуска до выхода). Она предназначена для обмена данными между вызовами разных команд. +``DataBridge`` — это сущность, предоставляющая временное хранилище данных, которое существует в рамках одной сессии приложения (от запуска до выхода). Она предназначена для обмена данными между обработчиками. -Основной способ получения доступа к `DataBridge` — через систему внедрения зависимостей (DI). +Основной способ получения доступа к ``DataBridge`` — через ``di``. .. code-block:: python :linenos: from argenta.di import FromDishka from argenta import DataBridge, Response + + # ... setting up router and other def my_handler(response: Response, data_bridge: FromDishka[DataBridge]): - # ... ваш код + # ... your code **Практический пример: Аутентификация** @@ -26,9 +28,9 @@ DataBridge **Как это работает:** -1. При вызове обработчика `dishka` автоматически внедряет экземпляр `DataBridge`. -2. Команда ``login --username <имя>`` вызывает `login_handler`, который через внедрённый `data_bridge` сохраняет токен. -3. Команда `get-profile` вызывает `get_profile_handler`, который так же получает `data_bridge` и извлекает из него токен. +1. При вызове обработчика ``dishka`` автоматически внедряет экземпляр ``DataBridge``. +2. Команда ``login --username <имя>`` вызывает ``login_handler``, который через внедрённый ``data_bridge`` сохраняет токен. +3. Команда ``get-profile`` вызывает ``get_profile_handler``, который так же получает ``data_bridge`` и извлекает из него токен. API класса ----------- @@ -37,7 +39,7 @@ API класса .. py:method:: __init__(self, initial_data: dict | None = None) - Инициализирует хранилище. При использовании через DI вызывается автоматически. + Инициализирует хранилище. При использовании через ``di`` вызывается автоматически. .. py:method:: update(self, data: dict) -> None @@ -49,11 +51,11 @@ API класса .. py:method:: get_by_key(self, key: str) -> Any - Возвращает значение по ключу или `None`, если ключ не найден. + Возвращает значение по ключу или ``None``, если ключ не найден. .. py:method:: delete_by_key(self, key: str) -> None - Удаляет значение по ключу. Вызывает `KeyError`, если ключ не найден. + Удаляет значение по ключу. Вызывает ``KeyError``, если ключ не найден. .. py:method:: clear_all(self) -> None diff --git a/docs/root/api/command/flags.rst b/docs/root/api/command/flags.rst index 312862d..89fb525 100644 --- a/docs/root/api/command/flags.rst +++ b/docs/root/api/command/flags.rst @@ -3,9 +3,7 @@ Flags ====== -`Flags` — это коллекция флагов команды. Её основная задача — группировать и управлять набором флагов, зарегистрированных для конкретной команды. `Flags` служит контейнером, который позволяет удобно добавлять, извлекать, итерировать флаги и проверять их наличие. - -`Flags` наследуется от базового класса `BaseFlags` и специализируется на работе с объектами типа `Flag`. Этот класс используется при создании команд с несколькими флагами и предоставляет интерфейс для управления ими. +``Flags`` — это коллекция флагов команды. Её основная задача — группировать и управлять набором флагов, зарегистрированных для конкретной команды. ``Flags`` служит контейнером, который позволяет удобно добавлять, извлекать, итерировать флаги и проверять их наличие. .. seealso:: @@ -27,14 +25,14 @@ Flags Создаёт новую коллекцию флагов. -* ``flags``: Необязательный список флагов типа `Flag` для инициализации коллекции. Если не указан, создаётся пустая коллекция. +* ``flags``: Необязательный список флагов типа ``Flag`` для инициализации коллекции. Если не указан, создаётся пустая коллекция. **Атрибуты:** .. py:attribute:: flags :no-index: - Список всех зарегистрированных флагов типа `Flag`. Пуст, если флаги не были переданы при инициализации. + Список всех зарегистрированных флагов типа ``Flag``. **Пример использования:** @@ -57,10 +55,10 @@ add_flag Добавляет флаг в коллекцию. -:param flag: Флаг типа `Flag` для добавления. +:param flag: Флаг типа ``Flag`` для добавления. :return: None. -Метод добавляет флаг в конец списка `flags`. Используется для динамического расширения набора флагов. +Используется для динамического расширения набора флагов. **Пример использования:** @@ -80,7 +78,7 @@ add_flags Добавляет в коллекцию список флагов. -:param flags: Список флагов типа `Flag` для добавления. +:param flags: Список флагов типа ``Flag`` для добавления. :return: None. Метод расширяет коллекцию, добавляя в неё все флаги из переданного списка. Эффективен для пакетного добавления. @@ -104,56 +102,12 @@ get_flag_by_name Возвращает флаг по имени. :param name: Имя искомого флага. -:return: Объект `Flag` или `None`, если флаг не найден. +:return: Объект ``Flag`` или ``None``, если флаг не найден. -Метод выполняет поиск по списку `flags` и возвращает первый флаг с соответствующим именем. Если флаг не найден, возвращается `None`. +Метод возвращает флаг с соответствующим именем. Если флаг не найден, возвращается ``None``. **Пример использования:** .. literalinclude:: ../../../code_snippets/flags/snippet4.py :linenos: :language: python - ------ - -Магические методы ------------------ - -__iter__ -~~~~~~~~ - -.. code-block:: python - :linenos: - - __iter__(self) -> Iterator[Flag] - -Делает коллекцию итерируемой для использования в циклах. - -:return: Итератор по списку флагов. - -**Пример использования:** - -.. literalinclude:: ../../../code_snippets/flags/snippet5.py - :linenos: - :language: python - ------ - -__getitem__ -~~~~~~~~~~~ - -.. code-block:: python - :linenos: - - __getitem__(self, flag_index: int) -> Flag - -Позволяет получать флаг по индексу. - -:param flag_index: Индекс флага в списке. -:return: Флаг по указанному индексу. - -**Пример использования:** - -.. literalinclude:: ../../../code_snippets/flags/snippet6.py - :linenos: - :language: python diff --git a/docs/root/api/command/input_flags.rst b/docs/root/api/command/input_flags.rst index c6171de..782863c 100644 --- a/docs/root/api/command/input_flags.rst +++ b/docs/root/api/command/input_flags.rst @@ -3,9 +3,7 @@ InputFlags ========== -`InputFlags` — это коллекция флагов, введённых пользователем. Её основная задача — группировать и управлять набором флагов, переданных вместе с командой. `InputFlags` служит контейнером, который позволяет удобно извлекать, итерировать и проверять наличие флагов, а также работать с их значениями и статусами валидации. - -`InputFlags` наследуется от `BaseFlags` и специализируется на работе с объектами типа `InputFlag`. Этот класс создаётся автоматически при обработке пользовательского ввода и передаётся в обработчики команд через объект `Response`. +``InputFlags`` — это коллекция флагов, введённых пользователем. Её основная задача — группировать и управлять набором флагов, переданных вместе с командой. ``InputFlags`` служит контейнером, который позволяет удобно извлекать, итерировать и проверять наличие флагов, а также работать с их значениями и статусами валидации. .. seealso:: @@ -29,17 +27,17 @@ InputFlags Создаёт новую коллекцию введённых флагов. -* ``flags``: Необязательный список флагов типа `InputFlag` для инициализации коллекции. Если не указан, создаётся пустая коллекция. +* ``flags``: Необязательный список флагов типа ``InputFlag`` для инициализации коллекции. Если не указан, создаётся пустая коллекция. .. warning :: - Экземпляры этого класса обычно не создаются напрямую. Они автоматически формируются системой при обработке пользовательского ввода и доступны через атрибут `input_flags` объекта `Response`. + Экземпляры этого класса обычно не создаются напрямую. Они автоматически формируются системой при обработке пользовательского ввода и доступны через атрибут ``input_flags`` объекта ``Response``. **Атрибуты:** .. py:attribute:: flags :no-index: - Список всех введённых флагов типа `InputFlag`. Пуст, если флаги не были переданы при инициализации или пользователь не ввёл их с командой. + Список всех введённых флагов типа ``InputFlag``. Пуст, если флаги не были переданы при инициализации или пользователь не ввёл их с командой. **Пример использования:** @@ -60,12 +58,12 @@ get_flag_by_name get_flag_by_name(self, name: str) -> InputFlag | None -Возвращает введённый флаг по имени. +Возвращает флаг по имени. :param name: Имя искомого флага (без префикса). -:return: Объект `InputFlag` или `None`, если флаг не найден. +:return: Объект ``InputFlag`` или ``None``, если флаг не найден. -Метод выполняет поиск по списку `flags` и возвращает первый флаг с соответствующим именем (без учёта префикса). +Метод возвращает первый флаг с соответствующим именем (без учёта префикса). **Пример использования:** @@ -124,124 +122,6 @@ add_flags ----- -Магические методы ------------------ - -__iter__ -~~~~~~~~ - -.. code-block:: python - :linenos: - - __iter__(self) -> Iterator[InputFlag] - -Делает коллекцию итерируемой для использования в циклах. - -:return: Итератор по списку введённых флагов. - -Позволяет перебирать все введённые флаги, что полезно для проверки их статусов или пакетной обработки. - -**Пример использования:** - -.. literalinclude:: ../../../code_snippets/input_flags/snippet5.py - :linenos: - :language: python - ------ - -__getitem__ -~~~~~~~~~~~ - -.. code-block:: python - :linenos: - - __getitem__(self, flag_index: int) -> InputFlag - -Позволяет получать введённый флаг по индексу. - -:param flag_index: Индекс флага в списке. -:return: Флаг по указанному индексу. - -Позволяет обращаться к флагам по их позиции, что может быть полезно для их обработки в определённом порядке. - -**Пример использования:** - -.. literalinclude:: ../../../code_snippets/input_flags/snippet6.py - :linenos: - :language: python - ------ - -__bool__ -~~~~~~~~ - -.. code-block:: python - :linenos: - - __bool__(self) -> bool - -Определяет, содержит ли коллекция флаги. - -:return: `True`, если в коллекции есть хотя бы один флаг, иначе `False`. - -Позволяет проверять наличие флагов в команде для условной логики. - -**Пример использования:** - -.. literalinclude:: ../../../code_snippets/input_flags/snippet7.py - :linenos: - :language: python - ------ - -__eq__ -~~~~~~ - -.. code-block:: python - :linenos: - - __eq__(self, other: object) -> bool - -Сравнивает две коллекции введённых флагов на равенство. - -:param other: Объект для сравнения. -:return: `True`, если коллекции равны, иначе `False`. -:raises NotImplementedError: Если `other` не является экземпляром `InputFlags`. - -Две коллекции считаются равными, если они содержат одинаковое количество флагов и все соответствующие флаги равны (сравнение по имени, см. `InputFlag.__eq__`). - -**Пример использования:** - -.. literalinclude:: ../../../code_snippets/input_flags/snippet8.py - :linenos: - :language: python - ------ - -__contains__ -~~~~~~~~~~~~ - -.. code-block:: python - :linenos: - - __contains__(self, ingressable_item: object) -> bool - -Проверяет, содержится ли введённый флаг в коллекции. - -:param ingressable_item: Объект `InputFlag` для проверки. -:return: `True`, если флаг найден, иначе `False`. -:raises TypeError: Если `ingressable_item` не является экземпляром `InputFlag`. - -Позволяет использовать оператор `in` для проверки наличия флага в коллекции. - -**Пример использования:** - -.. literalinclude:: ../../../code_snippets/input_flags/snippet9.py - :linenos: - :language: python - ------ - Практические примеры -------------------- diff --git a/docs/root/api/command/validation_status.rst b/docs/root/api/command/validation_status.rst index a877022..9a22eca 100644 --- a/docs/root/api/command/validation_status.rst +++ b/docs/root/api/command/validation_status.rst @@ -3,17 +3,17 @@ ValidationStatus ================ -`ValidationStatus` — это перечисление (`Enum`), которое определяет состояние валидации флага. Его задача — предоставить стандартные константы для отображения результата проверки. `ValidationStatus` используется в атрибуте `status` класса `InputFlag`, чтобы сообщить, прошла ли валидация успешно. +``ValidationStatus`` — это перечисление, которое определяет состояние валидации флага. Его задача — предоставить стандартные константы для отображения результата проверки. ``ValidationStatus`` используется в атрибуте ``status`` класса ``InputFlag``. -`ValidationStatus` наследуется от `Enum` и содержит три значения: `VALID` (корректный флаг), `INVALID` (некорректный) и `UNDEFINED` (незарегистрированный). +``ValidationStatus`` содержит три значения: **VALID** (корректный флаг), **INVALID** (некорректный) и **UNDEFINED** (незарегистрированный). .. note:: - Статус валидации устанавливается автоматически при создании экземпляра `InputFlag` на основе правил, заданных в соответствующем `Flag`. + Статус валидации устанавливается автоматически при создании экземпляра ``InputFlag`` на основе правил, заданных в соответствующем ``Flag``. .. seealso:: - Документация по :ref:`InputFlag ` — класс введённого флага, использующий `ValidationStatus`. + Документация по :ref:`InputFlag ` — класс введённого флага, использующий ``ValidationStatus``. Документация по :ref:`Flag ` — класс флага с правилами валидации. @@ -21,9 +21,6 @@ ValidationStatus ----- -Значения enum -------------- - VALID ~~~~~ @@ -34,21 +31,15 @@ VALID Указывает, что флаг и его значение **прошли** валидацию. -Флаги с этим статусом соответствуют правилам, заданным в `possible_values` соответствующего `Flag`. Их можно безопасно использовать в логике приложения без дополнительных проверок. +Флаги с этим статусом соответствуют правилам, заданным в ``possible_values`` соответствующего ``Flag``. Их можно безопасно использовать в логике приложения без дополнительных проверок. **Условия получения статуса** ``VALID``: -* Флаг с `PossibleValues.NEITHER` передан без значения. -* Флаг с `PossibleValues.ALL` передан с любым значением или без него. +* Флаг с ``PossibleValues.NEITHER`` передан без значения. +* Флаг с ``PossibleValues.ALL`` передан с любым значением или без него. * Значение флага входит в список разрешённых. * Значение флага соответствует регулярному выражению. -**Пример использования:** - -.. literalinclude:: ../../../code_snippets/validation_status/valid.py - :linenos: - :language: python - ----- INVALID @@ -61,21 +52,15 @@ INVALID Указывает, что флаг или его значение **не прошли** валидацию. -Флаги с этим статусом нарушают правила, заданные в `possible_values` соответствующего `Flag`. Их следует обрабатывать как ошибочные. +Флаги с этим статусом нарушают правила, заданные в ``possible_values`` соответствующего ``Flag``. Их следует обрабатывать как ошибочные. **Условия получения статуса** ``INVALID``: -* Флаг с `PossibleValues.NEITHER` передан со значением. +* Флаг с ``PossibleValues.NEITHER`` передан со значением. * Значение флага не входит в список разрешённых. * Значение флага не соответствует регулярному выражению. * Флаг требует значение, но передан без него. -**Пример использования:** - -.. literalinclude:: ../../../code_snippets/validation_status/invalid.py - :linenos: - :language: python - ----- UNDEFINED @@ -91,19 +76,3 @@ UNDEFINED **Условия получения статуса** ``UNDEFINED``: * Введённый флаг не найден среди зарегистрированных для данной команды. - ------ - - -Практические примеры --------------------- - -Комплексный пример валидации -~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Пример демонстрирует использование всех статусов в реальном сценарии. - -.. literalinclude:: ../../../code_snippets/validation_status/comprehensive.py - :linenos: - :language: python - diff --git a/docs/root/api/response.rst b/docs/root/api/response.rst index 4759928..fd2ac27 100644 --- a/docs/root/api/response.rst +++ b/docs/root/api/response.rst @@ -3,7 +3,7 @@ Response ======== -`Response` — это объект, который передаётся в обработчик команды. Он создаётся автоматически при обработке пользовательского ввода и содержит статус валидации, введённые флаги. +``Response`` — это объект, который передаётся в обработчик команды. Он создаётся автоматически при обработке пользовательского ввода и содержит статус валидации, введённые флаги. .. seealso:: @@ -23,15 +23,14 @@ Response :linenos: __init__( - self, - status: ResponseStatus, + self, status: ResponseStatus, input_flags: InputFlags = EMPTY_INPUT_FLAGS, ) Создаёт новый объект ответа. -* ``status``: Общий статус валидации флагов из перечисления `ResponseStatus`. -* ``input_flags``: Коллекция введённых флагов (`InputFlags`). По умолчанию — пустая. +* ``status``: Общий статус валидации флагов из перечисления ``ResponseStatus``. +* ``input_flags``: Коллекция введённых флагов (``InputFlags``). По умолчанию — пустая. .. warning :: Экземпляры этого класса не предназначены для прямого создания. Они автоматически формируются системой и передаются в обработчик команды в качестве первого обязательного аргумента. @@ -41,12 +40,12 @@ Response .. py:attribute:: status :no-index: - Общий статус валидации всех флагов команды (`ResponseStatus`). Указывает, были ли среди введённых флагов некорректные или незарегистрированные. + Общий статус валидации всех флагов команды (``ResponseStatus``). Указывает, были ли среди введённых флагов некорректные или незарегистрированные. .. py:attribute:: input_flags :no-index: - Коллекция всех флагов, переданных с командой (`InputFlags`). Содержит все обработанные флаги с их значениями и статусами валидации. + Коллекция всех флагов, переданных с командой (``InputFlags``). Содержит все обработанные флаги с их значениями и статусами валидации. **Пример использования:** @@ -59,7 +58,7 @@ Response Работа с флагами ---------------- -`Response` предоставляет доступ к введённым флагам через атрибут `input_flags`. Вы можете проверять их наличие, получать значения и статусы валидации. +``Response`` предоставляет доступ к введённым флагам через атрибут ``input_flags``. Вы можете проверять их наличие, получать значения и статусы валидации. **Пример работы с флагами:** @@ -74,10 +73,7 @@ Response ResponseStatus -------------- -`ResponseStatus` — это перечисление (`Enum`), которое определяет общий статус валидации всех флагов команды. Используется в атрибуте `status` объекта `Response`. - -Значения enum -~~~~~~~~~~~~~ +``ResponseStatus`` — это перечисление, которое определяет общий статус валидации всех флагов команды. Используется в атрибуте ``status`` объекта ``Response``. ALL_FLAGS_VALID ~~~~~~~~~~~~~~~ diff --git a/mock/mock_app/routers.py b/mock/mock_app/routers.py index 735476f..d75a91f 100644 --- a/mock/mock_app/routers.py +++ b/mock/mock_app/routers.py @@ -1,18 +1,10 @@ -from argenta import Router, Response, Command -from argenta.command import Flags, Flag +from argenta import Command, Response, Router +from argenta.command import Flag, Flags work_router: Router = Router(title="Base points:", disable_redirect_stdout=True) -@work_router.command(Command - ( - 'hello', - flags=Flags( - Flag('test') - ), - description="Hello, world!" - ) -) +@work_router.command(Command("hello", flags=Flags(Flag("test")), description="Hello, world!")) def command_help(response: Response): - c = input("Enter your name: ") - print(f"Hello, {c}!") + c = input("Enter your name: ") + print(f"Hello, {c}!") diff --git a/pyproject.toml b/pyproject.toml index ec70feb..84906e8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -45,7 +45,7 @@ exclude = [ ".__pycache__", "tests" ] -line-length=100 +line-length=90 [tool.pyright] typeCheckingMode = "strict" diff --git a/src/argenta/command/flag/flags/models.py b/src/argenta/command/flag/flags/models.py index 6dd0206..4edb692 100644 --- a/src/argenta/command/flag/flags/models.py +++ b/src/argenta/command/flag/flags/models.py @@ -32,6 +32,9 @@ class BaseFlags(Generic[FlagType]): :return: None """ self.flags.extend(flags) + + def __len__(self) -> int: + return len(self.flags) def __iter__(self) -> Iterator[FlagType]: return iter(self.flags)