From ae9795bd534e429b23f0eeff1176316e9295c105 Mon Sep 17 00:00:00 2001 From: kolo Date: Fri, 4 Apr 2025 01:43:59 +0300 Subject: [PATCH] some fix and final refactor in readme --- README.md | 241 ++++++++++++++++++++---------- argenta/app/models.py | 5 - argenta/command/flag/models.py | 2 +- mock/default_mock_app/__init__.py | 0 mock/default_mock_app/main.py | 9 ++ pyproject.toml | 2 +- 6 files changed, 172 insertions(+), 87 deletions(-) create mode 100644 mock/default_mock_app/__init__.py create mode 100644 mock/default_mock_app/main.py diff --git a/README.md b/README.md index 4d900cd..24e0c2c 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ ## Описание **Argenta** — Python library for creating custom shells -![prewiev](imgs/mock_app_preview_last.png) +![prewiev](https://github.com/koloideal/Argenta/blob/kolo/imgs/mock_app_preview_last.png?raw=True) Пример внешнего вида TUI, написанного с помощью Argenta --- @@ -95,33 +95,29 @@ def handler_with_flags(flags: InputFlags): ### Конструктор ```python -App(prompt: str = 'Enter a command', - initial_greeting: str = '\nHello, I am Argenta\n', - farewell_message: str = '\nGoodBye\n', +App(prompt: str = 'What do you want to do?\n', + initial_message: str = 'Argenta', + farewell_message: str = 'See you', exit_command: str = 'Q', exit_command_description: str = 'Exit command', system_points_title: str = 'System points:', - ignore_exit_command_register: bool = True, - ignore_command_register: bool = False, - line_separate: str = '', - command_group_description_separate: str = '', + ignore_command_register: bool = True, + line_separate: str = '-----', repeat_command_groups: bool = True, - print_func: Callable[[str], None] = print) + print_func: Callable[[str], None] = Console().print) ``` **Аргументы:** - **name : mean** - `prompt` (`str`): Сообщение перед вводом команды. -- `initial_greeting` (`str`): Приветственное сообщение при запуске. +- `initial_message` (`str`): Приветственное сообщение при запуске. - `farewell_message` (`str`): Сообщение при выходе. - `exit_command` (`str`): Команда выхода (по умолчанию `'Q'`). - `exit_command_description` (`str`): Описание команды выхода. - `system_points_title` (`str`): Заголовок перед списком системных команд. -- `ignore_exit_command_register` (`bool`): Игнорировать регистр команды выхода. - `ignore_command_register` (`bool`): Игнорировать регистр всех команд. - `line_separate` (`str`): Разделительная строка между командами. -- `command_group_description_separate` (`str`): Разделитель между группами команд. - `repeat_command_groups` (`bool`): Повторять описание команд перед вводом. -- `print_func` (`Callable[[str], None]`): Функция вывода текста в терминал (по умолчанию `print`). +- `print_func` (`Callable[[str], None]`): Функция вывода текста в терминал. --- @@ -131,94 +127,83 @@ App(prompt: str = 'Enter a command', #### **.start_polling() -> `None`** -*method mean* **::** запускает цикл обработки ввода +*method mean* **::** Запускает цикл обработки ввода --- #### **.include_router(router: Router) -> `None`** -*param* `router: Router` **::** регистрируемый роутер +*param* `router: Router` **::** Регистрируемый роутер *required* **::** True -*method mean* **::** регистрирует роутер в оболочке +*method mean* **::** Регистрирует роутер в оболочке --- -#### **.set_initial_message(message: str) -> `None`** +#### **.include_routers(\*routers: Router) -> `None`** -*param* `message: str` **::** устанавливаемое приветственное сообщение -*required* **::** True -*example* **::** `"Hello, I'm a example app"` +*param* `routers: Router` **::** Неограниченное количество регистрируемых роутеров +*required* **::** True -*method mean* **::** устанавливает сообщение, которое будет отображено при запуске программы - ---- - -#### **.set_farewell_message(message: str) -> `None`** - -*param* `message: str` **::** устанавливаемое сообщение при выходе -*required* **::** True -*example* **::** `"GoodBye !"` - -*method mean* **::** устанавливает сообщение, которое будет отображено при выходе +*method mean* **::** Регистрирует роутер в оболочке --- #### **.set_description_message_pattern(pattern: str) -> `None`** -*param* `pattern: str` **::** паттерн описания команды при её выводе в консоль +*param* `pattern: str` **::** Паттерн описания команды при её выводе в консоль *required* **::** True *example* **::** `"[{command}] *=*=* {description}"` -*method mean* **::** устанавливает паттерн описания команд, который будет использован +*method mean* **::** Устанавливает паттерн описания команд, который будет использован при выводе в консоль --- - -#### **.set_repeated_input_flags_handler(handler: Callable[[str], None]) -> `None`** -*param* `handler: Callable[[str], None]` **::** функция или лямбда функция, которой будет передано управление при -вводе юзером повторяющихся флагов +#### **.add_message_on_startup(message: str) -> `None`** + +*param* `message: str` **::** Сообщение, которое будет выведено при запуске приложения *required* **::** True +*example* **::** `Message on startup` + +*method mean* **::** Устанавливает паттерн описания команд, который будет использован +при выводе в консоль + +--- + + +#### **.repeated_input_flags_handler: `Callable[[str], None])`** + *example* **::** `lambda raw_command: print_func(f'Repeated input flags: "{raw_command}"')` -*method mean* **::** устанавливает функцию, которой будет передано управление при +*attr mean* **::** Устанавливает функцию, которой будет передано управление при вводе юзером повторяющихся флагов --- -#### **.set_invalid_input_flags_handler(self, handler: Callable[[str], None]) -> `None`** +#### **.invalid_input_flags_handler: `Callable[[str], None])`** -*param* `handler: Callable[[str], None]` **::** функция или лямбда функция, которой будет передано управление при -вводе юзером команды с некорректным синтаксисом флагов -*required* **::** True *example* **::** `lambda raw_command: print_func(f'Incorrect flag syntax: "{raw_command}"')` -*method mean* **::** устанавливает функцию, которой будет передано управление при +*attr mean* **::** Устанавливает функцию, которой будет передано управление при вводе юзером команды с некорректным синтаксисом флагов --- -#### **.set_unknown_command_handler(self, handler: Callable[[str], None]) -> `None`** +#### **.unknown_command_handler: `Callable[[str], None]`** -*param* `handler: Callable[[str], None]` **::** функция или лямбда функция, которой будет передано управление при -вводе юзером неизвестной команды -*required* **::** True *example* **::** `lambda command: print_func(f"Unknown command: {command.get_string_entity()}")` -*method mean* **::** устанавливает функцию, которой будет передано управление при +*attr mean* **::** Устанавливает функцию, которой будет передано управление при вводе юзером неизвестной команды --- -#### **.set_empty_command_handler(self, handler: Callable[[str], None]) -> `None`** +#### **.empty_command_handler: `Callable[[str], None])`** -*param* `handler: Callable[[str], None]` **::** функция или лямбда функция, которой будет передано управление при -вводе юзером пустой команды -*required* **::** True *example* **::** `lambda: print_func(f'Empty input command')` -*method mean* **::** устанавливает функцию, которой будет передано управление при +*attr mean* **::** Устанавливает функцию, которой будет передано управление при вводе юзером пустой команды --- @@ -236,6 +221,9 @@ App(prompt: str = 'Enter a command', `RepeatedCommandInDifferentRoutersException`. Исключение вызывается только при наличии пересекающихся команд у __разных__ роутеров +- Наиболее частые сообщение при запуске предопределены и доступны для быстрого +использования: `argenta.app.defaults.PredeterminedMessages` + @@ -244,9 +232,7 @@ App(prompt: str = 'Enter a command', - `InvalidRouterInstanceException` — Переданный объект в метод `App().include_router()` не является экземпляром класса `Router`. - `InvalidDescriptionMessagePatternException` — Неправильный формат паттерна описания команд. - `IncorrectNumberOfHandlerArgsException` — У обработчика нестандартного поведения зарегистрировано неверное количество аргументов(в большинстве случаев у него должен быть один аргумент). -- `NoRegisteredRoutersException` — Отсутствуют зарегистрированные роутеры. - `NoRegisteredHandlersException` — У роутера нет ни одного обработчика команд. -- `RepeatedCommandInDifferentRoutersException` — Одна и та же команда зарегистрирована в разных роутерах. --- @@ -274,32 +260,27 @@ Router(title: str = 'Commands group title:', #### **command(command: Command)** -*param* `command: Command` **::** экземпляр класса `Command`, который определяет строковый триггер команды, +*param* `command: Command` **::** Экземпляр класса `Command`, который определяет строковый триггер команды, допустимые флаги команды и другое *required* **::** True *example* **::** `Command(command='ssh', description='connect via ssh')` -*method mean* **::** декоратор, который регистрирует функцию как обработчик команды +*method mean* **::** Декоратор, который регистрирует функцию как обработчик команды --- #### **.get_name() -> `str`** -*method mean* **::** возвращает установленное название роутера +*method mean* **::** Возвращает установленное название роутера --- #### **.get_title() -> `str`** -*method mean* **::** возвращает установленный заголовок группы команд данного роутера +*method mean* **::** Возвращает установленный заголовок группы команд данного роутера --- -#### **.get_all_commands() -> `list[str]`** - -*method mean* **::** возвращает все зарегистрированные команды для данного роутера - ---- ### Исключения - `RepeatedFlagNameException` - Повторяющиеся зарегистрированные флаги в команде @@ -330,19 +311,19 @@ Command(trigger: str, #### **.get_trigger() -> `str`** -*method mean* **::** возвращает строковый триггер экземпляра +*method mean* **::** Возвращает строковый триггер экземпляра --- #### **.get_description() -> `str`** -*method mean* **::** возвращает описание команды +*method mean* **::** Возвращает описание команды --- #### **.get_registered_flags() -> `Flags | None`** -*method mean* **::** возвращает зарегистрированные флаги экземпляра +*method mean* **::** Возвращает зарегистрированные флаги экземпляра --- @@ -364,18 +345,18 @@ Command(trigger: str, ### Конструктор ```python -Flag(flag_name: str, - flag_prefix: typing.Literal['-', '--', '---'] = '-', - possible_flag_values: list[str] | typing.Pattern[str] | False = True) +Flag(name: str, + prefix: typing.Literal['-', '--', '---'] = '-', + possible_values: list[str] | typing.Pattern[str] | False = True) ``` --- **Аргументы:** - **name : mean** -- `flag_name` (`str`): Имя флага -- `flag_prefix` (`Literal['-', '--', '---']`): Префикс команды, допустимым значением является от одного до трёх минусов -- `possible_flag_values` (`list[str] | Pattern[str] | bool`): Множество допустимых значений флага, может быть задано +- `name` (`str`): Имя флага +- `prefix` (`Literal['-', '--', '---']`): Префикс команды, допустимым значением является от одного до трёх минусов +- `possible_values` (`list[str] | Pattern[str] | bool`): Множество допустимых значений флага, может быть задано списком с допустимыми значениями или регулярным выражением (рекомендуется `re.compile(r'example exspression')`), при значении аргумента `False` у введённого флага не может быть значения, иначе будет вызвано исключение и обработано соответствующим еррор-хэндлером @@ -388,19 +369,60 @@ Flag(flag_name: str, #### **.get_string_entity() -> `str`** -*method mean* **::** возвращает строковое представление флага(префикс + имя) +*method mean* **::** Возвращает строковое представление флага(префикс + имя) --- -#### **.get_flag_name() -> `str`** +#### **.get_name() -> `str`** -*method mean* **::** возвращает имя флага +*method mean* **::** Возвращает имя флага --- -#### **.get_flag_prefix() -> `str`** +#### **.get_prefix() -> `str`** -*method mean* **::** возвращает префикс флага +*method mean* **::** Возвращает префикс флага + +--- + +## *class* :: `InputFlag` +Класс, экземпляры которого являются введёнными флагами команды, передаётся в хэндлер команды +через `InputFlags` + +--- + +### Примечания + +- Наиболее часто используемые флаги предопределены и доступны для быстрого использования: +`argenta.command.flag.defaults.PredeterminedFlags` + +--- + + +### Конструктор +```python +InputFlag(name: str, + prefix: typing.Literal['-', '--', '---'] = '-', + value: str = None) +``` + +--- + +**Аргументы:** +- **name : mean** +- `name` (`str`): Имя флага +- `prefix` (`Literal['-', '--', '---']`): Префикс команды, допустимым значением является от одного до трёх минусов +- `value` (`str`): Значение введённого флага, если оно есть + +--- + +### ***methods*** + +--- + +#### **.get_value() -> `str | None`** + +*method mean* **::** Возвращает значение введённого флага --- @@ -411,7 +433,7 @@ Flag(flag_name: str, ### Конструктор ```python -Flags(*flagы: Flag) +Flags(*flags: Flag) ``` --- @@ -428,7 +450,66 @@ Flags(*flagы: Flag) #### **.get_flags() -> `list[Flag]`** -*method mean* **::** возвращает зарегистрированные флаги +*method mean* **::** Возвращает зарегистрированные флаги + +--- + +#### **.add_flag(flag: Flag) -> `None`** + +*method mean* **::** Добавляет флаг в группу + +--- + +#### **.add_flags(flags: list[Flag]) -> `None`** + +*method mean* **::** Добавляет флаги в группу + +--- + +#### **.get_flag(name: str) -> `Flag | None`** + +*param* `name: str` **::** Строковый триггер флага без префикса +*required* **::** True +*example* **::** `'host'` + +*method mean* **::** Возвращает флаг по его триггеру или `None`, если флаг не найден + +--- + +## *class* :: `InputFlags` +Класс, объединяющий список введённых флагов в один объект, передаётся соответствующему хэндлеру +в качестве аргумента + +### Конструктор +```python +InputFlags(*flags: Flag) +``` + +--- + +**Аргументы:** +- **name : mean** +- `*flags` (`InputFlag`): Неограниченное количество передаваемых флагов + +--- + +### ***methods*** + +--- + +#### **.get_flags() -> `list[Flag]`** + +*method mean* **::** Возвращает введённые флаги + +--- + +#### **.get_flag(name: str) -> `InputFlag | None`** + +*param* `name: str` **::** Строковый триггер флага без префикса +*required* **::** True +*example* **::** `'host'` + +*method mean* **::** Возвращает введённый флаг по его триггеру или `None`, если флаг не найден --- diff --git a/argenta/app/models.py b/argenta/app/models.py index 0f2c329..141707c 100644 --- a/argenta/app/models.py +++ b/argenta/app/models.py @@ -151,9 +151,6 @@ class App(BaseApp): self._print_func(self._line_separate) self._error_handler(error, raw_command) self._print_func(self._line_separate) - - if not self._repeat_command_groups_description: - self._print_func(self._prompt) continue if self._is_exit_command(input_command): @@ -163,8 +160,6 @@ class App(BaseApp): if self._is_unknown_command(input_command): self._print_func(self._line_separate) - if not self._repeat_command_groups_description: - self._print_func(self._prompt) continue for registered_router in self._registered_routers: diff --git a/argenta/command/flag/models.py b/argenta/command/flag/models.py index 40b6615..7f3a042 100644 --- a/argenta/command/flag/models.py +++ b/argenta/command/flag/models.py @@ -27,7 +27,7 @@ class InputFlag(BaseFlag): super().__init__(name, prefix) self._flag_value = value - def get_value(self): + def get_value(self) -> str | None: return self._flag_value def set_value(self, value): diff --git a/mock/default_mock_app/__init__.py b/mock/default_mock_app/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/mock/default_mock_app/main.py b/mock/default_mock_app/main.py new file mode 100644 index 0000000..1af7849 --- /dev/null +++ b/mock/default_mock_app/main.py @@ -0,0 +1,9 @@ +from argenta.app import App +from argenta.app.defaults import PredeterminedMessages + + +app = App(repeat_command_groups=True) + +app.add_message_on_startup(PredeterminedMessages.USAGE + '\n\n') + +app.start_polling() diff --git a/pyproject.toml b/pyproject.toml index c786bef..1716ce2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "argenta" -version = "0.4.6" +version = "0.4.7" description = "python library for creating custom shells" authors = [ {name = "kolo", email = "kolo.is.main@gmail.com"}