Update documentation and code snippets

This commit is contained in:
2025-12-02 10:51:44 +03:00
parent 2a96dfcabe
commit 19906c1b1b
28 changed files with 85 additions and 531 deletions
+2 -8
View File
@@ -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)
+1 -3
View File
@@ -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
+1 -4
View File
@@ -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
+1 -2
View File
@@ -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")
-12
View File
@@ -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}")
-12
View File
@@ -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
+6 -5
View File
@@ -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")
+4 -7
View File
@@ -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:
+5 -3
View File
@@ -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")
@@ -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}")
@@ -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]}")
+6 -19
View File
@@ -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("Вы и так не были аутентифицированы.")
-4
View File
@@ -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:
+7 -6
View File
@@ -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}")
@@ -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}")
@@ -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}")
@@ -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)
@@ -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
@@ -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
)
@@ -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
+11 -9
View File
@@ -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
+8 -54
View File
@@ -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
+7 -127
View File
@@ -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
-----
Практические примеры
--------------------
+9 -40
View File
@@ -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 <root_api_command_input_flag>` — класс введённого флага, использующий `ValidationStatus`.
Документация по :ref:`InputFlag <root_api_command_input_flag>` — класс введённого флага, использующий ``ValidationStatus``.
Документация по :ref:`Flag <root_api_command_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
+8 -12
View File
@@ -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
~~~~~~~~~~~~~~~
+5 -13
View File
@@ -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}!")
+1 -1
View File
@@ -45,7 +45,7 @@ exclude = [
".__pycache__",
"tests"
]
line-length=100
line-length=90
[tool.pyright]
typeCheckingMode = "strict"
+3
View File
@@ -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)