This commit is contained in:
2025-10-28 09:38:07 +03:00
parent 7b40fff4c5
commit bc6cb583a7
49 changed files with 588 additions and 123 deletions
+4
View File
@@ -0,0 +1,4 @@
.. _root_api_command_flag:
Flag
=====
+216 -8
View File
@@ -3,17 +3,225 @@
Flags
======
.. _root_api_command_flag:
Объект ``Flags`` представляет собой коллекцию флагов команды в приложении ``Argenta``. Его основная задача — группировать и управлять набором флагов, зарегистрированных для конкретной команды. ``Flags`` служит контейнером, который позволяет удобно добавлять, извлекать и итерировать флаги, а также проверять их наличие.
Flag
=====
``Flags`` наследуется от базового класса ``BaseFlags`` и специализируется для работы с объектами типа ``Flag``. Этот класс используется при создании команд с множественными флагами и предоставляет интерфейс для управления ими.
.. seealso::
InputFlags
===========
Документация по отдельным флагам (:ref:`Flag <root_api_command_flag>`, :ref:`InputFlag <root_api_command_input_flag>`)
Документация по :ref:`InputFlags <root_api_command_input_flags>` — коллекции распаршенных флагов пользователя
:ref:`Общая информация <root_flags>` о флагах и их использовании в приложении ``Argenta``
-----
.. _root_api_command_input_flag:
Инициализация
-------------
InputFlag
==========
.. code-block:: python
:linenos:
__init__(self, flags: list[Flag] | None = None) -> None
Создает новую коллекцию флагов.
* ``flags`` : Необязательный список флагов типа ``Flag`` для инициализации коллекции. Если не указан, создается пустая коллекция.
**Атрибуты:**
.. py:attribute:: flags
Список всех зарегистрированных флагов типа ``Flag``. Пустой список, если флаги не были переданы при инициализации.
**Пример использования:**
.. literalinclude:: ../../../code_snippets/flags_snippet.py
:linenos:
:language: python
-----
Методы
------
add_flag
~~~~~~~~
.. code-block:: python
:linenos:
add_flag(self, flag: Flag) -> None
Добавляет один флаг в коллекцию.
:param flag: Флаг типа ``Flag`` для добавления в коллекцию
:return: None
Метод добавляет переданный флаг в конец списка ``flags``. Используется для динамического расширения набора флагов после создания коллекции.
**Пример использования:**
.. code-block:: python
:linenos:
from argenta import Flags, ValueFlag, BooleanFlag
# Создание коллекции
flags = Flags()
# Динамическое добавление флагов
flags.add_flag(ValueFlag("config", help="Config file path"))
flags.add_flag(BooleanFlag("debug", help="Debug mode"))
flags.add_flag(ValueFlag("log-level", possible_values=["INFO", "DEBUG", "ERROR"]))
print(len(flags.flags)) # 3
-----
add_flags
~~~~~~~~~
.. code-block:: python
:linenos:
add_flags(self, flags: list[Flag]) -> None
Добавляет список флагов в коллекцию.
:param flags: Список флагов типа ``Flag`` для добавления
:return: None
Метод расширяет текущую коллекцию, добавляя все флаги из переданного списка. Эффективен для пакетного добавления множества флагов.
**Пример использования:**
.. code-block:: python
:linenos:
from argenta import Flags, ValueFlag, BooleanFlag
# Начальная коллекция
flags = Flags([
ValueFlag("host", default="localhost")
])
# Дополнительные флаги
additional_flags = [
ValueFlag("port", default="8080"),
ValueFlag("database", help="Database name"),
BooleanFlag("ssl", help="Use SSL"),
BooleanFlag("verbose", help="Verbose output")
]
# Добавление списка флагов
flags.add_flags(additional_flags)
print(len(flags.flags)) # 5
-----
get_flag_by_name
~~~~~~~~~~~~~~~~
.. code-block:: python
:linenos:
get_flag_by_name(self, name: str) -> Flag | None
Получает флаг по его имени.
:param name: Имя искомого флага
:return: Объект ``Flag`` с указанным именем или ``None``, если флаг не найден
Метод выполняет поиск по списку ``flags`` и возвращает первый флаг с соответствующим именем. Если флаг не найден, возвращается ``None``.
**Пример использования:**
.. code-block:: python
:linenos:
from argenta import Flags, ValueFlag, BooleanFlag
flags = Flags([
ValueFlag("host", default="localhost"),
ValueFlag("port", default="8080"),
BooleanFlag("verbose")
])
# Получение флага по имени
host_flag = flags.get_flag_by_name("host")
if host_flag:
print(f"Found flag: {host_flag.name}")
print(f"Default value: {host_flag.default}")
# Поиск несуществующего флага
unknown_flag = flags.get_flag_by_name("nonexistent")
if unknown_flag is None:
print("Flag not found")
-----
Магические методы
-----------------
__iter__
~~~~~~~~
.. code-block:: python
:linenos:
__iter__(self) -> Iterator[Flag]
Делает коллекцию итерируемой, позволяя использовать её в циклах.
:return: Итератор по списку флагов
**Пример использования:**
.. code-block:: python
:linenos:
from argenta import Flags, ValueFlag, BooleanFlag
flags = Flags([
ValueFlag("host", default="localhost"),
ValueFlag("port", default="8080"),
BooleanFlag("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}")
-----
__getitem__
~~~~~~~~~~~
.. code-block:: python
:linenos:
__getitem__(self, flag_index: int) -> Flag
Позволяет получать флаги по индексу.
:param flag_index: Индекс флага в списке
:return: Флаг с указанным индексом
**Пример использования:**
.. code-block:: python
:linenos:
from argenta import Flags, ValueFlag
flags = Flags([
ValueFlag("first"),
ValueFlag("second"),
ValueFlag("third")
+139 -8
View File
@@ -3,14 +3,145 @@
Command
=======
.. toctree::
:hidden:
Объект ``Command`` представляет собой основную единицу функциональности в приложении ``Argenta``. Каждая команда определяет конкретное действие, которое пользователь может выполнить, введя соответствующий триггер. Команды регистрируются в роутерах и образуют интерфейс взаимодействия с приложением.
``Command`` инкапсулирует всю необходимую информацию о команде: её триггер (ключевое слово для вызова), описание, набор флагов для настройки поведения и список псевдонимов для альтернативных способов вызова.
-----
Инициализация
-------------
.. code-block:: python
:linenos:
__init__(self, trigger: str, *,
description: str | None = None,
flags: Flag | Flags = DEFAULT_WITHOUT_FLAGS,
aliases: list[str] | None = None) -> None
Создает новую команду для регистрации в роутере.
* ``trigger`` : Строковый триггер команды, который пользователь должен ввести для её вызова. Это основной идентификатор команды в системе.
* ``description`` : Необязательное описание команды, объясняющее её назначение. Если не указано, используется значение по умолчанию ``"Command without description"``. Отображается в справке и списке доступных команд.
* ``flags`` : Набор флагов команды для настройки её поведения. Может быть одиночным объектом ``Flag`` или коллекцией ``Flags``. По умолчанию команда создается без флагов.
* ``aliases`` : Список строковых синонимов для основного триггера. Позволяет вызывать команду альтернативными способами. По умолчанию список пуст.
**Атрибуты:**
.. py:attribute:: trigger
Основной триггер команды в виде строки. Используется для идентификации команды при парсинге пользовательского ввода.
.. py:attribute:: description
Текстовое описание команды. Если не было передано при инициализации, содержит значение ``"Command without description"``.
.. py:attribute:: registered_flags
Объект ``Flags``, содержащий все зарегистрированные флаги команды. Автоматически конвертируется из одиночного ``Flag`` в коллекцию при инициализации.
.. py:attribute:: aliases
Список строк с альтернативными триггерами команды. Пустой список, если псевдонимы не заданы.
**Пример использования:**
.. literalinclude:: ../../../code_snippets/command_snippet.py
:linenos:
.. seealso ::
Подробнее про флаги: :ref:`Flags <root_api_command_flags>` и :ref:`Флаги вводимых команд <root_flags>`.
-----
Регистрация команд
------------------
Команды регистрируются в роутерах с помощью декоратора ``@router.command()``. После регистрации команда становится доступной пользователям для вызова.
**Базовый пример:**
.. literalinclude:: ../../../code_snippets/command_snippet2.py
:linenos:
**Команды с флагами:**
.. literalinclude:: ../../../code_snippets/command_snippet3.py
:linenos:
-----
Работа с псевдонимами
---------------------
Псевдонимы позволяют вызывать один и тот же хэндлер разными триггерами, сохраняя при этом флаги команды и описание.
**Пример с псевдонимами:**
.. code-block:: python
:linenos:
from argenta import Router, Command
router = Router(title="System")
@router.command(Command(
"shutdown",
description="Shutdown the system",
aliases=["poweroff", "halt", "stop"]
))
def handle_shutdown(response):
response.write("Shutting down the system...")
Теперь пользователь может вызвать команду любым из способов:
.. code-block:: bash
shutdown
poweroff
halt
stop
Все эти варианты выполнят одну и ту же функцию ``handle_shutdown``.
-----
flags
possible_values
validation_status
.. _input_command:
.. _root_api_command_input_command:
InputCommand
~~~~~~~~~~~~
------------
Класс ``InputCommand`` представляет собой распаршенную команду, введенную пользователем. Это внутренний класс, который создается автоматически при парсинге пользовательского ввода. Непосредственная работа с данным классом возможна при создании кастомного хэндлера для обработки неизвестных команд.
.. seealso ::
Подробнее про кастомные хэндлеры обработки исключений ввода :ref:`тут <root_error_handling>`
Создает экземпляр распарсенной команды.
:param trigger: Триггер команды, извлеченный из пользовательского ввода
:param input_flags: Флаги, переданные пользователем при вызове команды
**Атрибуты:**
.. py:attribute:: trigger
:no-index:
Строковый триггер команды, введенный пользователем.
.. py:attribute:: input_flags
Объект ``InputFlags``, содержащий все флаги, переданные с командой. Автоматически конвертируется из одиночного ``InputFlag`` в коллекцию.
.. toctree ::
:hidden:
flag
possible_values
input_flag
validation_status
flags
input_flags
+6
View File
@@ -0,0 +1,6 @@
.. _root_api_command_input_flag:
InputFlag
==========
Объект ``InputFlag`` представляет собой флаг команды, который принимает значение ввода от пользователя. Он наследуется от базового класса ``Flag`` и расширяет его функциональность, добавляя возможность указания типа ввода и обработки введенных данных.
+4
View File
@@ -0,0 +1,4 @@
.. _root_api_command_input_flags:
InputFlags
===========
+1 -16
View File
@@ -85,24 +85,9 @@ get_by_type
**Пример использования:**
.. code-block:: python
.. literalinclude:: ../../../code_snippets/argspace_snippet3.py
:linenos:
from argenta import BooleanArgument, ValueArgument
# Получение всех булевых флагов
boolean_flags = argspace.get_by_type(BooleanArgument)
print(f"Active flags: {[arg.name for arg in boolean_flags if arg.value]}")
# Получение всех аргументов со значениями
value_args = argspace.get_by_type(ValueArgument)
for arg in value_args:
print(f"{arg.name} = {arg.value}")
# Подсчет количества аргументов каждого типа
print(f"Boolean arguments: {len(argspace.get_by_type(BooleanArgument))}")
print(f"Value arguments: {len(argspace.get_by_type(ValueArgument))}")
-----
InputArgument
+1 -1
View File
@@ -116,7 +116,7 @@
Для переопределения стандартного поведения используется сеттер ``.set_unknown_command_handler(_: NonStandardBehaviorHandler[InputCommand])``,
протокол ``NonStandardBehaviorHandler[InputCommand]`` соответствует ``Callable[[InputCommand], None]``, то есть хэндлер должен быть вызываемым объектом,
к примеру функция или лямбда, которая принимает обязательный аргумент типа :ref:`InputCommand <input_command>` и ничего не возвращает.
к примеру функция или лямбда, которая принимает обязательный аргумент типа :ref:`InputCommand <root_api_command_input_command>` и ничего не возвращает.
Сэмпл кода, переопределяющего хэндлер ввода неизвестной команды: