This commit is contained in:
2025-11-02 00:17:28 +03:00
parent acddb1fbc6
commit df7313912c
26 changed files with 501 additions and 566 deletions
+10 -16
View File
@@ -8,30 +8,24 @@ Argenta
**Библиотека для построения модульных CLI-приложений с простым и приятным API.** **Библиотека для построения модульных CLI-приложений с простым и приятным API.**
У вас есть некая функциональность и вы хотите распространять её в виде CLI? Argenta поможет вам. Если у вас есть функциональность, которую вы хотите предоставить в виде CLI-приложения, Argenta поможет вам в этом.
Основная цель библиотеки — дать возможность разработчикам сфокусироваться на реализации своих идей, предоставляя для этого удобные абстракции. Основная цель библиотеки — дать разработчикам возможность сосредоточиться на реализации своих идей, предоставляя для этого удобные абстракции.
.. image:: https://github.com/koloideal/Argenta/blob/main/imgs/mock_app_preview4.png?raw=True .. image:: https://github.com/koloideal/Argenta/blob/main/imgs/mock_app_preview4.png?raw=True
:alt: Пример приложения :alt: Пример приложения
Argenta нужна для создания приложений, которым необходим свой скоуп, то есть: при запуске приложения пользователь входит в абстрагированный скоуп, Argenta предназначена для создания приложений, работающих в собственном контексте (scope). Это означает, что при запуске пользователь входит в интерактивную сессию, где ему доступна вся реализованная вами функциональность.
в котором у него есть доступ к созданной функциональности.
Один из основных принципов библиотеки — это цикличность, это значит, что после ввода пользователем команды он не выходит из скоупа, в этом основное Один из ключевых принципов библиотеки — цикличность. После выполнения команды пользователь остаётся в интерактивной сессии, в отличие от таких библиотек, как ``argparse``, ``click`` и ``typer``. Выход из сессии контролируется самим пользователем.
отличие от таких библиотек, как ``argparse``, ``click`` и ``typer``. Выход из скоупа контролируется самим пользователем.
**Ключевые особенности:** **Ключевые особенности:**
* **Обработчики**. Объекты представления приложения, непосредственные обработчики введённых команд. Создание обработчиков максимально декларативно * **Обработчики (Handlers)**. Компоненты, отвечающие за исполнение введённых команд. Их создание максимально декларативно.
* **Маршрутизаторы**. Объекты маршрутизации, которые регистрируют обработчиков, позволяя создавать кастомные настройки для групп обработчиков, а также семантически их разделять. * **Маршрутизаторы (Routers)**. Регистрируют обработчики, позволяя группировать их и задавать общие настройки.
* **Приложение**. Объект управления жизненным циклом приложения, подключения созданных маршрутизаторов, конфигурирования различных вторичных утилит, таких как автокомплит, логирование и т.д. * **Приложение (App)**. Управляет жизненным циклом приложения, подключает маршрутизаторы и настраивает утилиты, такие как автодополнение и логирование.
* **Оркестратор**. Объект *оркестрации*, который конфигурирует, запускает и управляет всеми остальными компонентами программы. * **Оркестратор (Orchestrator)**. Конфигурирует, запускает и управляет всеми компонентами приложения.
* **Внедрение зависимостей**. ``Argenta`` нативно поддерживает ``dishka`` и предоставляет возможность инжектирования зависимостей в хэндлерах, разрешая типы, подробнее_. * **Внедрение зависимостей**. ``Argenta`` нативно поддерживает ``dishka``, что позволяет внедрять зависимости в обработчики по типам. `Подробнее <https://dishka.readthedocs.io/en/stable/di_intro.html>`_.
* **Флаги и аргументы**. Библиотека автоматически парсит и валидирует флаги и аргументы, переданные вместе с командой.
.. _подробнее: https://dishka.readthedocs.io/en/stable/di_intro.html
* **Поддержка флагов**. Библиотека поддерживает определение флагов, введённых вместе с командой, ``Argenta`` сама парсит и валидирует их, отдавая понятные сущности.
* **Поддержка аргументов**. Осуществлена поддержка аргументов командной строки, позволяющая пользователю передавать различные параметры при запуске приложения.
.. toctree:: .. toctree::
:hidden: :hidden:
+13 -13
View File
@@ -3,48 +3,48 @@
AutoCompleter AutoCompleter
===================== =====================
Объект ``AutoCompleter`` является компонентом ``Argenta``, отвечающим за интерактивное автодополнение команд. Его основная задача — улучшить опыт взаимодействия пользователя с командной строкой, предоставляя подсказки и автоматически завершая ввод на основе ранее введенных команд. Это значительно ускоряет работу и снижает вероятность опечаток. ``AutoCompleter`` — это компонент, отвечающий за интерактивное автодополнение команд. Он улучшает пользовательский опыт, предлагая подсказки и завершая ввод на основе истории команд, что ускоряет работу и снижает вероятность опечаток.
``AutoCompleter`` использует ``pyreadline3`` для имплементации ``readline GNU`` на ``Windows`` для управления историей команд и реализации логики автодополнения. ``AutoCompleter`` использует ``pyreadline3`` для реализации функциональности `GNU readline` в `Windows`, что позволяет управлять историей команд и автодополнением.
----- -----
Инициализация Инициализация
------------- -------------
.. code:: python .. code-block:: python
__init__(self, history_filename: str | None = None, __init__(self, history_filename: str | None = None,
autocomplete_button: str = "tab") -> None autocomplete_button: str = "tab") -> None
Создает и настраивает экземпляр ``AutoCompleter``. Создаёт и настраивает экземпляр ``AutoCompleter``.
* ``history_filename``: Имя файла для сохранения и загрузки истории команд. Если указано, история будет персистентной между сессиями приложения. Если **None**, история будет храниться только в памяти текущей сессии. * ``history_filename``: Имя файла для сохранения истории команд. Если указано, история будет сохраняться между сессиями. При значении `None` история хранится только в памяти.
* ``autocomplete_button``: Название клавиши, которая активирует автодополнение. По умолчанию используется клавиша **"tab"**. * ``autocomplete_button``: Клавиша, активирующая автодополнение. По умолчанию **Tab**.
----- -----
Назначение и возможности Назначение и возможности
------------------------- -------------------------
``AutoCompleter`` обладает следующими возможностями: Основные возможности ``AutoCompleter``:
* **Автодополнение по истории**: Основная логика автодополнения основана на истории команд, которые пользователь вводил ранее. Когда пользователь начинает вводить команду и нажимает клавишу автодополнения (по умолчанию **Tab**), система ищет в истории все команды, начинающиеся с введенного текста. * **Автодополнение по истории**: При нажатии клавиши автодополнения (по умолчанию **Tab**) система ищет в истории команды, начинающиеся с уже введённого текста.
* **Завершение по общему префиксу**: Если найдено несколько команд с общим префиксом, автодокомплитер подставит только общую часть. Например, если в истории есть команды ``show_users`` и ``show_profile``, при вводе ``sho`` и нажатии **Tab** будет подставлено ``show_``. * **Общий префикс**: Если найдено несколько команд с общим префиксом, будет подставлена только общая часть. Например, для команд ``show_users`` и ``show_profile`` при вводе ``sho`` и нажатии **Tab** ввод дополнится до ``show_``.
* **Персистентная история**: При указании параметра ``history_filename`` в конструкторе, вся история команд сохраняется в файл при выходе из приложения и загружается при следующем запуске. Это делает автодополнение со временем все более "умным" и персонализированным. * **Постоянная история**: Если указан ``history_filename``, история команд сохраняется в файл при выходе и загружается при следующем запуске. Это делает автодополнение со временем «умнее».
* **Очистка истории**: При сохранении истории ``AutoCompleter`` автоматически удаляет дубликаты и команды, которые больше не зарегистрированы в приложении, поддерживая актуальность и чистоту файла истории. * **Очистка истории**: При сохранении ``AutoCompleter`` удаляет дубликаты и более не существующие команды, поддерживая историю в актуальном состоянии.
* **Настройка клавиши активации**: Вы можете изменить клавишу, отвечающую за автодополнение, через параметр ``autocomplete_button``. * **Настройка клавиши**: Клавишу автодополнения можно изменить с помощью параметра ``autocomplete_button``.
----- -----
Пример использования Пример использования
-------------------- --------------------
``AutoCompleter`` передается как аргумент при инициализации `App`. ``AutoCompleter`` передаётся как аргумент при инициализации `App`.
.. literalinclude:: ../../../code_snippets/autocompleter/snippet.py .. literalinclude:: ../../../code_snippets/autocompleter/snippet.py
:language: python :language: python
+17 -18
View File
@@ -3,15 +3,14 @@
Dividing Lines Dividing Lines
============== ==============
Разделительные линии в ``Argenta`` играют важную роль в визуальном оформлении консольного интерфейса. Они используются для структурирования вывода, отделения блоков информации друг от друга (например, вывода команды от следующего приглашения к вводу). Разделительные линии в ``Argenta`` используются для визуального структурирования вывода и отделения блоков информации друг от друга. Библиотека предлагает два типа линий: статическую и динамическую.
Библиотека предлагает два подхода к управлению разделительными линиями: статический и динамический, каждый из которых имеет свои преимущества и сценарии использования.
---- ----
Класс ``StaticDividingLine`` Класс ``StaticDividingLine``
----------------------------- -----------------------------
``StaticDividingLine`` — это класс, который создает разделительную линию **фиксированной** длины. Длина и символ-заполнитель задаются при инициализации объекта. Этот тип линии полезен, когда вам нужен предсказуемый и унифицированный внешний вид интерфейса, независимо от содержимого вывода. ``StaticDividingLine`` создаёт разделительную линию **фиксированной** длины. Этот тип линии полезен для создания предсказуемого и унифицированного интерфейса.
.. code-block:: python .. code-block:: python
:linenos: :linenos:
@@ -19,28 +18,28 @@ Dividing Lines
def __init__(self, unit_part: str = "-", *, def __init__(self, unit_part: str = "-", *,
length: int = 25) -> None length: int = 25) -> None
Создает экземпляр статической разделительной линии. Создаёт экземпляр статической разделительной линии.
* ``unit_part``: Символ, который будет использоваться для построения линии. Учитывается только первый символ строки. По умолчанию: ``-``. * ``unit_part``: Символ для построения линии (учитывается только первый символ). По умолчанию: ``-``.
* ``length``: Целое число, определяющее фиксированную длину линии в символах. Является keyword-only аргументом. По умолчанию: ``25``. * ``length``: Фиксированная длина линии (keyword-only аргумент). По умолчанию: ``25``.
----- -----
Класс ``DynamicDividingLine`` Класс ``DynamicDividingLine``
------------------------------ ------------------------------
``DynamicDividingLine`` представляет собой более "умный" подход. Этот класс создает линию, длина которой **динамически** подстраивается под самую длинную строку, выведенную в консоль, в рамках выполнения одной команды. Это достигается за счет механизма перехвата `stdout`. В результате разделительные линии всегда идеально обрамляют выводимый контент, что выглядит очень аккуратно. ``DynamicDividingLine`` создаёт линию, длина которой **динамически** подстраивается под самую длинную строку в выводе команды. Это требует перехвата `stdout`, в результате чего разделители идеально обрамляют выводимый контент.
.. code-block:: python .. code-block:: python
:linenos: :linenos:
__init__(self, unit_part: str = "-") -> None __init__(self, unit_part: str = "-") -> None
Создает экземпляр динамической разделительной линии. Создаёт экземпляр динамической разделительной линии.
* ``unit_part``: Символ, который будет использоваться для построения линии. По умолчанию: ``-``. * ``unit_part``: Символ для построения линии. По умолчанию: ``-``.
Длина для этой линии не задается при инициализации, так как она вычисляется автоматически во время выполнения. Длина вычисляется автоматически и не задаётся при инициализации.
.. warning:: .. warning::
Обязательно почитайте про нюансы использования динамических линий и перехвата ``stdout`` в :ref:`этом разделе<root_redirect_stdout>`. Обязательно почитайте про нюансы использования динамических линий и перехвата ``stdout`` в :ref:`этом разделе<root_redirect_stdout>`.
@@ -50,20 +49,20 @@ Dividing Lines
Назначение и использование Назначение и использование
-------------------------- --------------------------
Выбор между статической и динамической линией зависит от ваших потребностей в конкретном приложении или даже для конкретного ``Router``-а. Выбор между статической и динамической линией зависит от ваших задач.
* **StaticDividingLine** идеально подходит, если: * **StaticDividingLine** идеально подходит, если:
* Вам нужен строгий, консистентный дизайн. * Вам нужен строгий и консистентный дизайн.
* Вы используете роутеры с отключенным перехватом ``stdout`` (``disable_redirect_stdout=True``), так как в этом случае динамическое вычисление длины невозможно. * Вы используете роутеры с отключённым перехватом ``stdout`` (``disable_redirect_stdout=True``), где динамическое вычисление длины невозможно.
* **DynamicDividingLine** (используется по умолчанию) является предпочтительным выбором, если: * **DynamicDividingLine** (поведение по умолчанию) предпочтительный выбор, если:
* Вы хотите, чтобы интерфейс выглядел аккуратно и адаптивно. * Вы хотите, чтобы интерфейс был адаптивным.
* Вывод ваших команд имеет разную длину, и вы хотите, чтобы рамки всегда соответствовали контенту. * Вывод ваших команд имеет разную длину.
* В ваших хэндлерах нет ожидающих ``io`` операций. * В ваших обработчиках нет интерактивных операций ввода (например, ``input()``).
Тип разделительной линии для всего приложения задается при инициализации ``App`` через параметр ``dividing_line``. Тип разделителя для всего приложения задаётся при инициализации ``App`` через параметр ``dividing_line``.
----- -----
+38 -50
View File
@@ -3,14 +3,14 @@
App App
=== ===
Объект ``App`` является центральной сущностью библиотеки ``Argenta``. Он выступает в роли ядра вашего консольного приложения, отвечая за его конфигурацию, управление жизненным циклом, обработку команд и взаимодействие с пользователем. ``App`` координирует работу всех остальных компонентов, таких как роутеры, обработчики команд и системные сообщения. Объект ``App`` — это ядро вашего консольного приложения. Он отвечает за конфигурацию, управление жизненным циклом, обработку команд и взаимодействие с пользователем, координируя работу всех компонентов: роутеров, обработчиков и системных сообщений.
------ ------
Инициализация Инициализация
------------- -------------
.. code-block:: rust .. code-block:: python
:linenos: :linenos:
AVAILABLE_DIVIDING_LINES: TypeAlias = StaticDividingLine | DynamicDividingLine AVAILABLE_DIVIDING_LINES: TypeAlias = StaticDividingLine | DynamicDividingLine
@@ -35,19 +35,19 @@ App
autocompleter: AutoCompleter = DEFAULT_AUTOCOMPLETER, autocompleter: AutoCompleter = DEFAULT_AUTOCOMPLETER,
print_func: Printer = DEFAULT_PRINT_FUNC) -> None print_func: Printer = DEFAULT_PRINT_FUNC) -> None
Создает и настраивает экземпляр приложения ``Argenta``. Создаёт и настраивает экземпляр приложения.
* ``prompt``: Строка-приглашение, которая отображается перед вводом каждой команды. По умолчанию: **"What do you want to do?\\n\\n"**. * ``prompt``: Приглашение к вводу, отображаемое перед каждой командой.
* ``initial_message``: Приветственное сообщение, которое выводится при запуске приложения. * ``initial_message``: Сообщение, выводимое при запуске приложения.
* ``farewell_message``: Прощальное сообщение при завершении работы приложения. * ``farewell_message``: Сообщение, выводимое при выходе из приложения.
* ``exit_command``: Сущность команды, которая будет маркирована как команда для выхода из приложения. * ``exit_command``: Команда, используемая для выхода из приложения.
* ``system_router_title``: Заголовок для системного роутера, который содержит команду выхода и другие системные команды. * ``system_router_title``: Заголовок для системного роутера (содержит команду выхода).
* ``ignore_command_register``: Если **True** (по умолчанию), регистр введенных команд будет игнорироваться при поиске обработчика. * ``ignore_command_register``: Если ``True``, регистр команд игнорируется при поиске обработчика.
* ``dividing_line``: Объект, управляющий стилем разделительной линии. Может быть **StaticDividingLine** или **DynamicDividingLine**. * ``dividing_line``: Стиль разделительной линии (``StaticDividingLine`` или ``DynamicDividingLine``).
* ``repeat_command_groups``: Если **True** (по умолчанию), описание доступных команд будет выводиться перед каждым вводом. * ``repeat_command_groups``: Если ``True``, список доступных команд выводится перед каждым вводом.
* ``override_system_messages``: Если **True** (по умолчанию), стандартное форматирование системных сообщений (цвета, ASCII-арт) будет отключено. * ``override_system_messages``: Если ``True``, стандартное форматирование (цвета, ASCII-арт) отключается.
* ``autocompleter``: Объект, отвечающий за логику автодополнения команд. * ``autocompleter``: Объект, отвечающий за автодополнение команд.
* ``print_func``: Функция, используемая для вывода всех системных сообщений. По умолчанию используется ``rich.console.Console().print``. * ``print_func``: Функция для вывода всех системных сообщений (по умолчанию ``rich.print``).
----- -----
@@ -56,19 +56,19 @@ App
- .. py:method:: include_router(self, router: Router) -> None - .. py:method:: include_router(self, router: Router) -> None
Регистрирует один ``Router`` в приложении. Все команды, определенные в этом роутере, становятся доступными для вызова. Регистрирует роутер в приложении. Все команды из этого роутера становятся доступными для вызова.
:param router: Объект роутера, который нужно зарегистрировать. :param router: Экземпляр ``Router`` для регистрации.
- .. py:method:: include_routers(self, *routers: Router) -> None - .. py:method:: include_routers(self, *routers: Router) -> None
Регистрирует несколько роутеров одновременно. Является удобной оберткой над ``include_router``. Регистрирует несколько роутеров одновременно.
:param routers: Последовательность объектов ``Router`` для регистрации. :param routers: Последовательность экземпляров ``Router`` для регистрации.
- .. py:method:: add_message_on_startup(self, message: str) -> None - .. py:method:: add_message_on_startup(self, message: str) -> None
Добавляет дополнительное текстовое сообщение, которое будет выведено на экран при запуске приложения, сразу после `initial_message`. Добавляет текстовое сообщение, которое выводится при запуске приложения после `initial_message`.
:param message: Строка с сообщением. :param message: Строка с сообщением.
@@ -77,70 +77,58 @@ App
Методы установки обработчиков Методы установки обработчиков
------------------------------- -------------------------------
``App`` позволяет гибко настраивать реакцию на различные события, такие как ошибки ввода или ввод неизвестной команды. ``App`` позволяет настраивать реакцию на различные события, такие как ошибки ввода или неизвестные команды.
.. hint:: .. hint::
Подробнее о исключениях и их обработке в соответствующем :ref:`разделе документации <root_error_handling>`. Подробнее о исключениях и их обработке в соответствующем :ref:`разделе документации <root_error_handling>`.
----- -----
.. py:method:: set_description_message_pattern(self, handler: DescriptionMessageGenerator) -> None .. py:method:: set_description_message_pattern(self, handler: Callable[[str, str], str]) -> None
Устанавливает пользовательский шаблон для форматирования строки, описывающей доступную команду (триггер + описание). Устанавливает шаблон для форматирования строки описания команды.
``DescriptionMessageGenerator`` -> ``Callable[[str, str], str]`` Обработчик принимает триггер команды (``str``) и её описание (``str``), а возвращает отформатированную строку.
Где первый аргумент - это триггер команды, а второй - ее описание, возвращает строку, которая является форматированной строкой.
------ ------
.. py:method:: set_incorrect_input_syntax_handler(self, handler: NonStandardBehaviorHandler[str]) -> None .. py:method:: set_incorrect_input_syntax_handler(self, handler: Callable[[str], None]) -> None
Устанавливает обработчик, который вызывается при некорректном синтаксисе флагов в введенной команде. Устанавливает обработчик для некорректного синтаксиса флагов.
``NonStandardBehaviorHandler[str]`` -> ``Callable[[str], None]`` Обработчик принимает строку, введённую пользователем.
Где первый и единственный аргумент - это необработанная строка пользовательского ввода.
------ ------
.. py:method:: set_repeated_input_flags_handler(self, handler: NonStandardBehaviorHandler[str]) -> None .. py:method:: set_repeated_input_flags_handler(self, handler: Callable[[str], None]) -> None
Устанавливает обработчик для ситуации, когда пользователь вводит один и тот же флаг несколько раз. Устанавливает обработчик для повторяющихся флагов в команде.
``NonStandardBehaviorHandler[str]`` -> ``Callable[[str], None]`` Обработчик принимает строку, введённую пользователем.
Где первый и единственный аргумент - это необработанная строка пользовательского ввода.
------ ------
.. py:method:: set_unknown_command_handler(self, handler: NonStandardBehaviorHandler[InputCommand]) -> None .. py:method:: set_unknown_command_handler(self, handler: Callable[[InputCommand], None]) -> None
Устанавливает обработчик, который срабатывает, если введенная команда не была найдена ни в одном из зарегистрированных роутеров. Устанавливает обработчик для неизвестной команды.
``NonStandardBehaviorHandler[InputCommand]`` -> ``Callable[[InputCommand], None]`` Обработчик принимает объект ``InputCommand``.
Где первый и единственный аргумент - это распаршенный в объект InputCommand ввод пользователя.
----- -----
.. py:method:: set_empty_command_handler(self, handler: EmptyCommandHandler) -> None .. py:method:: set_empty_command_handler(self, handler: Callable[[], None]) -> None
Устанавливает обработчик для случая, когда пользователь отправляет пустую строку вместо команды. Устанавливает обработчик для пустого ввода.
``EmptyCommandHandler`` -> ``Callable[[], None]`` Обработчик не принимает аргументов.
Не принимает и не возвращает ничего.
----- -----
.. py:method:: set_exit_command_handler(self, handler: NonStandardBehaviorHandler[Response]) -> None .. py:method:: set_exit_command_handler(self, handler: Callable[[Response], None]) -> None
Позволяет переопределить стандартное поведение при вызове команды выхода. По умолчанию просто выводится ``farewell_message``. Переопределяет стандартное поведение при вызове команды выхода.
``NonStandardBehaviorHandler[Response]`` -> ``Callable[[Response], None]`` Обработчик принимает объект ``Response``.
Где первый и единственный аргумент - это объект ответа, ``Response``.
.. toctree:: .. toctree::
:hidden: :hidden:
+22 -22
View File
@@ -3,13 +3,13 @@
Flag Flag
===== =====
Объект ``Flag`` представляет собой сущность флага, регистрируемого для последующей обработки в приложении ``Argenta``. Его основная задача — определить параметры флага команды, включая имя, префикс и допустимые значения. ``Flag`` используется при создании команд с флагами и предоставляет механизм валидации входящих значений от пользователя. ``Flag`` — это сущность, описывающая флаг команды. Её основная задача — определить параметры флага, включая его имя, префикс и правила валидации. `Flag` используется при создании команд и предоставляет механизм для проверки значений, введённых пользователем.
.. seealso:: .. seealso::
Документация по :ref:`PossibleValues <root_api_command_possible_values>`сущность, определяющая допустимые значения флага. Документация по :ref:`PossibleValues <root_api_command_possible_values>`перечисление, определяющее типы допустимых значений.
Документация по :ref:`InputFlag <root_api_command_input_flag>` — объект распаршенного введённого флага. Документация по :ref:`InputFlag <root_api_command_input_flag>` — объект обработанного флага, введённого пользователем.
:ref:`Общая информация <root_flags>` о флагах и их использовании в приложении ``Argenta`` :ref:`Общая информация <root_flags>` о флагах и их использовании в приложении ``Argenta``
@@ -27,11 +27,11 @@ Flag
possible_values: list[str] | Pattern[str] | PossibleValues = PossibleValues.ALL, possible_values: list[str] | Pattern[str] | PossibleValues = PossibleValues.ALL,
) -> None ) -> None
Создает новый флаг для регистрации в команде. Создаёт новый флаг для регистрации в команде.
* ``name`` : Имя флага (обязательный параметр) * ``name``: Имя флага (обязательный параметр).
* ``prefix`` : Префикс флага. По умолчанию ``"--"``. Возможные значения: ``"-"``, ``"--"``, ``"---"`` * ``prefix``: Префикс флага (``-``, ``--``, ``---``). По умолчанию ``--``.
* ``possible_values`` : Допустимые значения флага. По умолчанию ``PossibleValues.ALL``. Может быть списком строк, регулярным выражением или значением из enum ``PossibleValues`` * ``possible_values``: Правила валидации значения. Может быть списком строк, регулярным выражением или значением из `PossibleValues`. По умолчанию `PossibleValues.ALL`.
**Атрибуты:** **Атрибуты:**
@@ -45,12 +45,12 @@ Flag
.. py:attribute:: possible_values .. py:attribute:: possible_values
Определяет допустимые значения для флага. Может быть: Определяет допустимые значения для флага:
* Списком строк флаг принимает только значения из этого списка * Список строк: флаг принимает только значения из этого списка.
* Регулярным выражением (``Pattern[str]``) — значение проверяется на соответствие паттерну * Регулярное выражение (`Pattern[str]`): значение проверяется на соответствие паттерну.
* Значением ``PossibleValues.ALL`` флаг принимает любое значение * `PossibleValues.ALL`: флаг принимает любое значение.
* Значением ``PossibleValues.NEITHER`` флаг не должен иметь значения * `PossibleValues.NEITHER`: флаг не должен иметь значения.
**Пример использования:** **Пример использования:**
@@ -72,11 +72,11 @@ string_entity
@property @property
string_entity(self) -> str string_entity(self) -> str
Возвращает строковое представление флага в формате ``prefix + name``. Возвращает строковое представление флага в формате `prefix + name`.
:return: Строковое представление флага :return: Строковое представление флага
Это свойство объединяет префикс и имя флага в единую строку, которая представляет, как флаг будет выглядеть в командной строке. Это свойство объединяет префикс и имя в единую строку, которая представляет флаг так, как он выглядел бы в командной строке.
**Пример использования:** **Пример использования:**
@@ -97,7 +97,7 @@ __str__
__str__(self) -> str __str__(self) -> str
Возвращает строковое представление флага (аналогично ``string_entity``). Возвращает строковое представление флага (аналогично `string_entity`).
:return: Строковое представление флага :return: Строковое представление флага
@@ -117,9 +117,9 @@ __repr__
__repr__(self) -> str __repr__(self) -> str
Возвращает отладочное представление объекта флага. Возвращает отладочное представление объекта.
:return: Строка в формате ``Flag<prefix=..., name=...>`` :return: Строка в формате `Flag<prefix=..., name=...>`.
**Пример использования:** **Пример использования:**
@@ -137,13 +137,13 @@ __eq__
__eq__(self, other: object) -> bool __eq__(self, other: object) -> bool
Сравнивает два флага на равенство по их строковому представлению. Сравнивает два флага на равенство по их строковому представлению (`string_entity`).
:param other: Объект для сравнения :param other: Объект для сравнения
:return: ``True``, если флаги равны, иначе ``False`` :return: ``True``, если флаги равны, иначе ``False``
:raises NotImplementedError: Если ``other`` не является экземпляром ``Flag`` :raises NotImplementedError: Если `other` не является экземпляром `Flag`.
Два флага считаются равными, если их ``string_entity`` идентичны. Два флага считаются равными, если их `string_entity` идентичны.
**Пример использования:** **Пример использования:**
@@ -160,9 +160,9 @@ PredefinedFlags
``argenta.command.flag.defaults.PredefinedFlags`` ``argenta.command.flag.defaults.PredefinedFlags``
Класс ``PredefinedFlags`` предоставляет набор предопределенных флагов, которые можно использовать в приложениях без необходимости их ручного создания. Эти флаги покрывают наиболее распространенные сценарии использования и следуют общепринятым соглашениям командной строки. Класс `PredefinedFlags` предоставляет набор готовых флагов для использования в приложениях без их ручного создания. Эти флаги покрывают наиболее распространённые сценарии и следуют общепринятым соглашениям.
Все предопределенные флаги являются атрибутами класса и представляют собой готовые экземпляры ``Flag``. Все предопределённые флаги являются атрибутами класса и представляют собой готовые экземпляры `Flag`.
----- -----
+24 -23
View File
@@ -3,15 +3,15 @@
Flags Flags
====== ======
Объект ``Flags`` представляет собой коллекцию флагов команды в приложении ``Argenta``. Его основная задача — группировать и управлять набором флагов, зарегистрированных для конкретной команды. ``Flags`` служит контейнером, который позволяет удобно добавлять, извлекать и итерировать флаги, а также проверять их наличие. `Flags` — это коллекция флагов команды. Её основная задача — группировать и управлять набором флагов, зарегистрированных для конкретной команды. `Flags` служит контейнером, который позволяет удобно добавлять, извлекать, итерировать флаги и проверять их наличие.
``Flags`` наследуется от базового класса ``BaseFlags`` и специализируется для работы с объектами типа ``Flag``. Этот класс используется при создании команд с множественными флагами и предоставляет интерфейс для управления ими. `Flags` наследуется от базового класса `BaseFlags` и специализируется на работе с объектами типа `Flag`. Этот класс используется при создании команд с несколькими флагами и предоставляет интерфейс для управления ими.
.. seealso:: .. seealso::
Документация по отдельным флагам (:ref:`Flag <root_api_command_flag>`, :ref:`InputFlag <root_api_command_input_flag>`) Документация по отдельным флагам (:ref:`Flag <root_api_command_flag>`, :ref:`InputFlag <root_api_command_input_flag>`)
Документация по :ref:`InputFlags <root_api_command_input_flags>` — коллекции распаршенных флагов пользователя Документация по :ref:`InputFlags <root_api_command_input_flags>` — коллекция обработанных флагов, введённых пользователем.
:ref:`Общая информация <root_flags>` о флагах и их использовании в приложении ``Argenta`` :ref:`Общая информация <root_flags>` о флагах и их использовании в приложении ``Argenta``
@@ -25,15 +25,16 @@ Flags
__init__(self, flags: list[Flag] | None = None) -> None __init__(self, flags: list[Flag] | None = None) -> None
Создает новую коллекцию флагов. Создаёт новую коллекцию флагов.
* ``flags`` : Необязательный список флагов типа ``Flag`` для инициализации коллекции. Если не указан, создается пустая коллекция. * ``flags``: Необязательный список флагов типа `Flag` для инициализации коллекции. Если не указан, создаётся пустая коллекция.
**Атрибуты:** **Атрибуты:**
.. py:attribute:: flags .. py:attribute:: flags
:no-index:
Список всех зарегистрированных флагов типа ``Flag``. Пустой список, если флаги не были переданы при инициализации. Список всех зарегистрированных флагов типа `Flag`. Пуст, если флаги не были переданы при инициализации.
**Пример использования:** **Пример использования:**
@@ -54,12 +55,12 @@ add_flag
add_flag(self, flag: Flag) -> None add_flag(self, flag: Flag) -> None
Добавляет один флаг в коллекцию. Добавляет флаг в коллекцию.
:param flag: Флаг типа ``Flag`` для добавления в коллекцию :param flag: Флаг типа `Flag` для добавления.
:return: None :return: None.
Метод добавляет переданный флаг в конец списка ``flags``. Используется для динамического расширения набора флагов после создания коллекции. Метод добавляет флаг в конец списка `flags`. Используется для динамического расширения набора флагов.
**Пример использования:** **Пример использования:**
@@ -77,12 +78,12 @@ add_flags
add_flags(self, flags: list[Flag]) -> None add_flags(self, flags: list[Flag]) -> None
Добавляет список флагов в коллекцию. Добавляет в коллекцию список флагов.
:param flags: Список флагов типа ``Flag`` для добавления :param flags: Список флагов типа `Flag` для добавления.
:return: None :return: None.
Метод расширяет текущую коллекцию, добавляя все флаги из переданного списка. Эффективен для пакетного добавления множества флагов. Метод расширяет коллекцию, добавляя в неё все флаги из переданного списка. Эффективен для пакетного добавления.
**Пример использования:** **Пример использования:**
@@ -100,12 +101,12 @@ get_flag_by_name
get_flag_by_name(self, name: str) -> Flag | None get_flag_by_name(self, name: str) -> Flag | None
Получает флаг по его имени. Возвращает флаг по имени.
:param name: Имя искомого флага :param name: Имя искомого флага.
:return: Объект ``Flag`` с указанным именем или ``None``, если флаг не найден :return: Объект `Flag` или `None`, если флаг не найден.
Метод выполняет поиск по списку ``flags`` и возвращает первый флаг с соответствующим именем. Если флаг не найден, возвращается ``None``. Метод выполняет поиск по списку `flags` и возвращает первый флаг с соответствующим именем. Если флаг не найден, возвращается `None`.
**Пример использования:** **Пример использования:**
@@ -126,9 +127,9 @@ __iter__
__iter__(self) -> Iterator[Flag] __iter__(self) -> Iterator[Flag]
Делает коллекцию итерируемой, позволяя использовать её в циклах. Делает коллекцию итерируемой для использования в циклах.
:return: Итератор по списку флагов :return: Итератор по списку флагов.
**Пример использования:** **Пример использования:**
@@ -146,10 +147,10 @@ __getitem__
__getitem__(self, flag_index: int) -> Flag __getitem__(self, flag_index: int) -> Flag
Позволяет получать флаги по индексу. Позволяет получать флаг по индексу.
:param flag_index: Индекс флага в списке :param flag_index: Индекс флага в списке.
:return: Флаг с указанным индексом :return: Флаг по указанному индексу.
**Пример использования:** **Пример использования:**
+21 -23
View File
@@ -3,9 +3,9 @@
Command Command
======= =======
Объект ``Command`` представляет собой основную единицу функциональности в приложении ``Argenta``. Каждая команда определяет конкретное действие, которое пользователь может выполнить, введя соответствующий триггер. Команды регистрируются в роутерах и образуют интерфейс взаимодействия с приложением. ``Command`` — это основная единица функциональности в приложении. Каждая команда определяет действие, которое пользователь может выполнить, введя соответствующий триггер. Команды регистрируются в роутерах и формируют интерфейс взаимодействия с приложением.
``Command`` инкапсулирует всю необходимую информацию о команде: её триггер (ключевое слово для вызова), описание, набор флагов для настройки поведения и список псевдонимов для альтернативных способов вызова. ``Command`` инкапсулирует всю информацию о команде: её триггер (ключевое слово для вызова), описание, набор флагов и список псевдонимов.
----- -----
@@ -20,33 +20,30 @@ Command
flags: Flag | Flags = DEFAULT_WITHOUT_FLAGS, flags: Flag | Flags = DEFAULT_WITHOUT_FLAGS,
aliases: list[str] | None = None) -> None aliases: list[str] | None = None) -> None
Создает новую команду для регистрации в роутере. Создаёт новую команду для регистрации в роутере.
* ``trigger`` : Строковый триггер команды, который пользователь должен ввести для её вызова. Это основной идентификатор команды в системе. * ``trigger``: Строковый триггер, который пользователь вводит для вызова команды. Является основным идентификатором.
* ``description``: Необязательное описание, объясняющее назначение команды. Отображается в справке.
* ``description`` : Необязательное описание команды, объясняющее её назначение. Если не указано, используется значение по умолчанию ``"Command without description"``. Отображается в справке и списке доступных команд. * ``flags``: Набор флагов для настройки поведения. Может быть одиночным объектом `Flag` или коллекцией `Flags`.
* ``aliases``: Список строковых псевдонимов для основного триггера.
* ``flags`` : Набор флагов команды для настройки её поведения. Может быть одиночным объектом ``Flag`` или коллекцией ``Flags``. По умолчанию команда создается без флагов.
* ``aliases`` : Список строковых синонимов для основного триггера. Позволяет вызывать команду альтернативными способами. По умолчанию список пуст.
**Атрибуты:** **Атрибуты:**
.. py:attribute:: trigger .. py:attribute:: trigger
Основной триггер команды в виде строки. Используется для идентификации команды при парсинге пользовательского ввода. Основной триггер команды. Используется для её идентификации при обработке пользовательского ввода.
.. py:attribute:: description .. py:attribute:: description
Текстовое описание команды. Если не было передано при инициализации, содержит значение ``"Command without description"``. Текстовое описание команды. Если не передано, используется значение по умолчанию.
.. py:attribute:: registered_flags .. py:attribute:: registered_flags
Объект ``Flags``, содержащий все зарегистрированные флаги команды. Автоматически конвертируется из одиночного ``Flag`` в коллекцию при инициализации. Объект `Flags`, содержащий все зарегистрированные флаги. Автоматически конвертируется из одиночного `Flag` в коллекцию при инициализации.
.. py:attribute:: aliases .. py:attribute:: aliases
Список строк с альтернативными триггерами команды. Пустой список, если псевдонимы не заданы. Список строковых псевдонимов. Пуст, если псевдонимы не заданы.
**Пример использования:** **Пример использования:**
@@ -61,7 +58,7 @@ Command
Регистрация команд Регистрация команд
------------------ ------------------
Команды регистрируются в роутерах с помощью декоратора ``@router.command()``. После регистрации команда становится доступной пользователям для вызова. Команды регистрируются в роутерах с помощью декоратора ``@router.command()``, после чего становятся доступными для вызова.
**Базовый пример:** **Базовый пример:**
@@ -78,7 +75,7 @@ Command
Работа с псевдонимами Работа с псевдонимами
--------------------- ---------------------
Псевдонимы позволяют вызывать один и тот же хэндлер разными триггерами, сохраняя при этом флаги команды и описание. Псевдонимы позволяют вызывать один и тот же обработчик разными триггерами, сохраняя флаги и описание команды.
**Пример с псевдонимами:** **Пример с псевдонимами:**
@@ -115,26 +112,27 @@ Command
InputCommand InputCommand
------------ ------------
Класс ``InputCommand`` представляет собой распаршенную команду, введенную пользователем. Это внутренний класс, который создается автоматически при парсинге пользовательского ввода. Непосредственная работа с данным классом возможна при создании кастомного хэндлера для обработки неизвестных команд. ``InputCommand`` представляет собой обработанную команду, введённую пользователем. Этот внутренний класс создаётся автоматически при обработке пользовательского ввода. Прямая работа с ним возможна при создании пользовательского обработчика для неизвестных команд.
.. seealso :: .. seealso ::
Подробнее про кастомные хэндлеры обработки исключений ввода :ref:`тут <root_error_handling>` Подробнее о пользовательских обработчиках исключений см. :ref:`здесь <root_error_handling>`.
Создает экземпляр распарсенной команды. Создаёт экземпляр обработанной команды.
:param trigger: Триггер команды, извлеченный из пользовательского ввода :param trigger: Триггер команды, извлечённый из пользовательского ввода.
:param input_flags: Флаги, переданные пользователем при вызове команды :param input_flags: Флаги, переданные пользователем.
**Атрибуты:** **Атрибуты:**
.. py:attribute:: trigger .. py:attribute:: trigger
:no-index: :no-index:
Строковый триггер команды, введенный пользователем. Строковый триггер, введённый пользователем.
.. py:attribute:: input_flags .. py:attribute:: input_flags
:no-index:
Объект ``InputFlags``, содержащий все флаги, переданные с командой. Автоматически конвертируется из одиночного ``InputFlag`` в коллекцию. Объект `InputFlags`, содержащий все переданные с командой флаги. Автоматически конвертируется из одиночного `InputFlag` в коллекцию.
.. toctree :: .. toctree ::
:hidden: :hidden:
+23 -22
View File
@@ -3,11 +3,11 @@
InputFlag InputFlag
========= =========
Объект ``InputFlag`` представляет собой сущность флага введённой команды. Он создаётся в результате парсинга пользовательского ввода и содержит информацию о распознанном флаге, включая его имя, префикс, введённое значение и статус валидации. Объект `InputFlag` представляет собой флаг, введённый пользователем. Он создаётся в результате обработки пользовательского ввода и содержит информацию о распознанном флаге: его имя, префикс, значение и статус валидации.
.. seealso:: .. seealso::
Документация по :ref:`Flag <root_api_command_flag>`сущность флага, регистрируемого для последующей обработки. Документация по :ref:`Flag <root_api_command_flag>`класс для регистрации флага.
Документация по :ref:`ValidationStatus <root_api_command_validation_status>` — статусы валидации флагов. Документация по :ref:`ValidationStatus <root_api_command_validation_status>` — статусы валидации флагов.
@@ -28,33 +28,34 @@ InputFlag
Создаёт новый объект введённого флага. Создаёт новый объект введённого флага.
* ``name`` : Имя введённого флага (обязательный параметр) * ``name``: Имя введённого флага.
* ``prefix`` : Префикс флага. По умолчанию ``"--"``. Возможные значения: ``"-"``, ``"--"``, ``"---"`` * ``prefix``: Префикс флага (``-``, ``--``, ``---``). По умолчанию ``--``.
* ``input_value`` : Значение введённого флага. Может быть ``None`` если флаг не принимает значения * ``input_value``: Значение, переданное с флагом. Может быть `None`.
* ``status`` : Статус валидации флага из перечисления ``ValidationStatus`` * ``status``: Статус валидации из перечисления `ValidationStatus`.
.. warning :: .. warning ::
Экземпляры класса не предназначены для их прямого создания, они содержаться в контейнере :ref:`Response <root_api_response>` Экземпляры этого класса не предназначены для прямого создания. Они содержатся в объекте :ref:`Response <root_api_response>`.
**Атрибуты:** **Атрибуты:**
.. py:attribute:: name .. py:attribute:: name
:no-index: :no-index:
Имя введённого флага в виде строки. Имя введённого флага.
.. py:attribute:: prefix .. py:attribute:: prefix
:no-index: :no-index:
Префикс флага. Один из: ``"-"``, ``"--"``, ``"---"``. Префикс флага: ``-``, ``--`` или ``---``.
.. py:attribute:: input_value .. py:attribute:: input_value
Значение, переданное с флагом в командной строке. Может быть ``None`` для флагов без значений. Значение, переданное с флагом. Может быть `None` для флагов без значений.
.. py:attribute:: status .. py:attribute:: status
:no-index:
Статус валидации флага. Один из: ``ValidationStatus.VALID``, ``ValidationStatus.INVALID``, ``ValidationStatus.UNDEFINED``. Статус валидации флага: `ValidationStatus.VALID`, `ValidationStatus.INVALID` или `ValidationStatus.UNDEFINED`.
**Пример использования:** **Пример использования:**
@@ -76,11 +77,11 @@ string_entity
@property @property
string_entity(self) -> str string_entity(self) -> str
Возвращает строковое представление флага в формате ``prefix + name``. Возвращает строковое представление флага в формате `prefix + name`.
:return: Строковое представление флага :return: Строковое представление флага
Это свойство объединяет префикс и имя флага в единую строку, которая представляет, как флаг был введён в командной строке. Это свойство объединяет префикс и имя в строку, представляющую флаг так, как он был введён в командной строке.
**Пример использования:** **Пример использования:**
@@ -101,9 +102,9 @@ __str__
__str__(self) -> str __str__(self) -> str
Возвращает строковое представление введённого флага вместе с его значением. Возвращает строковое представление флага вместе с его значением.
:return: Строка в формате ``флаг значение`` :return: Строка в формате `флаг значение`.
**Пример использования:** **Пример использования:**
@@ -121,9 +122,9 @@ __repr__
__repr__(self) -> str __repr__(self) -> str
Возвращает отладочное представление объекта введённого флага. Возвращает отладочное представление объекта.
:return: Строка в формате ``InputFlag<prefix=..., name=..., value=..., status=...>`` :return: Строка в формате `InputFlag<prefix=..., name=..., value=..., status=...>`.
**Пример использования:** **Пример использования:**
@@ -141,13 +142,13 @@ __eq__
__eq__(self, other: object) -> bool __eq__(self, other: object) -> bool
Сравнивает два введённых флага на равенство по их имени. Сравнивает два введённых флага на равенство по имени.
:param other: Объект для сравнения :param other: Объект для сравнения.
:return: ``True``, если имена флагов совпадают, иначе ``False`` :return: `True`, если имена флагов совпадают, иначе `False`.
:raises NotImplementedError: Если ``other`` не является экземпляром ``InputFlag`` :raises NotImplementedError: Если `other` не является экземпляром `InputFlag`.
Два введённых флага считаются равными, если их имена идентичны. Два введённых флага считаются равными, если их имена совпадают.
**Пример использования:** **Пример использования:**
+41 -40
View File
@@ -3,15 +3,15 @@
InputFlags InputFlags
========== ==========
Объект ``InputFlags`` представляет собой коллекцию введённых флагов команды в приложении ``Argenta``. Его основная задача — группировать и управлять набором флагов, которые были введены пользователем вместе с командой. ``InputFlags`` служит контейнером, который позволяет удобно извлекать, итерировать и проверять наличие введённых флагов, а также работать с их значениями и статусами валидации. `InputFlags` — это коллекция флагов, введённых пользователем. Её основная задача — группировать и управлять набором флагов, переданных вместе с командой. `InputFlags` служит контейнером, который позволяет удобно извлекать, итерировать и проверять наличие флагов, а также работать с их значениями и статусами валидации.
``InputFlags`` наследуется от базового класса ``BaseFlags`` и специализируется для работы с объектами типа ``InputFlag``. Этот класс автоматически создаётся системой при парсинге пользовательского ввода и передаётся в обработчики команд через объект ``Response``. `InputFlags` наследуется от `BaseFlags` и специализируется на работе с объектами типа `InputFlag`. Этот класс создаётся автоматически при обработке пользовательского ввода и передаётся в обработчики команд через объект `Response`.
.. seealso:: .. seealso::
Документация по отдельным флагам (:ref:`Flag <root_api_command_flag>`, :ref:`InputFlag <root_api_command_input_flag>`) Документация по отдельным флагам (:ref:`Flag <root_api_command_flag>`, :ref:`InputFlag <root_api_command_input_flag>`)
Документация по :ref:`Flags <root_api_command_flags>` — коллекции зарегистрированных флагов команды Документация по :ref:`InputFlags <root_api_command_input_flags>` — коллекция обработанных флагов, введённых пользователем.
Документация по :ref:`Response <root_api_response>` — объект ответа, содержащий ``InputFlags`` Документация по :ref:`Response <root_api_response>` — объект ответа, содержащий ``InputFlags``
@@ -27,18 +27,19 @@ InputFlags
__init__(self, flags: list[InputFlag] | None = None) -> None __init__(self, flags: list[InputFlag] | None = None) -> None
Создает новую коллекцию введённых флагов. Создаёт новую коллекцию введённых флагов.
* ``flags`` : Необязательный список введённых флагов типа ``InputFlag`` для инициализации коллекции. Если не указан, создается пустая коллекция. * ``flags``: Необязательный список флагов типа `InputFlag` для инициализации коллекции. Если не указан, создаётся пустая коллекция.
.. warning :: .. warning ::
Экземпляры класса обычно не создаются напрямую. Они автоматически формируются системой при парсинге пользовательского ввода и доступны через атрибут ``input_flags`` объекта ``Response`` в обработчиках команд. Экземпляры этого класса обычно не создаются напрямую. Они автоматически формируются системой при обработке пользовательского ввода и доступны через атрибут `input_flags` объекта `Response`.
**Атрибуты:** **Атрибуты:**
.. py:attribute:: flags .. py:attribute:: flags
:no-index:
Список всех введённых флагов типа ``InputFlag``. Пустой список, если флаги не были переданы при инициализации или пользователь не ввёл флагов с командой. Список всех введённых флагов типа `InputFlag`. Пуст, если флаги не были переданы при инициализации или пользователь не ввёл их с командой.
**Пример использования:** **Пример использования:**
@@ -59,12 +60,12 @@ get_flag_by_name
get_flag_by_name(self, name: str) -> InputFlag | None get_flag_by_name(self, name: str) -> InputFlag | None
Получает введённый флаг по его имени. Возвращает введённый флаг по имени.
:param name: Имя искомого флага (без префикса) :param name: Имя искомого флага (без префикса).
:return: Объект ``InputFlag`` с указанным именем или ``None``, если флаг не найден :return: Объект `InputFlag` или `None`, если флаг не найден.
Метод выполняет поиск по списку ``flags`` и возвращает первый флаг с соответствующим именем. Поиск происходит по атрибуту ``name`` объекта ``InputFlag``, сравнивая только имена флагов, без учёта префикса. Метод выполняет поиск по списку `flags` и возвращает первый флаг с соответствующим именем (без учёта префикса).
**Пример использования:** **Пример использования:**
@@ -82,15 +83,15 @@ add_flag
add_flag(self, flag: InputFlag) -> None add_flag(self, flag: InputFlag) -> None
Добавляет один введённый флаг в коллекцию. Добавляет введённый флаг в коллекцию.
:param flag: Флаг типа ``InputFlag`` для добавления в коллекцию :param flag: Флаг типа `InputFlag` для добавления.
:return: None :return: None.
Метод добавляет переданный флаг в конец списка ``flags``. Используется для динамического расширения набора флагов после создания коллекции. Метод добавляет флаг в конец списка `flags`. Используется для динамического расширения коллекции.
.. note:: .. note::
Этот метод используется редко, так как ``InputFlags`` обычно создаётся автоматически системой при парсинге пользовательского ввода. Однако он может быть полезен для тестирования или ручного создания коллекций флагов. Этот метод используется редко, так как `InputFlags` обычно создаётся автоматически. Однако он может быть полезен для тестирования или ручного создания коллекций.
**Пример использования:** **Пример использования:**
@@ -108,12 +109,12 @@ add_flags
add_flags(self, flags: list[InputFlag]) -> None add_flags(self, flags: list[InputFlag]) -> None
Добавляет список введённых флагов в коллекцию. Добавляет в коллекцию список введённых флагов.
:param flags: Список флагов типа ``InputFlag`` для добавления :param flags: Список флагов типа `InputFlag` для добавления.
:return: None :return: None.
Метод расширяет текущую коллекцию, добавляя все флаги из переданного списка. Эффективен для пакетного добавления множества флагов. Метод расширяет коллекцию, добавляя в неё все флаги из переданного списка. Эффективен для пакетного добавления.
**Пример использования:** **Пример использования:**
@@ -134,11 +135,11 @@ __iter__
__iter__(self) -> Iterator[InputFlag] __iter__(self) -> Iterator[InputFlag]
Делает коллекцию итерируемой, позволяя использовать её в циклах. Делает коллекцию итерируемой для использования в циклах.
:return: Итератор по списку введённых флагов :return: Итератор по списку введённых флагов.
Позволяет перебирать все введённые флаги команды, что особенно полезно для проверки статусов валидации или обработки всех флагов. Позволяет перебирать все введённые флаги, что полезно для проверки их статусов или пакетной обработки.
**Пример использования:** **Пример использования:**
@@ -156,12 +157,12 @@ __getitem__
__getitem__(self, flag_index: int) -> InputFlag __getitem__(self, flag_index: int) -> InputFlag
Позволяет получать введённые флаги по индексу. Позволяет получать введённый флаг по индексу.
:param flag_index: Индекс флага в списке :param flag_index: Индекс флага в списке.
:return: Флаг с указанным индексом :return: Флаг по указанному индексу.
Позволяет обращаться к флагам по их позиции в списке, что может быть полезно для обработки флагов в определённом порядке. Позволяет обращаться к флагам по их позиции, что может быть полезно для их обработки в определённом порядке.
**Пример использования:** **Пример использования:**
@@ -179,11 +180,11 @@ __bool__
__bool__(self) -> bool __bool__(self) -> bool
Определяет, содержит ли коллекция какие-либо флаги. Определяет, содержит ли коллекция флаги.
:return: ``True``, если в коллекции есть хотя бы один флаг, иначе ``False`` :return: `True`, если в коллекции есть хотя бы один флаг, иначе `False`.
Позволяет проверять наличие флагов в команде, что удобно для условной логики. Позволяет проверять наличие флагов в команде для условной логики.
**Пример использования:** **Пример использования:**
@@ -203,11 +204,11 @@ __eq__
Сравнивает две коллекции введённых флагов на равенство. Сравнивает две коллекции введённых флагов на равенство.
:param other: Объект для сравнения :param other: Объект для сравнения.
:return: ``True``, если коллекции равны, иначе ``False`` :return: `True`, если коллекции равны, иначе `False`.
:raises NotImplementedError: Если ``other`` не является экземпляром ``InputFlags`` :raises NotImplementedError: Если `other` не является экземпляром `InputFlags`.
Две коллекции считаются равными, если они содержат одинаковое количество флагов и все соответствующие флаги равны (сравнение происходит по правилам ``InputFlag.__eq__``, то есть по имени). Две коллекции считаются равными, если они содержат одинаковое количество флагов и все соответствующие флаги равны (сравнение по имени, см. `InputFlag.__eq__`).
**Пример использования:** **Пример использования:**
@@ -225,13 +226,13 @@ __contains__
__contains__(self, ingressable_item: object) -> bool __contains__(self, ingressable_item: object) -> bool
Проверяет, содержится ли указанный введённый флаг в коллекции. Проверяет, содержится ли введённый флаг в коллекции.
:param ingressable_item: Объект ``InputFlag`` для проверки :param ingressable_item: Объект `InputFlag` для проверки.
:return: ``True``, если флаг найден в коллекции, иначе ``False`` :return: `True`, если флаг найден, иначе `False`.
:raises TypeError: Если ``ingressable_item`` не является экземпляром ``InputFlag`` :raises TypeError: Если `ingressable_item` не является экземпляром `InputFlag`.
Позволяет использовать оператор ``in`` для проверки наличия флага в коллекции. Позволяет использовать оператор `in` для проверки наличия флага в коллекции.
**Пример использования:** **Пример использования:**
@@ -247,7 +248,7 @@ __contains__
Обработка всех флагов с проверкой статусов Обработка всех флагов с проверкой статусов
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Пример демонстрирует, как итерироваться по всем введённым флагам и проверять их статусы валидации: Пример демонстрирует итерацию по всем введённым флагам с проверкой их статусов валидации:
.. literalinclude:: ../../../code_snippets/input_flags/snippet10.py .. literalinclude:: ../../../code_snippets/input_flags/snippet10.py
:linenos: :linenos:
+15 -15
View File
@@ -4,18 +4,18 @@
PossibleValues PossibleValues
============== ==============
Enum ``PossibleValues`` представляет собой перечисление, определяющее специальные режимы валидации значений флагов в приложении ``Argenta``. Его основная задача — предоставить стандартизированные константы для управления поведением флагов в отношении допустимых значений. ``PossibleValues`` используется в параметре ``possible_values`` класса ``Flag`` для определения того, может ли флаг принимать значения и какие ограничения на них накладываются. `PossibleValues` — это перечисление (`Enum`), которое определяет специальные режимы валидации для значений флагов. Его задача — предоставить стандартные константы для управления поведением флагов. `PossibleValues` используется в параметре `possible_values` класса `Flag`, чтобы указать, может ли флаг принимать значения и какие ограничения на них накладываются.
``PossibleValues`` наследуется от стандартного класса ``Enum`` и содержит два основных значения: ``NEITHER`` для флагов без значений и ``ALL`` для флагов, принимающих любые значения. Этот enum используется совместно со списками строк и регулярными выражениями для создания гибкой системы валидации флагов. `PossibleValues` наследуется от `Enum` и содержит два основных значения: `NEITHER` (для флагов без значений) и `ALL` (для флагов, принимающих любые значения). Это перечисление используется вместе со списками строк и регулярными выражениями для создания гибкой системы валидации.
.. note:: .. note::
Результат валидации значений введенных флагов можно получить через атрибут ``status`` у экземпляра ``InputFlag``. Подробнее :ref:`тут <root_api_command_input_flag>` Результат валидации доступен через атрибут `status` у экземпляра `InputFlag`. Подробнее см. :ref:`здесь <root_api_command_input_flag>`.
.. seealso:: .. seealso::
Документация по :ref:`Flag <root_api_command_flag>`сущности флага, использующей ``PossibleValues`` Документация по :ref:`Flag <root_api_command_flag>`класс флага, использующий `PossibleValues`.
Документация по :ref:`PredefinedFlags <root_api_command_flag_predefined_flags>`предопределенным флагам с примерами использования ``PossibleValues`` Документация по :ref:`PredefinedFlags <root_api_command_flag_predefined_flags>`готовые флаги с примерами использования `PossibleValues`.
:ref:`Общая информация <root_flags>` о флагах и их использовании в приложении ``Argenta`` :ref:`Общая информация <root_flags>` о флагах и их использовании в приложении ``Argenta``
@@ -34,7 +34,7 @@ NEITHER
Указывает, что флаг **не должен** иметь значения. Указывает, что флаг **не должен** иметь значения.
Флаги с этим значением работают как булевы переключатели их наличие в командной строке само по себе является информацией. Попытка передать значение такому флагу приведёт к ошибке валидации. Флаги с этим значением работают как булевы переключатели: их наличие в командной строке само по себе является информацией. Попытка передать такому флагу значение приведёт к ошибке валидации.
**Примеры флагов с** ``NEITHER``: **Примеры флагов с** ``NEITHER``:
@@ -59,9 +59,9 @@ ALL
PossibleValues.ALL = 'ALL' PossibleValues.ALL = 'ALL'
Указывает, что флаг может принимать **любое** значение без ограничений. Указывает, что флаг может принимать **любое** значение.
Флаги с этим значением являются универсальными и не накладывают никаких ограничений на передаваемые данные. Валидация всегда успешна для любой строки или её отсутствия. Флаги с этим значением универсальны и не накладывают ограничений на передаваемые данные. Валидация всегда будет успешной.
**Примеры флагов с** ``ALL``: **Примеры флагов с** ``ALL``:
@@ -84,14 +84,14 @@ ALL
Параметр possible_values Параметр possible_values
~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~
``PossibleValues`` используется в качестве одного из возможных типов для параметра ``possible_values`` при создании экземпляра ``Flag``. `PossibleValues` используется как один из возможных типов для параметра `possible_values` при создании экземпляра `Flag`.
**Доступные типы для** ``possible_values``: **Доступные типы для** `possible_values`:
1. ``PossibleValues.NEITHER`` флаг без значения 1. `PossibleValues.NEITHER`: флаг без значения.
2. ``PossibleValues.ALL`` флаг с любым значением (по умолчанию) 2. `PossibleValues.ALL`: флаг с любым значением (по умолчанию).
3. ``list[str]`` флаг с ограниченным набором допустимых значений 3. `list[str]`: флаг с ограниченным набором значений.
4. ``Pattern[str]`` флаг со значением, проверяемым регулярным выражением 4. `Pattern[str]`: флаг со значением, проверяемым по регулярному выражению.
**Пример комбинированного использования:** **Пример комбинированного использования:**
@@ -104,7 +104,7 @@ ALL
Использование в PredefinedFlags Использование в PredefinedFlags
------------------------------- -------------------------------
Многие предопределенные флаги используют ``PossibleValues.NEITHER``: Многие предопределённые флаги используют `PossibleValues.NEITHER`:
.. literalinclude:: ../../../code_snippets/possible_values/predefined.py .. literalinclude:: ../../../code_snippets/possible_values/predefined.py
:linenos: :linenos:
+20 -20
View File
@@ -3,21 +3,21 @@
ValidationStatus ValidationStatus
================ ================
Enum ``ValidationStatus`` представляет собой перечисление, определяющее состояние валидации значений флагов в приложении ``Argenta``. Его основная задача — предоставить стандартизированные константы для отображения результата проверки введённых пользователем флагов и их значений. ``ValidationStatus`` используется в атрибуте ``status`` класса ``InputFlag`` для информирования о том, прошёл ли флаг валидацию успешно. `ValidationStatus` — это перечисление (`Enum`), которое определяет состояние валидации флага. Его задача — предоставить стандартные константы для отображения результата проверки. `ValidationStatus` используется в атрибуте `status` класса `InputFlag`, чтобы сообщить, прошла ли валидация успешно.
``ValidationStatus`` наследуется от стандартного класса ``Enum`` и содержит три основных значения: ``VALID`` для корректных флагов, ``INVALID`` для некорректных флагов и ``UNDEFINED`` для незарегистрированных флагов. `ValidationStatus` наследуется от `Enum` и содержит три значения: `VALID` (корректный флаг), `INVALID` (некорректный) и `UNDEFINED` (незарегистрированный).
.. note:: .. note::
Статус валидации устанавливается автоматически при создании экземпляра ``InputFlag`` на основе проверки через соответствующий ``Flag``. Статус валидации устанавливается автоматически при создании экземпляра `InputFlag` на основе правил, заданных в соответствующем `Flag`.
.. seealso:: .. seealso::
Документация по :ref:`InputFlag <root_api_command_input_flag>`сущности входного флага, использующей ``ValidationStatus`` Документация по :ref:`InputFlag <root_api_command_input_flag>`класс введённого флага, использующий `ValidationStatus`.
Документация по :ref:`Flag <root_api_command_flag>`сущности флага с методом валидации Документация по :ref:`Flag <root_api_command_flag>`класс флага с правилами валидации.
Документация по :ref:`PossibleValues <root_api_command_possible_values>` — типам допустимых значений флагов Документация по :ref:`PossibleValues <root_api_command_possible_values>` — типы допустимых значений.
----- -----
@@ -32,16 +32,16 @@ VALID
ValidationStatus.VALID = 'VALID' ValidationStatus.VALID = 'VALID'
Указывает, что флаг и его значение **прошли** валидацию успешно. Указывает, что флаг и его значение **прошли** валидацию.
Флаги с этим статусом полностью соответствуют правилам, заданным в параметре ``possible_values`` соответствующего ``Flag``. Такие флаги могут быть безопасно использованы в логике приложения без дополнительных проверок. Флаги с этим статусом соответствуют правилам, заданным в `possible_values` соответствующего `Flag`. Их можно безопасно использовать в логике приложения без дополнительных проверок.
**Условия получения статуса** ``VALID``: **Условия получения статуса** ``VALID``:
* Флаг с ``PossibleValues.NEITHER`` передан без значения * Флаг с `PossibleValues.NEITHER` передан без значения.
* Флаг с ``PossibleValues.ALL`` передан с любым значением или без него * Флаг с `PossibleValues.ALL` передан с любым значением или без него.
* Флаг со списком значений передан с одним из допустимых значений * Значение флага входит в список разрешённых.
* Флаг с регулярным выражением передан со значением, соответствующим паттерну * Значение флага соответствует регулярному выражению.
**Пример использования:** **Пример использования:**
@@ -61,14 +61,14 @@ INVALID
Указывает, что флаг или его значение **не прошли** валидацию. Указывает, что флаг или его значение **не прошли** валидацию.
Флаги с этим статусом нарушают правила, установленные в ``possible_values`` соответствующего ``Flag``. Такие флаги должны быть обработаны как ошибочные, и их использование может привести к некорректной работе приложения. Флаги с этим статусом нарушают правила, заданные в `possible_values` соответствующего `Flag`. Их следует обрабатывать как ошибочные.
**Условия получения статуса** ``INVALID``: **Условия получения статуса** ``INVALID``:
* Флаг с ``PossibleValues.NEITHER`` передан со значением * Флаг с `PossibleValues.NEITHER` передан со значением.
* Флаг со списком значений передан с недопустимым значением * Значение флага не входит в список разрешённых.
* Флаг с регулярным выражением передан со значением, не соответствующим паттерну * Значение флага не соответствует регулярному выражению.
* Флаг требует значение, но передан без него (для определённых типов валидации) * Флаг требует значение, но передан без него.
**Пример использования:** **Пример использования:**
@@ -86,11 +86,11 @@ UNDEFINED
ValidationStatus.UNDEFINED = 'UNDEFINED' ValidationStatus.UNDEFINED = 'UNDEFINED'
Указывает, что флаг был введён, но не зарегистрирован. Указывает, что введённый флаг не был зарегистрирован в команде.
**Условия получения статуса** ``UNDEFINED``: **Условия получения статуса** ``UNDEFINED``:
* Флаг был введён с любым значением, но не зарегистрирован * Введённый флаг не найден среди зарегистрированных для данной команды.
----- -----
@@ -101,7 +101,7 @@ UNDEFINED
Комплексный пример валидации Комплексный пример валидации
~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Пример демонстрирует использование всех статусов в реальном сценарии: Пример демонстрирует использование всех статусов в реальном сценарии.
.. literalinclude:: ../../../code_snippets/validation_status/comprehensive.py .. literalinclude:: ../../../code_snippets/validation_status/comprehensive.py
:linenos: :linenos:
+6 -6
View File
@@ -7,14 +7,14 @@
Описание раздела Описание раздела
---------------- ----------------
В данном разделе приводятся сведения о публичной части интерфейса библиотеки: В этом разделе описан публичный API библиотеки. Он включает:
- Классы и функции, предназначенные для прямой интеграции в сторонние приложения. - Классы и функции для интеграции в ваши приложения.
- Советы по совместимости, ограничения и поддерживаемые сценарии использования. - Рекомендации по использованию и поддерживаемые сценарии.
- Примеры типовой интеграции, подробные сигнатуры методов и описание возвращаемых сущностей. - Примеры кода, подробные сигнатуры и описание возвращаемых значений.
- Гарантии стабильности API, поддержка и обратная совместимость между версиями. - Гарантии стабильности и обратной совместимости.
Интерфейсы, не указанные в этом разделе, считаются внутренними и не подлежат использованию вне самой библиотеки. При разработке собственных решений рекомендуем обращаться именно к описанным здесь компонентам — это даст стабильность и гарантии на будущее развитие ваших продуктов с использованием ``Argenta``. Интерфейсы, не описанные в этом разделе, считаются внутренними. Их использование может привести к ошибкам при обновлении библиотеки. При разработке собственных решений используйте только компоненты, описанные здесь. Это обеспечит стабильность и совместимость ваших продуктов с будущими версиями ``Argenta``.
.. toctree:: .. toctree::
+10 -10
View File
@@ -3,7 +3,7 @@
ArgParser ArgParser
========== ==========
Объект ``ArgParser`` в ``Argenta`` предназначен для разбора и обработки **аргументов командной строки**, которые передаются вашему приложению при его запуске. Важно не путать их с флагами команд, которые пользователь вводит в интерактивном режиме работы приложения. ``ArgParser`` позволяет вашему приложению получать внешнюю конфигурацию в момент старта, например, путь к файлу настроек, флаги для отладки или режим запуска. ``ArgParser`` предназначен для обработки **аргументов командной строки**, передаваемых приложению при запуске. Важно не путать их с флагами, которые пользователь вводит в интерактивном режиме. ``ArgParser`` позволяет получать внешнюю конфигурацию в момент старта (например, путь к файлу настроек, флаги отладки или режим запуска).
----- -----
@@ -18,31 +18,31 @@ ArgParser
description: str = "Argenta available arguments", description: str = "Argenta available arguments",
epilog: str = "github.com/koloideal/Argenta | made by kolo") epilog: str = "github.com/koloideal/Argenta | made by kolo")
Создает экземпляр парсера аргументов командной строки. Создаёт экземпляр парсера аргументов командной строки.
* ``processed_args``: Список аргументов, которые будут обрабатываться и парситься при запуске приложения, подробнее :ref:`тут <root_api_orchestrator_arguments>`. * ``processed_args``: Список аргументов для обработки при запуске приложения. Подробнее см. :ref:`здесь <root_api_orchestrator_arguments>`.
* ``name``: Имя приложения, которое будет отображаться в справке. * ``name``: Имя приложения для отображения в справке.
* ``description``: Описание приложения, которое будет отображаться в справке. * ``description``: Описание приложения для отображения в справке.
* ``epilog``: Дополнительная информация, которая будет отображаться в конце справки. * ``epilog``: Дополнительная информация для отображения в конце справки.
Основные методы и атрибуты Основные методы и атрибуты
--------------------------- ---------------------------
.. py:attribute:: parsed_argspace: ArgSpace .. py:attribute:: parsed_argspace: ArgSpace
Экземпляр класса ``ArgSpace``, который содержит все обработанные аргументы командной строки, подробнее :ref:`тут <root_api_orchestrator_argspace>`. Экземпляр ``ArgSpace``, содержащий все обработанные аргументы командной строки. Подробнее см. :ref:`здесь <root_api_orchestrator_argspace>`.
.. caution:: .. caution::
До инициализации инстанса ``Orchestrator``, которому в конструктор был передан соответствующий экземпляр ``ArgParser``, атрибут ``parsed_argspace`` будет равен пустому ``ArgSpace``. До инициализации ``Orchestrator``, в конструктор которого был передан экземпляр ``ArgParser``, атрибут ``parsed_argspace`` будет содержать пустой ``ArgSpace``.
Парсинг и валидация аргументов командной строки происходит при инициализации ``Orchestrator``, соответственно использование атрибута ``parsed_argspace`` **целесообразно только после инициализации** ``Orchestrator``. Парсинг и валидация аргументов происходят при инициализации ``Orchestrator``, поэтому использовать ``parsed_argspace`` **целесообразно только после** этого.
----- -----
Лучшие практики Лучшие практики
------------------------ ------------------------
Использование атрибута ``parsed_argspace`` рекомендуется только на этапе настройки приложения, в хэндлерах лучшей практикой является получение ``ArgSpace`` через ``di``, подробнее :ref:`тут <root_dependency_injection>`. Использовать атрибут ``parsed_argspace`` рекомендуется только на этапе настройки приложения. В обработчиках лучшей практикой является получение ``ArgSpace`` через DI. Подробнее см. :ref:`здесь <root_dependency_injection>`.
Пример использования Пример использования
-------------------- --------------------
+16 -16
View File
@@ -3,9 +3,9 @@
ArgSpace ArgSpace
========== ==========
Объект ``ArgSpace`` является контейнером для хранения и управления распаршенными аргументами командной строки в приложении ``Argenta``. Его основная задача — предоставить удобный интерфейс для доступа к значениям аргументов, переданных при запуске приложения. ``ArgSpace`` — это контейнер для хранения и управления обработанными аргументами командной строки. Его основная задача — предоставить удобный интерфейс для доступа к значениям, переданным при запуске приложения.
``ArgSpace`` автоматически создается после парсинга аргументов через ``ArgParser`` и содержит коллекцию объектов ``InputArgument``, представляющих собой финальные значения всех переданных параметров командной строки. ``ArgSpace`` создаётся автоматически после обработки аргументов с помощью `ArgParser` и содержит коллекцию объектов `InputArgument`.
----- -----
@@ -17,15 +17,15 @@ ArgSpace
__init__(self, all_arguments: list[InputArgument]) -> None __init__(self, all_arguments: list[InputArgument]) -> None
Создает новое пространство аргументов. Создаёт новое пространство аргументов.
* ``all_arguments`` : Список распаршенных аргументов в виде объектов ``InputArgument``. Каждый элемент содержит имя, значение и тип исходного аргумента. * ``all_arguments``: Список обработанных аргументов в виде объектов `InputArgument`. Каждый элемент содержит имя, значение и тип исходного аргумента.
**Атрибуты:** **Атрибуты:**
.. py:attribute:: all_arguments .. py:attribute:: all_arguments
Список всех распаршенных аргументов типа ``InputArgument``. Содержит все аргументы, переданные при запуске приложения, включая значения по умолчанию для не указанных параметров. Список всех обработанных аргументов типа `InputArgument`, включая значения по умолчанию для не указанных параметров.
----- -----
@@ -40,12 +40,12 @@ get_by_name
get_by_name(self, name: str) -> InputArgument | None get_by_name(self, name: str) -> InputArgument | None
Возвращает аргумент по его имени. Возвращает аргумент по имени.
:param name: Имя искомого аргумента :param name: Имя искомого аргумента.
:return: Объект ``InputArgument`` с указанным именем или ``None``, если аргумент не найден :return: Объект `InputArgument` или `None`, если аргумент не найден.
Метод выполняет линейный поиск по списку ``all_arguments`` и возвращает аргумент с соответствующим именем. Если аргумент не найден, возвращается ``None``. Метод выполняет линейный поиск по списку `all_arguments`. Если аргумент не найден, возвращается `None`.
**Пример использования:** **Пример использования:**
@@ -76,12 +76,12 @@ get_by_type
get_by_type(self, arg_type: type[BaseArgument]) -> list[InputArgument] | list[Never] get_by_type(self, arg_type: type[BaseArgument]) -> list[InputArgument] | list[Never]
Получает все аргументы определенного типа. Возвращает все аргументы определённого типа.
:param arg_type: Тип аргумента (``BooleanArgument`` или ``ValueArgument``) :param arg_type: Тип аргумента (`BooleanArgument` или `ValueArgument`).
:return: Список аргументов указанного типа или пустой список, если аргументы не найдены :return: Список аргументов указанного типа или пустой список.
Метод фильтрует ``all_arguments`` по атрибуту ``founder_class`` каждого ``InputArgument`` и возвращает только те аргументы, которые были созданы из указанного типа. Метод фильтрует `all_arguments` по атрибуту `founder_class` и возвращает аргументы, созданные из указанного типа.
**Пример использования:** **Пример использования:**
@@ -94,21 +94,21 @@ InputArgument
------------- -------------
.. seealso :: .. seealso ::
Документация по ``InputArgument`` находится :ref:`тут <root_api_orchestrator_arguments_inputargument>` Документация по ``InputArgument`` находится :ref:`здесь <root_api_orchestrator_arguments_inputargument>`.
----- -----
Примеры испольования Примеры испольования
-------------------- --------------------
``ArgSpace`` используется для доступа к значениям аргументов после запуска приложения. Типичный сценарий работы включает парсинг аргументов через ``ArgParser`` и последующее извлечение значений из ``ArgSpace``. `ArgSpace` используется для доступа к значениям аргументов после запуска приложения. Типичный сценарий включает обработку аргументов через `ArgParser` и последующее извлечение значений из `ArgSpace`.
**Полный пример:** **Полный пример:**
.. literalinclude:: ../../../code_snippets/argspace/snippet.py .. literalinclude:: ../../../code_snippets/argspace/snippet.py
:linenos: :linenos:
Доступ к аргументам из хэндлеров осуществляется с помощью ``di``, подробнее :ref:`тут <root_dependency_injection>`. Доступ к аргументам из обработчиков осуществляется с помощью DI. Подробнее см. :ref:`здесь <root_dependency_injection>`.
.. literalinclude:: ../../../code_snippets/argspace/snippet2.py .. literalinclude:: ../../../code_snippets/argspace/snippet2.py
:linenos: :linenos:
+27 -27
View File
@@ -3,16 +3,16 @@
Arguments Arguments
========= =========
Модуль ``Arguments`` предоставляет набор классов для работы с аргументами командной строки при запуске приложения ``Argenta``. Эти аргументы позволяют настраивать поведение приложения на этапе его старта, передавая различные параметры конфигурации через интерфейс командной строки. Модуль ``Arguments`` предоставляет классы для работы с аргументами командной строки. Они позволяют настраивать поведение приложения в момент его запуска, передавая различные параметры конфигурации.
Аргументы регистрируются в ``ArgParser`` и парсятся при запуске приложения, становясь доступными через объект ``ArgSpace``. Аргументы регистрируются в `ArgParser` и после обработки становятся доступными в объекте `ArgSpace`.
----- -----
ValueArgument ValueArgument
------------- -------------
Класс для аргументов командной строки, требующих передачи значения. Используется для параметров конфигурации, которым необходимо указать конкретное значение при запуске приложения. Класс для аргументов, требующих передачи значения. Используется для параметров конфигурации, которым необходимо указать значение при запуске.
.. py:class:: ValueArgument(BaseArgument) .. py:class:: ValueArgument(BaseArgument)
@@ -27,15 +27,15 @@ ValueArgument
is_required: bool = False, is_required: bool = False,
is_deprecated: bool = False) -> None is_deprecated: bool = False) -> None
Создает аргумент командной строки, требующий значения. Создаёт аргумент командной строки, требующий значения.
:param name: Имя аргумента :param name: Имя аргумента
:param prefix: Префикс аргумента, по умолчанию ``--`` :param prefix: Префикс (по умолчанию ``--``)
:param help: Сообщение справки, отображаемое при ``--help`` :param help: Сообщение для справки (``--help``)
:param possible_values: Список допустимых значений для аргумента. Передается в параметр ``choices`` ArgumentParser :param possible_values: Список допустимых значений (передаётся в `choices` `ArgumentParser`)
:param default: Значение по умолчанию, используемое если аргумент не передан при запуске :param default: Значение по умолчанию, если аргумент не передан
:param is_required: Обязатялен ли аргумент. Если ``True``, приложение не запустится без этого аргумента :param is_required: Если ``True``, аргумент становится обязательным
:param is_deprecated: Является ли аргумент устаревшим :param is_deprecated: Если ``True``, помечает аргумент как устаревший
**Пример использования:** **Пример использования:**
@@ -83,7 +83,7 @@ ValueArgument
BooleanArgument BooleanArgument
--------------- ---------------
Класс для булевых аргументов командной строки, которые не требуют передачи значения. Наличие или отсутствие аргумента при запуске определяет состояние распаршенных аргументов(``True`` при наличии и ``False`` при отсутствии). Класс для булевых аргументов, не требующих значения. Их наличие при запуске устанавливает значение в `True`, отсутствие — в `False`.
.. py:class:: BooleanArgument(BaseArgument) .. py:class:: BooleanArgument(BaseArgument)
@@ -95,12 +95,12 @@ BooleanArgument
help: str = "Help message for the boolean argument", help: str = "Help message for the boolean argument",
is_deprecated: bool = False) -> None is_deprecated: bool = False) -> None
Создает булевый аргумент командной строки без значения. Создаёт булев аргумент командной строки без значения.
:param name: Имя аргумента :param name: Имя аргумента
:param prefix: Префикс аргумента, по умолчанию ``--`` :param prefix: Префикс (по умолчанию ``--``)
:param help: Сообщение справки, отображаемое при ``--help`` :param help: Сообщение для справки (``--help``)
:param is_deprecated: Является ли аргумент устаревшим :param is_deprecated: Если ``True``, помечает аргумент как устаревший
**Пример использования:** **Пример использования:**
@@ -147,9 +147,9 @@ InputArgument
------------- -------------
.. seealso:: .. seealso::
``InputArgument`` непосредственно связан и является наполнителем контейнера ``ArgSpace``, подробнее про него :ref:`тут <root_api_orchestrator_argspace>`. ``InputArgument`` напрямую связан с контейнером ``ArgSpace`` и является его наполнителем. Подробнее о нём см. :ref:`здесь <root_api_orchestrator_argspace>`.
Представляет собой распаршенный аргумент командной строки после запуска приложения. Этот класс используется внутри объекта ``ArgSpace`` для хранения значений аргументов, полученных при парсинге. Представляет собой обработанный аргумент командной строки. Этот класс используется внутри `ArgSpace` для хранения значений, полученных после парсинга.
.. py:class:: InputArgument .. py:class:: InputArgument
@@ -160,35 +160,35 @@ InputArgument
value: str | Literal[True], value: str | Literal[True],
founder_class: type[BaseArgument]) -> None founder_class: type[BaseArgument]) -> None
Создает экземпляр распарсенного входного аргумента. Создаёт экземпляр обработанного входного аргумента.
:param name: Имя аргумента :param name: Имя аргумента
:param value: Значение аргумента. Для ``BooleanArgument`` всегда ``True`` если флаг передан, для ``ValueArgument`` — строка со значением :param value: Значение аргумента. Для `BooleanArgument``True`, если флаг передан; для `ValueArgument` — строка со значением
:param founder_class: Класс-родитель, из которого был создан этот аргумент (``BooleanArgument`` или ``ValueArgument``) :param founder_class: Класс-родитель, из которого был создан аргумент (`BooleanArgument` или `ValueArgument`)
**Атрибуты:** **Атрибуты:**
.. py:attribute:: name .. py:attribute:: name
:no-index: :no-index:
Имя аргумента в виде строки. Соответствует имени, указанному при создании ``ValueArgument`` или ``BooleanArgument``. Имя аргумента, указанное при создании `ValueArgument` или `BooleanArgument`.
.. py:attribute:: value .. py:attribute:: value
Значение аргумента. Тип значения зависит от исходного класса аргумента: Значение аргумента. Тип зависит от исходного класса:
* Для ``BooleanArgument``: ``True`` если флаг был передан при запуске * Для `BooleanArgument`: `True`, если флаг был передан.
* Для ``ValueArgument``: строка с переданным значением или значением по умолчанию * Для `ValueArgument`: строка с переданным значением или значением по умолчанию
.. py:attribute:: founder_class .. py:attribute:: founder_class
Ссылка на класс, из которого был создан этот аргумент. Используется для определения типа аргумента и фильтрации в методе ``get_by_type()``. Ссылка на класс-родитель. Используется для определения типа и фильтрации в методе `get_by_type()`.
**Методы:** **Методы:**
.. py:method:: __str__() -> str .. py:method:: __str__() -> str
Возвращает строковое представление аргумента в формате ``InputArgument(name=value)``. Возвращает строковое представление в формате `InputArgument(name=value)`.
.. code-block:: python .. code-block:: python
:linenos: :linenos:
@@ -198,4 +198,4 @@ InputArgument
.. py:method:: __repr__() -> str .. py:method:: __repr__() -> str
Возвращает техническое представление объекта в виде строки. Возвращает техническое представление объекта.
+16 -17
View File
@@ -3,16 +3,16 @@
Orchestrator Orchestrator
==================== ====================
Объект ``Orchestrator`` в ``Argenta`` представляет собой высокоуровневый компонент, который стоит над ``App`` и отвечает за "оркестрацию" всего приложения. Его главная задача — инициализация и конфигурация сложных систем, таких как внедрение зависимостей (``di``), парсинг аргументов командной строки при запуске, и запуск основного цикла приложения. ``Orchestrator`` — это высокоуровневый компонент, который управляет жизненным циклом приложения. Его главная задача — инициализация и конфигурация окружения, включая внедрение зависимостей (DI), парсинг аргументов командной строки и запуск основного цикла `App`.
В то время как ``App`` отвечает за интерактивную сессию (ввод команд, роутинг), ``Orchestrator`` подготавливает окружение, в котором ``App`` будет работать. Он является точкой входа для приложений. В то время как `App` отвечает за логику интерактивной сессии (ввод команд, маршрутизация), `Orchestrator` подготавливает окружение для его работы и служит точкой входа в приложение.
----- -----
Инициализация Инициализация
------------- -------------
.. code-block:: rust .. code-block:: python
:linenos: :linenos:
DEFAULT_ARGPARSER: ArgParser = ArgParser(processed_args=[]) DEFAULT_ARGPARSER: ArgParser = ArgParser(processed_args=[])
@@ -25,11 +25,11 @@ Orchestrator
custom_providers: list[Provider] = [], custom_providers: list[Provider] = [],
auto_inject_handlers: bool = True) -> None auto_inject_handlers: bool = True) -> None
Создает и конфигурирует экземпляр ``Orchestrator``. Создаёт и конфигурирует экземпляр ``Orchestrator``.
* ``arg_parser``: Экземпляр :class:`argenta.orchestrator.argparser.ArgParser`, который отвечает за парсинг аргументов, переданных скрипту при запуске из командной строки (не путать с командами, вводимыми в интерактивном режиме). * ``arg_parser``: Экземпляр `ArgParser`, отвечающий за парсинг аргументов командной строки при запуске скрипта (не путать с командами в интерактивном режиме).
* ``custom_providers``: Список пользовательских провайдеров ``dishka.Provider``. Это основной механизм для добавления ваших собственных сервисов (например, подключений к базе данных, клиентов API) в контейнер внедрения зависимостей. * ``custom_providers``: Список пользовательских провайдеров `dishka.Provider` для добавления ваших сервисов (например, подключений к БД или API-клиентов) в DI-контейнер.
* ``auto_inject_handlers``: Если **True** (по умолчанию), ``dishka`` будет автоматически инспектировать сигнатуры обработчиков команд и внедрять в них требуемые зависимости из контейнера. * ``auto_inject_handlers``: Если `True` (по умолчанию), `dishka` автоматически внедрит зависимости в обработчики команд, инспектируя их сигнатуры.
----- -----
@@ -38,26 +38,25 @@ Orchestrator
.. py:method:: start_polling(self, app: App) -> None .. py:method:: start_polling(self, app: App) -> None
Это главный метод, который запускает все приложение. Он выполняет следующие шаги: Это главный метод, который запускает приложение. Он выполняет следующие шаги:
1. **Настройка DI**: На основе системного провайдера (``SystemProvider``, который предоставляет ``ArgParser``) и списка ``custom_providers`` создается ``ioc`` - контейнер и настраивается внедрение зависимостей. 1. **Настройка DI**: Создаёт DI-контейнер на основе системного провайдера (предоставляет `ArgParser`) и пользовательских `custom_providers`.
2. **Запуск основного цикла**: Запускает бесконечный цикл ожидания и обработки пользовательского ввода.
3. **Запуск основного цикла**: Запускает бесконечный цикл ожидания и обработки пользовательского ввода. :param app: Экземпляр `App`, который будет запущен.
:param app: Экземпляр класса :class:`~argenta.app.models.App`, который будет запущен.
----- -----
Назначение и использование Назначение и использование
---------------------------- ----------------------------
``Orchestrator`` абстрагирует от вас всю сложность, связанную с настройкой внедрения зависимостей и парсингом стартовых аргументов. Типичный сценарий использования ``Argenta`` выглядит следующим образом: ``Orchestrator`` абстрагирует сложность, связанную с настройкой DI и парсингом стартовых аргументов. Типичный сценарий использования выглядит так:
1. Создать экземпляр ``App`` и настроить его (добавить роутеры). 1. Создайте и настройте экземпляр `App` (добавьте роутеры).
2. Создать экземпляр ``Orchestrator``, передав в него необходимые DI-провайдеры и, возможно, парсер аргументов. 2. Создайте экземпляр `Orchestrator`, передав в него DI-провайдеры.
3. Вызвать ``orchestrator.start_polling(app)``, чтобы запустить приложение. 3. Вызовите `orchestrator.start_polling(app)`, чтобы запустить приложение.
Такой подход позволяет сохранить код чистым и разделяет ответственность: ``App`` отвечает за логику интерактивной сессии, а ``Orchestrator`` — за подготовку и запуск окружения. Такой подход разделяет ответственности: `App` отвечает за логику интерактивной сессии, а `Orchestrator` — за подготовку и запуск окружения.
Пример использования Пример использования
-------------------- --------------------
+23 -21
View File
@@ -3,9 +3,9 @@
Response Response
======== ========
Объект ``Response`` представляет собой сущность ответа пользовательского ввода, передаваемого в обработчик команды. Он создаётся автоматически при парсинге пользовательского ввода и содержит информацию о статусе валидации флагов, введённые флаги, а также предоставляет механизм для передачи данных между обработчиками команд через глобальное хранилище данных. `Response` — это объект, который передаётся в обработчик команды. Он создаётся автоматически при обработке пользовательского ввода и содержит статус валидации, введённые флаги, а также предоставляет механизм для обмена данными между обработчиками.
``Response`` наследуется от ``DataBridge``, который предоставляет методы для работы с глобальным хранилищем данных, позволяющим обмениваться данными между различными обработчиками команд в контексте приложения. `Response` наследует от `DataBridge` методы для работы с глобальным хранилищем, что позволяет обмениваться данными между обработчиками в рамках одной сессии.
.. seealso:: .. seealso::
@@ -29,23 +29,25 @@ Response
input_flags: InputFlags = EMPTY_INPUT_FLAGS, input_flags: InputFlags = EMPTY_INPUT_FLAGS,
) )
Создаёт новый объект ответа на пользовательский ввод. Создаёт новый объект ответа.
* ``status`` : Статус валидации флагов команды из перечисления ``ResponseStatus`` * ``status``: Общий статус валидации флагов из перечисления `ResponseStatus`.
* ``input_flags`` : Коллекция введённых флагов команды. По умолчанию используется пустая коллекция ``EMPTY_INPUT_FLAGS`` * ``input_flags``: Коллекция введённых флагов (`InputFlags`). По умолчанию — пустая.
.. warning :: .. warning ::
Экземпляры класса не предназначены для их прямого создания. Они автоматически создаются системой при обработке пользовательского ввода и передаются в обработчики команд в качестве обязательного первого аргумента. Экземпляры этого класса не предназначены для прямого создания. Они автоматически формируются системой и передаются в обработчик команды в качестве первого обязательного аргумента.
**Атрибуты:** **Атрибуты:**
.. py:attribute:: status .. py:attribute:: status
:no-index:
Статус валидации всех флагов команды типа ``ResponseStatus``. Указывает, были ли среди введённых флагов невалидные или незарегистрированные. Общий статус валидации всех флагов команды (`ResponseStatus`). Указывает, были ли среди введённых флагов некорректные или незарегистрированные.
.. py:attribute:: input_flags .. py:attribute:: input_flags
:no-index:
Коллекция всех флагов, переданных с командой, типа ``InputFlags``. Содержит все распарсенные флаги команды с их значениями и статусами валидации. Коллекция всех флагов, переданных с командой (`InputFlags`). Содержит все обработанные флаги с их значениями и статусами валидации.
**Пример использования:** **Пример использования:**
@@ -57,7 +59,7 @@ Response
Методы DataBridge Методы DataBridge
``Response`` наследует от ``DataBridge`` методы для работы с глобальным хранилищем данных, которое позволяет передавать информацию между различными обработчиками команд в рамках одного сеанса работы приложения. `Response` наследует от `DataBridge` методы для работы с глобальным хранилищем, которое позволяет обмениваться данными между обработчиками в рамках одной сессии.
update_data update_data
~~~~~~~~~~~ ~~~~~~~~~~~
@@ -68,12 +70,12 @@ update_data
@classmethod @classmethod
update_data(cls, data: dict[str, Any]) -> None update_data(cls, data: dict[str, Any]) -> None
Обновляет глобальное хранилище данных, добавляя или обновляя значения из переданного словаря. Обновляет глобальное хранилище, добавляя или изменяя значения из переданного словаря.
:param data: Словарь с данными для обновления хранилища :param data: Словарь с данными для обновления хранилища
:return: None :return: None
Метод объединяет переданные данные с существующими данными в хранилище. Если ключ уже существует, его значение будет обновлено. Метод объединяет переданный словарь с данными в хранилище. Если ключ уже существует, его значение обновляется.
**Пример использования:** **Пример использования:**
@@ -92,7 +94,7 @@ get_data
@classmethod @classmethod
get_data(cls) -> dict[str, Any] get_data(cls) -> dict[str, Any]
Получает все данные из глобального хранилища. Возвращает все данные из глобального хранилища.
:return: Словарь со всеми данными из хранилища :return: Словарь со всеми данными из хранилища
@@ -113,7 +115,7 @@ clear_data
@classmethod @classmethod
clear_data(cls) -> None clear_data(cls) -> None
Очищает все данные из глобального хранилища. Очищает глобальное хранилище.
:return: None :return: None
@@ -134,11 +136,11 @@ delete_from_data
@classmethod @classmethod
delete_from_data(cls, key: str) -> None delete_from_data(cls, key: str) -> None
Удаляет конкретный ключ и его значение из глобального хранилища данных. Удаляет ключ и его значение из глобального хранилища.
:param key: Ключ, который необходимо удалить из хранилища :param key: Ключ, который необходимо удалить из хранилища
:return: None :return: None
:raises KeyError: Если указанный ключ не существует в хранилище :raises KeyError: Если ключ не найден в хранилище.
**Пример использования:** **Пример использования:**
@@ -151,7 +153,7 @@ delete_from_data
Работа с флагами Работа с флагами
---------------- ----------------
``Response`` предоставляет доступ к введённым флагам команды через атрибут ``input_flags``. Вы можете проверять наличие флагов, получать их значения и статусы валидации. `Response` предоставляет доступ к введённым флагам через атрибут `input_flags`. Вы можете проверять их наличие, получать значения и статусы валидации.
**Пример работы с флагами:** **Пример работы с флагами:**
@@ -166,7 +168,7 @@ delete_from_data
ResponseStatus ResponseStatus
-------------- --------------
Enum ``ResponseStatus`` представляет собой перечисление, определяющее общий статус валидации всех флагов команды. Используется в атрибуте ``status`` объекта ``Response`` для информирования о результате проверки всех введённых флагов. `ResponseStatus` — это перечисление (`Enum`), которое определяет общий статус валидации всех флагов команды. Используется в атрибуте `status` объекта `Response`.
Значения enum Значения enum
~~~~~~~~~~~~~ ~~~~~~~~~~~~~
@@ -179,7 +181,7 @@ ALL_FLAGS_VALID
ResponseStatus.ALL_FLAGS_VALID = 'ALL_FLAGS_VALID' ResponseStatus.ALL_FLAGS_VALID = 'ALL_FLAGS_VALID'
Указывает, что все введённые флаги команды прошли валидацию успешно. Нет ни невалидных, ни незарегистрированных флагов. Все введённые флаги прошли валидацию. Нет ни некорректных, ни незарегистрированных флагов.
UNDEFINED_FLAGS UNDEFINED_FLAGS
~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~
@@ -189,7 +191,7 @@ UNDEFINED_FLAGS
ResponseStatus.UNDEFINED_FLAGS = 'UNDEFINED_FLAGS' ResponseStatus.UNDEFINED_FLAGS = 'UNDEFINED_FLAGS'
Указывает, что среди введённых флагов присутствуют незарегистрированные флаги, но нет флагов с невалидными значениями. Среди введённых флагов есть незарегистрированные, но нет флагов с некорректными значениями.
INVALID_VALUE_FLAGS INVALID_VALUE_FLAGS
~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~
@@ -199,7 +201,7 @@ INVALID_VALUE_FLAGS
ResponseStatus.INVALID_VALUE_FLAGS = 'INVALID_VALUE_FLAGS' ResponseStatus.INVALID_VALUE_FLAGS = 'INVALID_VALUE_FLAGS'
Указывает, что среди введённых флагов присутствуют флаги с невалидными значениями, но нет незарегистрированных флагов. Среди введённых флагов есть флаги с некорректными значениями, но нет незарегистрированных.
UNDEFINED_AND_INVALID_FLAGS UNDEFINED_AND_INVALID_FLAGS
~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -209,4 +211,4 @@ UNDEFINED_AND_INVALID_FLAGS
ResponseStatus.UNDEFINED_AND_INVALID_FLAGS = 'UNDEFINED_AND_INVALID_FLAGS' ResponseStatus.UNDEFINED_AND_INVALID_FLAGS = 'UNDEFINED_AND_INVALID_FLAGS'
Указывает, что среди введённых флагов одновременно присутствуют и незарегистрированные флаги, и флаги с невалидными значениями. Среди введённых флагов есть как незарегистрированные, так и флаги с некорректными значениями.
+14 -14
View File
@@ -3,9 +3,9 @@
Router Router
============= =============
Объект ``Router`` является фундаментальным строительным блоком для организации логики в приложении ``Argenta``. Его основная задача — группировать связанные команды и их обработчики. Каждый роутер представляет собой логический контейнер для определенного набора функциональности. ``Router`` — это основной строительный блок для организации логики в приложении. Его задача — группировать связанные команды и их обработчики. Каждый роутер представляет собой логический контейнер для определённого набора функций.
Например, в приложении для управления пользователями один роутер может отвечать за команды, связанные с аутентификацией (``login``, ``logout``), а другой — за операции с профилем (``profile show``, ``profile edit``). Например, в приложении для управления пользователями один роутер может отвечать за аутентификацию (``login``, ``logout``), а другой — за операции с профилем (``profile-show``, ``profile-edit``).
----- -----
@@ -18,23 +18,23 @@ Router
__init__(self, title: str | None = None, __init__(self, title: str | None = None,
disable_redirect_stdout: bool = False) -> None disable_redirect_stdout: bool = False) -> None
Создаёт новый экземпляр маршрутизатора. Создаёт новый экземпляр роутера.
* ``title`` : Необязательный заголовок для группы команд, которые регистрируются в этом роутере. Этот заголовок будет отображаться в списке доступных команд, помогая пользователю ориентироваться. * ``title``: Необязательный заголовок для группы команд. Отображается в списке доступных команд, помогая пользователю ориентироваться.
* ``disable_redirect_stdout`` : Если установлено в ``True``, отключает механизм перехвата стандартного вывода (``stdout``) для всех команд этого роутера. Это необходимо для команд, которые требуют интерактивного ввода от пользователя (например, с помощью ``input()``). При отключении перехвата вывода автоматически используется статическая разделительная линия. Подробнее в :ref:`соответствующем разделе <root_redirect_stdout>` * ``disable_redirect_stdout``: Если ``True``, отключает перехват ``stdout`` для всех команд этого роутера. Это необходимо для интерактивных команд (например, с ``input()``). При отключении перехвата автоматически используется статическая разделительная линия. Подробнее см. в разделе :ref:`Переопределение стандартного вывода <root_redirect_stdout>`.
----- -----
Регистрация команд Регистрация команд
------------------ ------------------
Для регистрации новой команды и привязки к ней функции-обработчика используется декоратор ``@command``. Для регистрации команды и привязки к ней обработчика используется декоратор ``@command``.
.. py:method:: @command(self, command: Command | str) .. py:method:: @command(self, command: Command | str)
Декоратор для регистрации функции как обработчика для указанной команды. Декоратор для регистрации функции как обработчика команды.
:param command: Экземпляр класса ``argenta.command.Command``, описывающий триггер, флаги и описание команды. Также может быть просто строкой, которая будет являться триггером, в этом случае нет возможности настроить флаги, описание и всё остальное. :param command: Экземпляр ``Command``, описывающий триггер, флаги и описание команды. Может быть строкой, которая станет триггером (без возможности настройки флагов и описания).
**Пример использования:** **Пример использования:**
@@ -51,27 +51,27 @@ Router
.. py:data:: system_router .. py:data:: system_router
Предопределенный экземпляр ``Router``, который содержит базовые системные команды. По умолчанию в него включена команда выхода из приложения (обычно **exit**). Он имеет заголовок **"System points:"**, который можно переопределить в инстансе приложения -> ``App``. Предопределённый экземпляр ``Router`` с базовыми системными командами (по умолчанию — команда выхода). Имеет заголовок **«System points:»**, который можно переопределить в ``App``.
Вы можете добавлять свои команды в этот роутер, для этого импортируйте ``argenta.router.defaults.system_router`` и декорируйте необходимые хэндлеры его методом. Вы можете добавлять свои команды в этот роутер. Для этого импортируйте ``argenta.router.defaults.system_router`` и используйте его декоратор ``@command``.
----- -----
Возможные исключения Возможные исключения
-------------------- --------------------
При регистрации команд и флагов в ``Router`` могут возникнуть следующие исключения, сигнализирующие о некорректной конфигурации: При регистрации команд и флагов в ``Router`` могут возникнуть следующие исключения:
.. py:exception:: TriggerContainSpacesException .. py:exception:: TriggerContainSpacesException
Выбрасывается, если триггер команды, передаваемый в ``Command``, содержит пробелы. Триггеры команд должны быть одним словом. Выбрасывается, если триггер команды в ``Command`` содержит пробелы. Триггеры должны быть одним словом.
**Неправильно:** ``Command("add user")`` **Неправильно:** ``Command("add user")``
**Правильно:** ``Command("add-user")`` **Правильно:** ``Command("add-user")``
.. py:exception:: RepeatedFlagNameException .. py:exception:: RepeatedFlagNameException
Возникает, если при определении флагов для одной команды были использованы дублирующиеся имена (как короткие, так и длинные). Каждое имя флага в рамках одной команды должно быть уникальным. Возникает, если при определении флагов для команды были использованы дублирующиеся имена. Имена флагов в рамках одной команды должны быть уникальны.
**Пример, вызывающий исключение:** **Пример, вызывающий исключение:**
@@ -85,5 +85,5 @@ Router
.. py:exception:: RequiredArgumentNotPassedException .. py:exception:: RequiredArgumentNotPassedException
Это исключение возникает, если какой-либо обработчик команды не ожидает обязательный аргумент, которым является объект ответа(``Response``). Возникает, если обработчик команды не принимает обязательный аргумент ``Response``.
+16 -38
View File
@@ -6,74 +6,52 @@
Наше обязательство Наше обязательство
------------------ ------------------
В стремлении создать открытую и приветливую атмосферу, мы, как В целях создания открытой и гостеприимной атмосферы мы, как участники и мейнтейнеры, обязуемся сделать участие в нашем проекте и сообществе свободным от преследований для всех, независимо от возраста, телосложения, инвалидности, этнической принадлежности, гендерной идентичности и самовыражения, уровня опыта, образования, социально-экономического статуса, национальности, внешности, расы, религии или сексуальной идентичности и ориентации.
участники и мейнтейнеры, обязуемся сделать участие в нашем проекте и
сообществе свободным от преследований для всех, независимо от возраста, телосложения,
инвалидности, этнической принадлежности, половых характеристик, уровня опыта, образования,
социально-экономического статуса, национальности, внешности, расы и религии.
----- -----
Наши стандарты Наши стандарты
-------------- --------------
Примеры поведения, способствующего созданию позитивной среды для нашего Примеры поведения, которые способствуют созданию позитивной среды:
сообщества, включают:
* Проявление эмпатии и доброты по отношению к другим людям. * Проявление эмпатии и доброты по отношению к другим.
* Уважительное отношение к различным мнениям, точкам зрения и опыту. * Уважение к различным мнениям, точкам зрения и опыту.
* Предоставление и тактичное принятие конструктивной обратной связи. * Предоставление и тактичное принятие конструктивной обратной связи.
* Принятие ответственности, извинения перед теми, кого затронули наши ошибки, * Принятие ответственности и извинения перед теми, кого затронули наши ошибки, а также извлечение уроков из этого опыта.
и извлечение уроков из этого опыта. * Фокус на том, что лучше для всего сообщества.
* Сосредоточение на том, что лучше не только для нас как отдельных личностей, но и для
всего сообщества в целом.
Примеры недопустимого поведения включают: Примеры недопустимого поведения включают:
* Троллинг, оскорбительные или уничижительные комментарии, а также личные или политические нападки. * Троллинг, оскорбительные или уничижительные комментарии, а также личные или политические нападки.
* Публичное или частное преследование. * Публичное или частное преследование.
* Публикация личной информации других лиц, такой как физический или электронный * Публикация личной информации других лиц (например, физического или электронного адреса) без их явного разрешения.
адрес, без их явного разрешения. * Любое другое поведение, которое можно обоснованно считать неуместным в профессиональной среде.
* Иное поведение, которое можно обоснованно считать неуместным в
профессиональной среде.
----- -----
Наши обязанности Наши обязанности
---------------- ----------------
Мейнтейнеры проекта несут ответственность за разъяснение и обеспечение соблюдения наших стандартов Мейнтейнеры проекта несут ответственность за разъяснение и обеспечение соблюдения стандартов приемлемого поведения и предпримут справедливые корректирующие действия в ответ на любые случаи неприемлемого поведения.
приемлемого поведения и предпримут соответствующие и справедливые корректирующие действия в
ответ на любые случаи неприемлемого поведения.
Мейнтейнеры проекта имеют право и обязанность удалять, редактировать или отклонять Мейнтейнеры проекта имеют право и обязанность удалять, редактировать или отклонять комментарии, коммиты, код, правки в вики, задачи и другие вклады, которые не соответствуют настоящему Кодексу поведения, а также временно или навсегда блокировать любого участника за поведение, которое они сочтут неуместным, угрожающим, оскорбительным или вредным.
комментарии, коммиты, код, правки в вики, задачи и другие вклады, которые
не соответствуют настоящему Кодексу поведения, или временно либо навсегда
заблокировать любого участника за другое поведение, которое они сочтут
неуместным, угрожающим, оскорбительным или вредным.
----- -----
Сфера применения Сфера применения
---------------- ----------------
Настоящий Кодекс поведения применяется во всех пространствах сообщества, а также когда Настоящий Кодекс поведения применяется как в рамках проекта, так и в публичных пространствах, когда человек официально представляет сообщество. Примеры такого представительства включают использование официального адреса электронной почты, публикации через официальный аккаунт в социальных сетях или выступление в качестве назначенного представителя на онлайн- или офлайн-мероприятии.
человек официально представляет сообщество в публичных местах.
Примеры представления нашего сообщества включают использование официального адреса электронной почты,
публикации через официальный аккаунт в социальных сетях или выступление в качестве назначенного
представителя на онлайн- или офлайн-мероприятии.
----- -----
Обеспечение соблюдения Обеспечение соблюдения
---------------------- ----------------------
О случаях оскорбительного, преследовательского или иного неприемлемого поведения можно О случаях оскорбительного, преследовательского или иного неприемлемого поведения можно сообщить команде проекта по адресу [ВСТАВЬТЕ АДРЕС ЭЛЕКТРОННОЙ ПОЧТЫ]. Все жалобы будут рассмотрены и расследованы оперативно и справедливо.
сообщить руководителям сообщества, ответственным за обеспечение правоприменения, по адресу .
Все жалобы будут рассмотрены и расследованы оперативно и справедливо.
Все руководители сообщества обязаны уважать частную жизнь и безопасность Команда проекта обязуется уважать частную жизнь и безопасность заявителя.
заявителя любого инцидента.
----- -----
+56 -60
View File
@@ -7,16 +7,16 @@
Прежде всего, спасибо, что уделили время для внесения своего вклада! ❤️ Прежде всего, спасибо, что уделили время для внесения своего вклада! ❤️
Мы приветствуем и ценим любые виды вклада. Пожалуйста, прочтите соответствующий раздел, прежде чем делать свой вклад. Это значительно облегчит работу для нас, мейнтейнеров, и сделает процесс более гладким для всех участников. Сообщество с нетерпением ждет ваших вкладов. 🎉 Мы приветствуем и ценим любой вклад. Пожалуйста, прочтите соответствующий раздел, прежде чем начать. Это облегчит работу мейнтейнеров и сделает процесс более гладким для всех. Сообщество с нетерпением ждёт ваших идей! 🎉
.. note:: .. note::
Если вам нравится проект, но у вас просто нет времени на вклад, это нормально. Есть и другие простые способы поддержать проект и выразить свою признательность, которым мы также будем очень рады: Если вам нравится проект, но у вас нет времени на активный вклад, вы можете поддержать нас другими способами:
* Поставить звезду проекту * Поставить звезду на GitHub.
* Написать о нем в ``Twitter`` * Написать о проекте в Twitter или других социальных сетях.
* Ссылаться на этот проект в ``Readme`` вашего проекта * Сослаться на проект в `README` вашего репозитория.
* Упомянуть проект на местных встречах и рассказать о нем друзьям/коллегам * Упомянуть проект на митапах и рассказать о нём друзьям и коллегам.
.. _Содержание: .. _Содержание:
@@ -51,15 +51,11 @@
.. note:: .. note::
Если вы хотите задать вопрос, мы предполагаем, что вы уже ознакомились с доступной `Документацией <https://argenta.readthedocs.io>`_. Прежде чем задать вопрос, пожалуйста, ознакомьтесь с `документацией <https://argenta.readthedocs.io>`_.
Прежде чем задать вопрос, лучше всего поискать существующие `Issues <https://github.com/koloideal/Argenta/issues>`_, которые могут вам помочь. Если вы нашли подходящий ``issue``, но все еще нуждаетесь в разъяснениях, вы можете написать свой вопрос в этом ``issue``. Также рекомендуется сначала поискать ответы в интернете. Поищите ответ в существующих `Issues <https://github.com/koloideal/Argenta/issues>`_. Если вы нашли похожий вопрос, но всё ещё нуждаетесь в разъяснениях, можете написать в нём. Также рекомендуем поискать ответ в интернете.
Если после этого вы все еще чувствуете необходимость задать вопрос, мы рекомендуем следующее: Если ответа не нашлось, создайте новый `Issue <https://github.com/koloideal/Argenta/issues/new>`_ и предоставьте как можно больше контекста, включая версии проекта и платформы (CPython, pip и т.д.).
* Откройте новый `Issue <https://github.com/koloideal/Argenta/issues/new>`_.
* Предоставьте как можно больше контекста о том, с чем вы столкнулись.
* Укажите версии проекта и платформы (cpython, pip и т.д.), в зависимости от того, что кажется релевантным.
Мы займемся вашей задачей как можно скорее. Мы займемся вашей задачей как можно скорее.
@@ -74,7 +70,7 @@
.. note:: .. note::
Внося вклад в этот проект, вы должны согласиться с тем, что вы являетесь автором 100% контента, что у вас есть необходимые права на этот контент, и что предоставленный вами контент может распространяться под лицензией проекта. Внося вклад в этот проект, вы подтверждаете, что являетесь автором 100% контента, обладаете необходимыми правами на него и соглашаетесь, что он может распространяться под лицензией проекта.
.. _Сообщение об ошибках: .. _Сообщение об ошибках:
@@ -83,37 +79,37 @@
.. rubric:: Перед отправкой отчета об ошибке .. rubric:: Перед отправкой отчета об ошибке
Хороший отчет об ошибке не должен заставлять других вытягивать из вас дополнительную информацию. Поэтому мы просим вас тщательно все изучить, собрать информацию и подробно описать проблему в своем отчете. Пожалуйста, выполните следующие шаги заранее, чтобы помочь нам исправить любую потенциальную ошибку как можно быстрее. Хороший отчёт об ошибке не должен заставлять других вытягивать из вас дополнительную информацию. Пожалуйста, тщательно всё изучите, соберите информацию и подробно опишите проблему. Это поможет нам исправить её как можно быстрее.
* Убедитесь, что вы используете последнюю версию. * Убедитесь, что вы используете последнюю версию.
* Определите, действительно ли ваша проблема является ошибкой, а не ошибкой с вашей стороны, например, из-за использования несовместимых компонентов/версий окружения (Убедитесь, что вы прочитали `документацию <https://argenta.readthedocs.io>`_. Если вам нужна поддержка, возможно, стоит заглянуть в раздел `У меня есть вопрос`_). * Убедитесь, что проблема действительно является ошибкой, а не вызвана, например, использованием несовместимых версий окружения. Прочтите `документацию <https://argenta.readthedocs.io>`_ и, если нужна поддержка, загляните в раздел `У меня есть вопрос`_.
* Чтобы увидеть, сталкивались ли другие пользователи (и, возможно, уже решили) с той же проблемой, проверьте, нет ли уже отчета о вашей ошибке в `трекере ошибок <https://github.com/koloideal/Argenta/issues?q=label%3Abug>`_. * Проверьте, нет ли уже отчёта о вашей ошибке в `трекере <https://github.com/koloideal/Argenta/issues?q=label%3Abug>`_.
* Также обязательно поищите в интернете (включая ``Stack Overflow``), чтобы узнать, обсуждали ли проблему пользователи за пределами сообщества ``GitHub``. * Также поищите в интернете (включая `Stack Overflow`), чтобы узнать, обсуждалась ли проблема за пределами `GitHub`.
* Соберите информацию об ошибке: * Соберите информацию об ошибке:
* Трассировка стека * Трассировка стека.
* ОС, платформа и версия ``Windows``, ``Linux``, ``macOS``, ``x86``, ``ARM`` * ОС, платформа и версия (Windows, Linux, macOS, x86, ARM).
* Версия интерпретатора, компилятора, SDK, среды выполнения, менеджера пакетов, в зависимости от того, что кажется релевантным. * Версия интерпретатора, компилятора, SDK, среды выполнения, менеджера пакетов и т.д.
* Возможно, ваши входные данные и результат * Входные данные и полученный результат.
* Можете ли вы надежно воспроизвести проблему? И можете ли вы воспроизвести ее на старых версиях? * Можете ли вы надёжно воспроизвести проблему? Воспроизводится ли она на старых версиях?
.. rubric:: Как мне отправить хороший отчет об ошибке? .. rubric:: Как мне отправить хороший отчет об ошибке?
.. note:: .. note::
Никогда не сообщайте о проблемах безопасности, уязвимостях или ошибках, содержащих конфиденциальную информацию, в трекере задач или в других публичных местах. Конфиденциальные ошибки должны быть отправлены по электронной почте. Никогда не сообщайте о проблемах безопасности, уязвимостях или ошибках с конфиденциальной информацией в публичном трекере. Для этого используйте электронную почту.
Мы используем ``Issues GitHub`` для отслеживания ошибок. Если вы столкнулись с проблемой в проекте: Мы используем `GitHub Issues` для отслеживания ошибок. Если вы столкнулись с проблемой:
* Откройте `Issue <https://github.com/koloideal/Argenta/issues/new>`_. (Поскольку на данном этапе мы не можем быть уверены, является ли это ошибкой, мы просим вас пока не говорить об ошибке и не присваивать метку задаче.) * Откройте новый `Issue <https://github.com/koloideal/Argenta/issues/new>`_. На этом этапе не нужно присваивать ему метки.
* Объясните поведение, которое вы ожидали, и фактическое поведение. * Объясните ожидаемое и фактическое поведение.
* Пожалуйста, предоставьте как можно больше контекста и опишите *шаги для воспроизведения*, чтобы кто-то другой мог воссоздать проблему самостоятельно. Обычно это включает ваш код. Для хороших отчетов об ошибках следует изолировать проблему и создать сокращенный тестовый пример. * Предоставьте как можно больше контекста и опишите **шаги для воспроизведения**, чтобы проблему можно было воссоздать. Лучше всего изолировать её и создать минимальный тестовый пример.
* Предоставьте информацию, которую вы собрали в предыдущем разделе. * Предоставьте информацию, которую вы собрали в предыдущем разделе.
После того, как задача будет создана: После того, как задача будет создана:
* Команда проекта присвоит задаче соответствующую метку. * Команда проекта присвоит задаче соответствующую метку.
* Член команды попытается воспроизвести проблему по вашим шагам. Если шагов для воспроизведения нет или нет очевидного способа воспроизвести проблему, команда попросит вас предоставить эти шаги и пометит задачу как `needs-repro`. Ошибки с меткой `needs-repro` не будут рассматриваться до тех пор, пока они не будут воспроизведены. * Член команды попытается воспроизвести проблему. Если шагов нет или они не приводят к результату, команда попросит вас предоставить их и пометит задачу как `needs-repro`. Такие задачи не будут рассматриваться до тех пор, пока проблема не будет воспроизведена.
* Если команда сможет воспроизвести проблему, она будет помечена как `needs-fix`, а также, возможно, другими метками (например, `critical`), и задача будет оставлена для :ref:`реализации кем-либо <Ваш первый вклад в код>`. * Если проблема будет воспроизведена, она будет помечена как `needs-fix`, возможно, другими метками, например `critical`), после чего её сможет взять в работу :ref:`любой желающий <Ваш первый вклад в код>`.
----- -----
@@ -122,24 +118,24 @@
Предложение улучшений Предложение улучшений
--------------------- ---------------------
Этот раздел поможет вам отправить предложение по улучшению ``Argenta``, **включая совершенно новые функции и незначительные улучшения существующей функциональности**. Следование этим рекомендациям поможет мейнтейнерам и сообществу понять ваше предложение и найти связанные с ним предложения. Этот раздел поможет вам отправить предложение по улучшению `Argenta`, **включая как новые функции, так и незначительные улучшения**. Следование этим рекомендациям поможет мейнтейнерам и сообществу лучше понять вашу идею.
.. rubric:: Перед отправкой предложения по улучшению .. rubric:: Перед отправкой предложения по улучшению
* Убедитесь, что вы используете последнюю версию. * Убедитесь, что вы используете последнюю версию.
* Внимательно прочтите `документацию <https://argenta.readthedocs.io>`_ и выясните, не реализована ли уже данная функциональность, возможно, через индивидуальную конфигурацию. * Внимательно прочтите `документацию <https://argenta.readthedocs.io>`_ и убедитесь, что предлагаемая функциональность ещё не реализована (возможно, через конфигурацию).
* Выполните `поиск <https://github.com/koloideal/Argenta/issues>`_, чтобы проверить, не было ли уже предложено данное улучшение. Если да, добавьте комментарий к существующей задаче вместо создания новой. * Выполните `поиск <https://github.com/koloideal/Argenta/issues>`_, чтобы проверить, не предлагалось ли это улучшение ранее. Если да, добавьте комментарий к существующей задаче.
* Определите, соответствует ли ваша идея масштабам и целям проекта. Вам предстоит убедительно доказать разработчикам проекта достоинства этой функции. Помните, что мы хотим видеть функции, которые будут полезны большинству наших пользователей, а не только небольшой их части. Если вы ориентируетесь только на меньшинство пользователей, рассмотрите возможность написания дополнения/плагина. * Определите, соответствует ли ваша идея масштабу и целям проекта. Вам предстоит убедительно доказать её пользу. Мы хотим видеть функции, которые будут полезны большинству пользователей. Если ваша идея ориентирована на узкий круг, рассмотрите возможность создания плагина.
.. rubric:: Как мне отправить хорошее предложение по улучшению? .. rubric:: Как мне отправить хорошее предложение по улучшению?
Предложения по улучшению отслеживаются как `Issues GitHub <https://github.com/koloideal/Argenta/issues>`_. Предложения по улучшению отслеживаются в `GitHub Issues <https://github.com/koloideal/Argenta/issues>`_.
* Используйте **четкий и описательный заголовок** для задачи, чтобы идентифицировать предложение. * Используйте **чёткий и описательный заголовок**, чтобы идентифицировать предложение.
* Предоставьте **пошаговое описание предлагаемого улучшения** как можно подробнее. * Предоставьте **пошаговое и подробное описание** предлагаемого улучшения.
* **Опишите текущее поведение** и **объясните, какое поведение вы ожидали увидеть вместо этого** и почему. На этом этапе вы также можете указать, какие альтернативы вам не подходят. * **Опишите текущее поведение** и **объясните, какое вы ожидали увидеть вместо этого** и почему. Здесь же можно указать, какие альтернативы вам не подходят.
* Вы можете **включить скриншоты или записи экрана**, которые помогут продемонстрировать шаги или указать на часть, к которой относится предложение. * **Приложите скриншоты или видео**, которые помогут продемонстрировать шаги или указать на часть, к которой относится предложение.
* **Объясните, почему это улучшение было бы полезно** большинству пользователей ``Argenta``. Вы также можете указать на другие проекты, которые решили эту проблему лучше и которые могут послужить источником вдохновения. * **Объясните, почему это улучшение будет полезно** большинству пользователей `Argenta`. Вы также можете указать на другие проекты, которые решили эту проблему и могут послужить источником вдохновения.
----- -----
@@ -148,9 +144,9 @@
Ваш первый вклад в код Ваш первый вклад в код
----------------------- -----------------------
Не знаете, с чего начать свой вклад в ``Argenta``? Вы можете начать с просмотра задач с метками ``good first issue`` и ``help wanted`` в нашем репозитории на ``GitHub``. Это задачи, которые хорошо подходят для новичков. Не знаете, с чего начать? Посмотрите на задачи с метками `good first issue` и `help wanted` в нашем репозитории на `GitHub`. Они хорошо подходят для новичков.
Чтобы начать вносить свой первый вклад в код, пожалуйста, выполните следующие шаги для настройки вашего локального окружения для разработки. Чтобы начать, настройте локальное окружение для разработки, следуя этим шагам.
#. Сделайте форк репозитория ``Argenta`` на ``GitHub``. #. Сделайте форк репозитория ``Argenta`` на ``GitHub``.
#. Клонируйте ваш форк на локальную машину: #. Клонируйте ваш форк на локальную машину:
@@ -178,20 +174,20 @@
pip install -e .[dev] pip install -e .[dev]
#. Создайте новую ветку для вашей новой функции или исправления ошибки. Используйте описательное имя, например ``fix/login-bug`` или ``feat/new-widget``. #. Создайте новую ветку для вашей функции или исправления. Используйте описательное имя, например `fix/login-bug` или `feat/new-widget`.
.. code-block:: bash .. code-block:: bash
git switch -c your-new-branch-name git switch -c your-new-branch-name
#. Внесите свои изменения! Напишите код и не забудьте добавить или обновить тесты для ваших изменений. #. Внесите свои изменения. Напишите код и не забудьте добавить или обновить тесты.
#. Запустите тесты, чтобы убедиться, что все работает корректно. #. Запустите тесты, чтобы убедиться, что все работает корректно.
.. code-block:: bash .. code-block:: bash
python -m pytest tests python -m pytest tests
#. Сделайте коммит ваших изменений, следуя нашему руководству по стилю сообщений коммитов, и отправьте их в ваш форк. #. Сделайте коммит, следуя нашему руководству по стилю, и отправьте изменения в ваш форк.
.. code-block:: bash .. code-block:: bash
@@ -199,7 +195,7 @@
git commit -m "feat(widget): add the new super widget" git commit -m "feat(widget): add the new super widget"
git push origin your-new-branch-name git push origin your-new-branch-name
#. Откройте ``Pull Request`` из вашей ветки в ветку ``main`` официального репозитория ``Argenta``. Предоставьте четкое описание проблемы и вашего решения. Укажите номер связанной задачи, если это применимо. #. Откройте `Pull Request` из вашей ветки в ветку `main` официального репозитория. Предоставьте чёткое описание проблемы и вашего решения. Укажите номер связанной задачи, если она есть.
----- -----
@@ -208,7 +204,7 @@
Улучшение документации Улучшение документации
---------------------- ----------------------
Хорошая документация крайне важна для любого проекта. Мы используем ``Sphinx`` для генерации нашей документации из исходных файлов, расположенных в директории ``docs/``. Мы приветствуем любые улучшения, от исправления простой опечатки до написания целого нового раздела. Хорошая документация крайне важна. Мы используем `Sphinx` для её генерации из исходных файлов в директории `docs/`. Мы приветствуем любые улучшения: от исправления опечатки до написания нового раздела.
.. note:: .. note::
@@ -223,22 +219,22 @@
cd docs cd docs
#. Внесите необходимые изменения в **русскую** версию документации - ``docs/index.rst`` и/или ``docs/root/*`` #. Внесите изменения в **русскую** версию документации (`docs/index.rst` и/или `docs/root/*`).
#. Чтобы собрать документацию локально и увидеть ваши изменения, выполните: #. Чтобы собрать документацию локально и увидеть изменения, выполните:
.. code-block:: bash .. code-block:: bash
make live-ru make live-ru
#. Откройте ``127.0.0.1:8000`` в вашем веб-браузере, чтобы просмотреть сгенерированную документацию. #. Откройте `127.0.0.1:8000` в браузере, чтобы просмотреть сгенерированную документацию.
#. После завершения работы над русской документацией необходимо создать английский перевод: #. После завершения работы над русской версией необходимо создать английский перевод:
.. code-block:: bash .. code-block:: bash
make update-langs make update-langs
#. После обновления шаблона перевода, обновите необходимые файлы перевода, расположенные по пути ``docs/locales/en/LC_MESSAGES``. #. После обновления шаблона обновите файлы перевода, расположенные в `docs/locales/en/LC_MESSAGES/`.
#. Когда вы будете довольны своими изменениями, сделайте коммит и откройте ``Pull Request``. Используйте префикс ``docs:`` в сообщении коммита. #. Когда изменения будут готовы, сделайте коммит и откройте `Pull Request`. Используйте префикс `docs:` в сообщении коммита.
----- -----
@@ -252,7 +248,7 @@
Сообщения коммитов Сообщения коммитов
~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~
Мы следуем спецификации `Conventional Commits <https://www.conventionalcommits.org/en/v1.0.0/>`_ для наших сообщений коммитов. Это приводит к более читаемым сообщениям, которые легко отслеживать при просмотре истории проекта, и позволяет автоматически генерировать журнал изменений. Мы следуем спецификации `Conventional Commits <https://www.conventionalcommits.org/en/v1.0.0/>`_. Это делает историю проекта более читаемой и позволяет автоматически генерировать журнал изменений.
Каждое сообщение коммита состоит из **заголовка**, **тела** и **нижнего колонтитула**. Каждое сообщение коммита состоит из **заголовка**, **тела** и **нижнего колонтитула**.
@@ -290,13 +286,13 @@
Присоединяйтесь к команде проекта Присоединяйтесь к команде проекта
--------------------------------- ---------------------------------
Мы всегда ищем энтузиастов и преданных своему делу людей для присоединения к нашей команде проекта. Если вы являетесь постоянным участником и продемонстрировали глубокое понимание целей и архитектуры проекта, вы можете стать хорошим кандидатом на роль мейнтейнера. Мы всегда ищем энтузиастов для присоединения к команде. Если вы являетесь постоянным участником и продемонстрировали глубокое понимание целей и архитектуры проекта, вы можете стать хорошим кандидатом на роль мейнтейнера.
Активные члены сообщества могут стать членами команды. Обычно это включает в себя: Активные члены сообщества могут стать членами команды. Обычно это включает:
* Постоянный вклад в виде высококачественного кода и документации. * Постоянный вклад в виде качественного кода и документации.
* Помощь другим пользователям, отвечая на вопросы и разбирая проблемы. * Помощь другим пользователям с их вопросами и проблемами.
* Проверку ``Pull Request`` от других участников с конструктивной обратной связью. * Проверку `Pull Request`'ов от других участников с конструктивной обратной связью.
Если вы заинтересованы в том, чтобы стать постоянным членом команды, лучший способ начать — это быть активным и полезным членом сообщества. Существующие мейнтейнеры заметят ваши усилия и могут связаться с вами с приглашением присоединиться к команде. Если вы заинтересованы в том, чтобы стать постоянным членом команды, лучший способ быть активным и полезным участником сообщества. Существующие мейнтейнеры заметят ваши усилия и могут связаться с вами.
+11 -13
View File
@@ -3,32 +3,30 @@
Внедрение зависимостей Внедрение зависимостей
======================= =======================
Внедрение зависимостей (Dependency Injection, DI) — это паттерн проектирования, который помогает писать слабосвязанный, легко тестируемый и расширяемый код. Вместо того чтобы хендлеры сами создавали нужные им объекты (зависимости) они лишь объявляют о необходимости в их получении, а ``Argenta`` "внедряет" их в хендлеры в момент вызова. Внедрение зависимостей (Dependency Injection, DI) — это паттерн проектирования, который помогает писать слабосвязанный, легко тестируемый и расширяемый код. Вместо того чтобы обработчики сами создавали нужные им объекты (зависимости), они лишь объявляют их в качестве аргументов. В момент вызова ``Argenta`` автоматически "внедряет" эти зависимости.
``Argenta`` использует популярную библиотеку ``dishka`` для реализации DI, что позволяет вам декларативно объявлять зависимости прямо в сигнатурах ваших хендлеров. ``Argenta`` использует библиотеку ``dishka`` для реализации DI, что позволяет декларативно объявлять зависимости прямо в сигнатурах ваших обработчиков.
Более подробно про ``DI``, ``IoC``, ``API`` создания провайдеров и другое вы можете прочитать тут_. Подробнее о `DI`, `IoC` и API для создания провайдеров можно прочитать в `официальной документации dishka <https://dishka.readthedocs.io/en/stable/di_intro.html>`_.
.. _тут : https://dishka.readthedocs.io/en/stable/di_intro.html
Основная идея Основная идея
------------- -------------
Представьте, что вашему хендлеру для работы нужен доступ к базе данных. Вместо того чтобы импортировать и инициализировать соединение внутри функции, вы просто объявляете его как аргумент с тайп-хинтом: Представьте, что вашему обработчику для работы нужен доступ к базе данных. Вместо импорта и инициализации соединения внутри функции, вы просто объявляете его как аргумент с аннотацией типа:
.. note:: .. note::
``argenta.di.FromDishka`` это алиас к ``dishka.FromDishka``, они полностью взаимозаменяемы. ``argenta.di.FromDishka`` является псевдонимом для ``dishka.FromDishka``, и они полностью взаимозаменяемы.
.. literalinclude:: ../code_snippets/dependency_injection/snippet.py .. literalinclude:: ../code_snippets/dependency_injection/snippet.py
:language: python :language: python
:linenos: :linenos:
``Argenta`` через ``dishka`` разрешит типы и внедрит зависимость с возвращаемым типом ``Connection``. Прежде чем использовать зависимость, её нужно создать, для этого нужно создать соответствующий провайдер. ``Argenta`` с помощью ``dishka`` разрешит зависимость по типу ``Connection`` и внедрит её. Но прежде чем использовать зависимость, её необходимо объявить в провайдере.
.. literalinclude:: ../code_snippets/dependency_injection/snippet2.py .. literalinclude:: ../code_snippets/dependency_injection/snippet2.py
:language: python :language: python
:linenos: :linenos:
После создания провайдера его нужно зарегистрировать в оркестраторе. После создания провайдера его необходимо зарегистрировать в оркестраторе.
.. literalinclude:: ../code_snippets/dependency_injection/snippet3.py .. literalinclude:: ../code_snippets/dependency_injection/snippet3.py
:language: python :language: python
@@ -45,9 +43,9 @@
Встроенные провайдеры Встроенные провайдеры
----------------------- -----------------------
``Argenta`` поставляется с предопределённым провайдером, который даёт доступ к важным системным зависимостям без какой-либо настройки. К примеру вы можете получить объект ``ArgSpace``, который представляет из себя распаршенные аргументы командной строки при запуске приложения. ``Argenta`` поставляется со встроенным провайдером, который даёт доступ к важным системным зависимостям без дополнительной настройки. Например, вы можете получить объект ``ArgSpace``, который содержит аргументы командной строки, переданные при запуске приложения.
Краткий пример кода, который получает объект ``ArgSpace`` и выводит в консоль аргумент с именем "type": Пример получения объекта ``ArgSpace`` и вывода в консоль значения аргумента `type`:
.. literalinclude:: ../code_snippets/dependency_injection/snippet4.py .. literalinclude:: ../code_snippets/dependency_injection/snippet4.py
:language: python :language: python
@@ -56,9 +54,9 @@
Обмен данными между хендлерами Обмен данными между хендлерами
------------------------------ ------------------------------
Помимо DI, хендлеры могут общаться друг с другом в контексте приложения через **объект контекста** ``Argenta`` эту роль выполняет объект ``Response``). Помимо DI, обработчики могут обмениваться данными в рамках сессии через **объект контекста**. В ``Argenta`` эту роль выполняет объект ``Response``.
Каждый хендлер может записывать данные, читать, обновлять и удалять. Каждый обработчик может записывать в него данные, а также читать, обновлять и удалять их.
.. seealso:: .. seealso::
+18 -34
View File
@@ -6,15 +6,13 @@
О разделе О разделе
------------ ------------
``Argenta`` в рантайме вызывает исключения в пограничных случаях пользовательского ввода. Argenta выбрасывает исключения в пограничных случаях, связанных с пользовательским вводом.
Все исключения обрабатываются системными хэндлерами, но у вас есть возможность их переопределить. Переопределение осуществляется По умолчанию они обрабатываются системными хэндлерами, но вы можете их переопределить. Это делается с помощью сеттеров экземпляра ``App`` вида ``.set_*_handler()``. Подробнее о каждом из них рассказано :ref:`ниже <possible_errors>`.
с помощью сеттеров инстанса ``App`` - ``.set_*_handler(_)``, где ``_`` - это протокол хэндлера нестандартного поведения, подробнее
о каждом протоколе и соответствующем сеттере :ref:`ниже <possible_errors>`
.. note:: .. note::
Все исключения никогда не остаются необработанными, так как у них есть стандартные хэндлеры. Поэтому переопределение опционально. Ни одно исключение не остаётся необработанным, так как для каждого случая предусмотрен стандартный хэндлер. Поэтому переопределение является опциональным.
Краткий пример кода, переопределяющего хэндлер ввода пустой команды: Пример переопределения обработчика для пустой команды:
.. literalinclude:: ../code_snippets/error_handling/snippet.py .. literalinclude:: ../code_snippets/error_handling/snippet.py
:language: python :language: python
@@ -26,12 +24,10 @@
Возможные исключения и нестандартное поведение Возможные исключения и нестандартное поведение
---------------------------------------------- ----------------------------------------------
``UnprocessedInputFlagException``: Необрабатываемый ввод от пользователя ``UnprocessedInputFlagException``: Некорректный синтаксис флагов
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Исключение вызывается, когда пользователь вводит команду с некорректным синтаксисом и, как следствие, парсер не может Это исключение выбрасывается, когда парсер не может обработать команду из-за некорректного синтаксиса. Чаще всего это связано с ошибкой в синтаксисе флагов. Подробнее о них можно прочитать в разделе :ref:`Flags <root_flags>`.
*распарсить* её. В большинстве случаев это означает, что проблема в синтаксисе введённых флагов команды, подробнее о
флагах и их синтаксисе в :ref:`Flags <root_flags>`.
Стандартный хэндлер выводит в консоль Стандартный хэндлер выводит в консоль
@@ -39,9 +35,7 @@
Incorrect flag syntax: <raw input command> Incorrect flag syntax: <raw input command>
Для переопределения стандартного поведения используется сеттер ``.set_incorrect_input_syntax_handler(_: NonStandardBehaviorHandler[str])``, Для переопределения используется сеттер ``.set_incorrect_input_syntax_handler()``. Он принимает на вход обработчик с сигнатурой ``Callable[[str], None]``, где единственный аргумент — это строка с необработанной командой.
протокол ``NonStandardBehaviorHandler[str]`` соответствует ``Callable[[str], None]``, то есть хэндлер должен быть вызываемым объектом,
к примеру функция или лямбда, которая принимает единственный аргумент - строку, которая представляет собой необработанную введённую команду, и ничего не возвращает.
Пример кода, переопределяющего хэндлер ввода команды с некорректным синтаксисом: Пример кода, переопределяющего хэндлер ввода команды с некорректным синтаксисом:
@@ -51,11 +45,10 @@
--------------- ---------------
``RepeatedInputFlagsException``: Повторяющийся флаг в введённой команде ``RepeatedInputFlagsException``: Повторяющиеся флаги в команде
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Исключение вызывается, когда пользователь вводит команду с повторяющимся флагом, пара введённых флагов(:ref:`InputFlag <root_api_command_input_flag>`) считается Исключение выбрасывается, если пользователь ввёл команду с повторяющимися флагами. Два флага (:ref:`InputFlag <root_api_command_input_flag>`) считаются одинаковыми, если у них совпадают имена. Подробнее о флагах и их синтаксисе — в разделе :ref:`Flags <root_flags>`.
равной, если у них одинаковые имена. Подробнее о флагах и их синтаксисе в :ref:`Flags <root_flags>`.
.. note:: .. note::
Сравнение на равенство у регистрируемых флагов(Flag) происходит иначе, подробнее в :ref:`Flag <root_flags>`. Сравнение на равенство у регистрируемых флагов(Flag) происходит иначе, подробнее в :ref:`Flag <root_flags>`.
@@ -66,9 +59,7 @@
Repeated input flags: <raw input command> Repeated input flags: <raw input command>
Для переопределения стандартного поведения используется сеттер ``.set_repeated_input_flags_handler(_: NonStandardBehaviorHandler[str])``, Для переопределения используется сеттер ``.set_repeated_input_flags_handler()``. Он принимает на вход обработчик с сигнатурой ``Callable[[str], None]``, где единственный аргумент — это строка с необработанной командой.
протокол ``NonStandardBehaviorHandler[str]`` соответствует ``Callable[[str], None]``, то есть хэндлер должен быть вызываемым объектом,
к примеру функция или лямбда, которая принимает единственный аргумент - строку, которая представляет собой необработанную введённую команду, и ничего не возвращает.
Пример кода, переопределяющего хэндлер ввода команды с повторяющимися флагами: Пример кода, переопределяющего хэндлер ввода команды с повторяющимися флагами:
@@ -81,7 +72,7 @@
``EmptyInputCommandException``: Введена пустая команда ``EmptyInputCommandException``: Введена пустая команда
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Исключение вызывается, когда пользователь вводит команду в виде строки из пробельных символов - ``\n``, ``\t``, пробел и т.д. Исключение выбрасывается, если пользователь ввёл пустую строку или строку, состоящую только из пробельных символов (``\n``, ``\t``, пробел и т.д.).
Стандартный хэндлер выводит в консоль Стандартный хэндлер выводит в консоль
@@ -89,9 +80,7 @@
Empty input command Empty input command
Для переопределения стандартного поведения используется сеттер ``.set_empty_command_handler(_: EmptyCommandHandler)``, Для переопределения используется сеттер ``.set_empty_command_handler()``. Он принимает на вход обработчик с сигнатурой ``Callable[[], None]`` (без аргументов).
протокол ``EmptyCommandHandler`` соответствует ``Callable[[], None]``, то есть хэндлер должен быть вызываемым объектом,
к примеру функция или лямбда, которая не принимает аргументов и ничего не возвращает.
Пример кода, переопределяющего хэндлер ввода пустой команды: Пример кода, переопределяющего хэндлер ввода пустой команды:
@@ -101,11 +90,10 @@
--------------- ---------------
``Поведение обработки неизвестной команды``: Введена неизвестная команда Обработка неизвестной команды
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Поведение триггерится, когда пользователь вводит команду, которая не зарегистрирована ни в одном роутере и не является алиасом ни для Это поведение активируется, когда пользователь вводит команду, которая не зарегистрирована ни в одном из роутеров и не является псевдонимом (alias) для существующей команды.
одной зарегистрированной команды.
Стандартный хэндлер выводит в консоль Стандартный хэндлер выводит в консоль
@@ -113,9 +101,7 @@
Unknown command: <trigger of the input command> Unknown command: <trigger of the input command>
Для переопределения стандартного поведения используется сеттер ``.set_unknown_command_handler(_: NonStandardBehaviorHandler[InputCommand])``, Для переопределения используется сеттер ``.set_unknown_command_handler()``. Он принимает на вход обработчик с сигнатурой ``Callable[[InputCommand], None]``, где аргумент — объект :ref:`InputCommand <root_api_command_input_command>`.
протокол ``NonStandardBehaviorHandler[InputCommand]`` соответствует ``Callable[[InputCommand], None]``, то есть хэндлер должен быть вызываемым объектом,
к примеру функция или лямбда, которая принимает обязательный аргумент типа :ref:`InputCommand <root_api_command_input_command>` и ничего не возвращает.
Пример кода, переопределяющего хэндлер ввода неизвестной команды: Пример кода, переопределяющего хэндлер ввода неизвестной команды:
@@ -125,10 +111,10 @@
--------------- ---------------
``Поведение выхода из приложения``: Введена команда выхода Выход из приложения
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Поведение триггерится, когда пользователь вводит команду, которая маркирована как команда завершения работы. Это поведение активируется, когда пользователь вводит команду, помеченную как команда выхода.
Стандартный хэндлер выводит в консоль текст и завершает работу приложения. Стандартный хэндлер выводит в консоль текст и завершает работу приложения.
@@ -136,9 +122,7 @@
See you See you
Для переопределения стандартного поведения используется сеттер ``.set_exit_command_handler(_: NonStandardBehaviorHandler[Response])``, Для переопределения используется сеттер ``.set_exit_command_handler()``. Он принимает на вход обработчик с сигнатурой ``Callable[[Response], None]``, где аргумент — объект :ref:`Response <root_api_response>`.
протокол ``NonStandardBehaviorHandler[Response]`` соответствует ``Callable[[Response], None]``, то есть хэндлер должен быть вызываемым объектом,
к примеру функция или лямбда, которая принимает обязательный аргумент типа :ref:`Response <root_api_response>` и ничего не возвращает.
Пример кода, переопределяющего хэндлер ввода команды выхода: Пример кода, переопределяющего хэндлер ввода команды выхода:
+10 -11
View File
@@ -3,21 +3,20 @@
Флаги вводимых команд Флаги вводимых команд
===================== =====================
Флаги (или параметры) — это специальные аргументы, которые конечный юзер может добавлять к командам, чтобы управлять их поведением. Флаги (или параметры) — это специальные аргументы, которые пользователь может добавлять к командам для управления их поведением.
----- -----
Синтаксис флагов Синтаксис флагов
----------------- -----------------
Обобщённый синтаксис выглядит так: Общий синтаксис выглядит так:
.. code-block:: py .. code-block:: py
<command_name> <flag_prefix: Literal['-', '--', '---']><flag_name> <flag_value: Optional> <command_name> <flag_prefix: Literal['-', '--', '---']><flag_name> <flag_value: Optional>
То есть у флага обязательно должен быть префикс, который может быть одним, двумя или тремя минусами. После префикса следует имя флага, без Флаг состоит из префикса (``-``, ``--`` или ``---``), имени и, опционально, значения, которое указывается через пробел.
пробела, после чего, через пробел, идёт значение флага, если оно есть.
----- -----
@@ -27,9 +26,9 @@
Флаги бывают двух основных видов: без значений (переключатели) и со значениями. ``Argenta`` позволяет регистрировать и вводить флаги обоих типов в любой последовательности для одной команды. Флаги бывают двух основных видов: без значений (переключатели) и со значениями. ``Argenta`` позволяет регистрировать и вводить флаги обоих типов в любой последовательности для одной команды.
.. note:: .. note::
Ошибки валидации значений являются пассивными, их не нужно обрабатывать явно. У каждого инстанса :ref:`InputFlag <root_api_command_input_flag>` есть поле ``status``, по которому можно определить результат валидации флага. **Конкретная реализация и описание API вы можете найти в разделе** :ref:`Flag <root_api_command_flag>`. Ошибки валидации не выбрасывают исключений. Вместо этого у каждого объекта :ref:`InputFlag <root_api_command_input_flag>` есть атрибут ``status``, по которому можно определить, прошла ли валидация успешно. Подробное описание API для создания флагов находится в разделе :ref:`Flag <root_api_command_flag>`.
При регистрации флага вы можете указать допустимые для него значения, по умолчанию любое введённое значение для флага будет валидным. Допустимые значения можно указать различными способами: При регистрации флага можно задать правила валидации для его значения. По умолчанию любое значение считается корректным. Валидацию можно настроить несколькими способами:
----- -----
@@ -48,7 +47,7 @@
# Эта команда сработает # Эта команда сработает
export --format json export --format json
# А эта вызовет ошибку валидации, так как "csv" нет в списке разрешённых # А эта команда не пройдёт валидацию, так как значение "csv" не входит в список разрешённых
export --format csv export --format csv
----- -----
@@ -56,7 +55,7 @@
Проверка с помощью регулярных выражений Проверка с помощью регулярных выражений
----------------------------------------- -----------------------------------------
Для более сложных проверок вы можете использовать регулярные выражения. Это особенно полезно, когда значение должно соответствовать определённому формату, например, быть email-адресом, датой или номером телефона. Для более сложных проверок можно использовать регулярные выражения. Это полезно, когда значение должно соответствовать определённому формату (например, email-адрес, дата или номер телефона).
**Пример:** **Пример:**
@@ -65,10 +64,10 @@
.. code-block:: bash .. code-block:: bash
:linenos: :linenos:
# Сработает, так как значение соответствует формату email # Эта команда выполнится, так как значение соответствует формату email
send --email "user@example.com" send --email "user@example.com"
# Вызовет ошибку валидации, так как "user_example.com" — некорректный email # Эта команда не пройдёт валидацию, так как "user_example.com" — некорректный email
send --email "user_example.com" send --email "user_example.com"
Встроенная валидация избавляет вас от необходимости писать ручные проверки и делает ваш код более декларативным. Встроенная валидация избавляет от необходимости писать проверки вручную и делает код более декларативным.
+11 -11
View File
@@ -1,40 +1,40 @@
.. _root_overriding_formatting: .. _root_overriding_formatting:
Стандартное форматирование Управление форматированием вывода
========================== =================================
По умолчанию в ``Argenta`` используется библиотека ``rich`` для вывода текста с расширенным форматированием в консоли. ``rich`` позволяет применять цвета, стили (жирный, курсив, подчеркнутый), составлять таблицы, выделять синтаксис кода и многое другое, что значительно улучшает визуальное восприятие текста. По умолчанию ``Argenta`` использует библиотеку ``rich`` для вывода текста с расширенным форматированием. Она позволяет применять цвета и стили, создавать таблицы, подсвечивать синтаксис и многое другое, что улучшает визуальное восприятие информации.
Вывод системных сообщений производится с помощью метода ``print`` объекта ``Console`` из библиотеки ``rich``, который обладает интерфейсом, совместимым со встроенной функцией ``print``. Системные сообщения выводятся с помощью метода ``print`` объекта ``rich.console.Console``, который имеет интерфейс, совместимый со встроенной функцией ``print``.
------ ------
Управление стандартным форматированием Управление стандартным форматированием
-------------------------------------- --------------------------------------
При создании экземпляра класса ``App`` предусмотрен параметр ``override_system_messages`` типа ``bool`` (по умолчанию ``False``), который позволяет включать или отключать стандартное форматирование системных сообщений. При создании экземпляра ``App`` можно использовать параметр ``override_system_messages: bool`` (по умолчанию ``False``), который позволяет отключать стандартное форматирование.
Если установить этот флаг в ``True``, стандартное форматирование, применяемое по умолчанию (например, стилизация текста и ASCII-арт), будет отключено, и системные сообщения будут выводиться в "сыром" виде, без дополнительных стилей. Если установить его в ``True``, стилизация текста и ASCII-арт будут отключены, а системные сообщения выводиться в «сыром» виде.
----- -----
Приветственное и прощальное сообщения Приветственное и прощальное сообщения
-------------------------------------- --------------------------------------
Приветственное (``initial_message``) и прощальное (``farewell_message``) сообщения по умолчанию формируются как ASCII-графика с помощью библиотеки ``art``. В частности, используется функция ``text2art``, которая преобразует обычный текст в стилизованное ASCII-арт изображение. Приветственное (``initial_message``) и прощальное (``farewell_message``) сообщения по умолчанию выводятся в виде ASCII-графики с помощью библиотеки ``art`` (а именно, функции ``text2art``).
.. warning:: .. warning::
Библиотека ``art`` ориентирована на работу с ASCII-символами и **не поддерживает корректный вывод кириллицы**. Это приводит к искажению или некорректному отображению символов русского и других кириллических алфавитов. Если ваше приветственное сообщение содержит кириллицу, рекомендуется отключить стандартное форматирование с помощью ``override_system_messages=True`` или использовать только латинские символы. Библиотека ``art`` ориентирована на работу с ASCII-символами и **не поддерживает кириллицу**. Это приводит к искажению символов русского и других кириллических алфавитов. Если ваше сообщение содержит кириллицу, рекомендуется отключить форматирование с помощью ``override_system_messages=True`` или использовать только латинские символы.
----- -----
Кастомизация вывода Кастомизация вывода
------------------- -------------------
Для полной замены логики вывода сообщений в конструкторе ``App`` доступен параметр ``print_func``. Для полной замены логики вывода в конструкторе ``App`` предусмотрен параметр ``print_func``.
* **print_func**: ``Printer`` - Протокол ``Printer`` соответствует ``Callable[[str], None]``. * **print_func**: ``Callable[[str], None]``
Этот параметр позволяет передать любую вызываемую сущность (например, функцию или лямбду), которая будет использоваться для вывода всех системных сообщений. По умолчанию это обертка вокруг ``rich.console.Console().print``. Вы можете передать сюда свою функцию, чтобы, например, логировать вывод в файл или отправлять его по сети. Этот параметр позволяет передать любую вызываемую сущность (например, функцию), которая будет использоваться для вывода всех системных сообщений. По умолчанию это обёртка над ``rich.console.Console().print``. Вы можете передать сюда свою функцию, чтобы, например, логировать вывод в файл или отправлять его по сети.
Пример использования Пример использования
-------------------- --------------------
+3 -3
View File
@@ -9,19 +9,19 @@
pip install argenta pip install argenta
2. **Определение роутера и хэндлеров**. За регистрацию функции как обработчика отвечает декоратор ``@router.command``, хэндлер всегда должен принимать аргумент с типом ``Response``, подробнее в :ref:`разделе <root_api_response>`. 2. **Создание обработчиков**. Чтобы зарегистрировать функцию как обработчик команды, используйте декоратор ``@router.command``. Обработчик всегда должен принимать первым аргументом объект ``Response`` (подробнее в :ref:`документации <root_api_response>`).
.. literalinclude:: ../code_snippets/quickstart/routers.py .. literalinclude:: ../code_snippets/quickstart/routers.py
:language: python :language: python
:linenos: :linenos:
3. **Определение приложения и оркестратора**. Для запуска приложения необходимо вызвать ``.include_router()`` у созданного приложения и передать ему ранее созданный роутер, после этого необходимо вызвать ``.start_polling()`` у созданного оркестратора и передать ему созданное приложение. 3. **Настройка и запуск**. Чтобы подключить обработчики, вызовите метод ``.include_router()`` у экземпляра приложения и передайте в него ваш роутер. Затем создайте оркестратор и вызовите его метод ``.start_polling()``, передав ему приложение.
.. literalinclude:: ../code_snippets/quickstart/main.py .. literalinclude:: ../code_snippets/quickstart/main.py
:language: python :language: python
:linenos: :linenos:
4. **Запуск приложения**. Запускаем приложение как обычный скрипт. 4. **Запуск**. Теперь приложение можно запустить как обычный Python-скрипт.
.. image:: https://github.com/koloideal/Argenta/blob/docs/create_docs/imgs/mock_app_preview6.png?raw=true .. image:: https://github.com/koloideal/Argenta/blob/docs/create_docs/imgs/mock_app_preview6.png?raw=true
+14 -17
View File
@@ -3,24 +3,21 @@
Переопределение стандартного вывода Переопределение стандартного вывода
=================================== ===================================
О разделе ``Argenta`` предоставляет гибкие механизмы для форматирования вывода, включая динамические разделительные линии. Это достигается за счёт перехвата стандартного потока вывода (``stdout``), что накладывает некоторые особенности.
~~~~~~~~~
``Argenta`` предоставляет гибкие механизмы для управления форматированием вывода, включая использование динамических разделительных линий. Это достигается за счет перехвата стандартного потока вывода (``stdout``), что имеет свои особенности.
----- -----
Механизм перехвата ``stdout`` Механизм перехвата ``stdout``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
По умолчанию ``Argenta`` перехватывает весь текст, который выводится в ``stdout`` внутри обработчика команды (``handler``). Это делается для реализации **динамической длины разделителя**. Система анализирует весь выведенный текст, находит самую длинную строку и использует её длину для отрисовки верхней и нижней разделительных линий. Это создает аккуратный и визуально согласованный интерфейс, где вывод команды "обернут" в рамку, идеально подогнанную под его содержимое. По умолчанию ``Argenta`` перехватывает весь текст, выводимый в ``stdout`` внутри обработчика команды. Это необходимо для реализации **динамических разделителей**: система анализирует вывод, находит самую длинную строку и использует её для отрисовки верхней и нижней границ. Такой подход создаёт аккуратный интерфейс, где вывод команды «обёрнут» в рамку, подогнанную под его содержимое.
----- -----
Побочные эффекты перехвата ``stdout`` Побочные эффекты перехвата ``stdout``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Главный побочный эффект этого механизма проявляется при использовании функций, которые одновременно ожидают ввод от пользователя и выводят текст-приглашение. Классический пример — стандартная функция ``input()``. Главный побочный эффект этого механизма проявляется при использовании функций, которые одновременно ожидают ввод от пользователя и выводят приглашение в консоль. Классический пример — стандартная функция ``input()``.
.. code-block:: python .. code-block:: python
:linenos: :linenos:
@@ -30,44 +27,44 @@
print(f"Привет, {user_name}!") print(f"Привет, {user_name}!")
.. warning:: .. warning::
При включенном перехвате ``stdout`` текст-приглашение ``"Введите ваше имя: "`` **не будет выведен в консоль немедленно**. Он попадет в буфер, и пользователь увидит только мигающий курсор, ожидающий ввода. Текст приглашения будет выведен только после того, как выполнение всего обработчика завершится, вместе с остальным буферизованным выводом. Это может сбить пользователя с толку и является пограничным случаем, требующим внимания при разработке. При включённом перехвате ``stdout`` текст-приглашение (например, ``"Введите ваше имя: "``) **не будет выведен в консоль немедленно**. Он попадёт в буфер, и пользователь увидит только мигающий курсор. Текст приглашения отобразится лишь после завершения работы обработчика вместе с остальным выводом. Это может сбить пользователя с толку.
----- -----
Отключение перехвата ``stdout`` с помощью ``disable_redirect_stdout`` Отключение перехвата ``stdout`` с помощью ``disable_redirect_stdout``
--------------------------------------------------------------------- ---------------------------------------------------------------------
Чтобы решить проблему с ``input()`` и другими подобными функциями, в конструкторе класса ``Router`` предусмотрен специальный аргумент: Чтобы решить эту проблему, в конструкторе ``Router`` предусмотрен специальный аргумент:
* **disable_redirect_stdout** (``bool``, по умолчанию ``False``) * **disable_redirect_stdout** (``bool``, по умолчанию ``False``)
Если при создании роутера установить ``disable_redirect_stdout=True``, то для всех команд этого роутера механизм перехвата ``stdout`` будет отключен. Если при создании роутера установить ``disable_redirect_stdout=True``, механизм перехвата ``stdout`` будет отключён для всех его обработчиков.
.. literalinclude:: ../code_snippets/redirect_stdout/sample.py .. literalinclude:: ../code_snippets/redirect_stdout/sample.py
:language: python :language: python
:linenos: :linenos:
В этом случае ``input()`` будет работать как обычно, и пользователь сразу увидит приглашение "Как вас зовут?". В этом случае ``input()`` будет работать как обычно, и пользователь сразу увидит приглашение к вводу.
----- -----
Типы разделительных линий Типы разделительных линий
-------------------------- --------------------------
``Argenta`` поддерживает два типа разделительных линий, которые можно настроить при инициализации ``App``: ``Argenta`` поддерживает два типа разделителей, которые настраиваются при инициализации ``App``:
1. **DynamicDividingLine()** 1. **DynamicDividingLine()**
* Это поведение по умолчанию. Длина линии динамически подстраивается под самый длинный выведенный текст. * Поведение по умолчанию. Длина линии динамически подстраивается под самый длинный текст в выводе.
* Требует включенного перехвата ``stdout`` (т.е. ``disable_redirect_stdout=False`` на роутере). * Требует включённого перехвата ``stdout`` (``disable_redirect_stdout=False`` в роутере).
2. **StaticDividingLine(length: int = 25)** 2. **StaticDividingLine(length: int = 25)**
* Линия имеет фиксированную длину (по умолчанию 25 символов), которую можно настроить через аргумент `length`. * Линия имеет фиксированную длину (по умолчанию 25 символов), которую можно задать через аргумент `length`.
* Используется автоматически для роутеров, где ``disable_redirect_stdout=True``, так как без перехвата вывода невозможно определить необходимую динамическую длину. * Используется принудительно для роутеров с ``disable_redirect_stdout=True``, так как без перехвата вывода невозможно определить динамическую длину.
Настройка разделительной линии в `App` Настройка разделительной линии в `App`
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Вы можете глобально задать тип разделительной линии для всего приложения через аргумент ``dividing_line`` в конструкторе ``App``. Вы можете глобально задать тип разделителя для всего приложения через аргумент ``dividing_line`` в конструкторе ``App``.
.. literalinclude:: ../code_snippets/redirect_stdout/sample2.py .. literalinclude:: ../code_snippets/redirect_stdout/sample2.py
:language: python :language: python
@@ -103,4 +100,4 @@
- Статическая линия указанной длины - Статическая линия указанной длины
- Да - Да
Таким образом, для создания интерактивных команд, требующих ввода от пользователя, всегда отключайте перехват ``stdout`` на соответствующем роутере. Для всех остальных команд можно оставить поведение по умолчанию. Таким образом, для интерактивных команд, требующих ввода от пользователя, отключайте перехват ``stdout`` на уровне роутера. Для всех остальных команд можно оставить поведение по умолчанию.