argenta 0.3.5__py3-none-any.whl → 0.3.6__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
argenta/app/__init__.py CHANGED
@@ -1,3 +1 @@
1
1
  from .entity import App
2
- from .exceptions import (InvalidDescriptionMessagePatternException,
3
- InvalidRouterInstanceException)
argenta/app/entity.py CHANGED
@@ -23,7 +23,7 @@ class App:
23
23
  invalid_input_flags_message: str = 'Invalid input flags',
24
24
  exit_command: str = 'Q',
25
25
  exit_command_description: str = 'Exit command',
26
- exit_command_title: str = 'System points:',
26
+ system_points_title: str = 'System points:',
27
27
  ignore_exit_command_register: bool = True,
28
28
  ignore_command_register: bool = False,
29
29
  line_separate: str = '',
@@ -34,7 +34,7 @@ class App:
34
34
  self.print_func = print_func
35
35
  self.exit_command = exit_command
36
36
  self.exit_command_description = exit_command_description
37
- self.exit_command_title = exit_command_title
37
+ self.system_points_title = system_points_title
38
38
  self.ignore_exit_command_register = ignore_exit_command_register
39
39
  self.farewell_message = farewell_message
40
40
  self.initial_message = initial_message
@@ -100,7 +100,7 @@ class App:
100
100
  self.print_func(self.prompt)
101
101
  continue
102
102
 
103
- self._check_command_for_exit_command(input_command.get_string_entity())
103
+ self._check_command_for_exit_command(input_command.get_trigger())
104
104
 
105
105
  self.print_func(self.line_separate)
106
106
  is_unknown_command: bool = self._check_is_command_unknown(input_command)
@@ -163,6 +163,14 @@ class App:
163
163
  self._unknown_command_handler = handler
164
164
 
165
165
 
166
+ def set_empty_command_handler(self, handler: Callable[[str], None]) -> None:
167
+ args = getfullargspec(handler).args
168
+ if len(args) != 1:
169
+ raise IncorrectNumberOfHandlerArgsException()
170
+ else:
171
+ self._empty_input_command_handler = handler
172
+
173
+
166
174
  def include_router(self, router: Router) -> None:
167
175
  if not isinstance(router, Router):
168
176
  raise InvalidRouterInstanceException()
@@ -219,11 +227,11 @@ class App:
219
227
  registered_router_entities: list[dict[str, str | list[dict[str, Callable[[], None] | Command]] | Router]] = self._registered_router_entities
220
228
  for router_entity in registered_router_entities:
221
229
  for command_entity in router_entity['commands']:
222
- if command_entity['command'].get_string_entity().lower() == command.get_string_entity().lower():
230
+ if command_entity['command'].get_trigger().lower() == command.get_trigger().lower():
223
231
  if self.ignore_command_register:
224
232
  return False
225
233
  else:
226
- if command_entity['command'].get_string_entity() == command.get_string_entity():
234
+ if command_entity['command'].get_trigger() == command.get_trigger():
227
235
  return False
228
236
  self._unknown_command_handler(command)
229
237
  return True
@@ -234,13 +242,13 @@ class App:
234
242
  self.print_func(router_entity['title'])
235
243
  for command_entity in router_entity['commands']:
236
244
  self.print_func(self._description_message_pattern.format(
237
- command=command_entity['command'].get_string_entity(),
245
+ command=command_entity['command'].get_trigger(),
238
246
  description=command_entity['command'].get_description()
239
247
  )
240
248
  )
241
249
  self.print_func(self.command_group_description_separate)
242
250
 
243
- self.print_func(self.exit_command_title)
251
+ self.print_func(self.system_points_title)
244
252
  self.print_func(self._description_message_pattern.format(
245
253
  command=self.exit_command,
246
254
  description=self.exit_command_description
argenta/command/entity.py CHANGED
@@ -1,9 +1,6 @@
1
1
  from .params.flag.entity import Flag
2
2
  from .params.flag.flags_group.entity import FlagsGroup
3
- from .exceptions import (InvalidCommandInstanceException,
4
- InvalidDescriptionInstanceException,
5
- InvalidFlagsInstanceException,
6
- UnprocessedInputFlagException,
3
+ from .exceptions import (UnprocessedInputFlagException,
7
4
  RepeatedInputFlagsException,
8
5
  EmptyInputCommandException)
9
6
 
@@ -14,37 +11,28 @@ T = TypeVar('T')
14
11
 
15
12
 
16
13
  class Command(Generic[T]):
17
- def __init__(self, command: str,
14
+ def __init__(self, trigger: str,
18
15
  description: str = None,
19
- flags: Flag | FlagsGroup | None = None):
20
- self._command = command
21
- self._description = f'description for "{self._command}" command' if not description else description
16
+ flags: Flag | FlagsGroup = None):
17
+ self._trigger = trigger
18
+ self._description = f'description for "{self._trigger}" command' if not description else description
22
19
  self._registered_flags: FlagsGroup | None = flags if isinstance(flags, FlagsGroup) else FlagsGroup([flags]) if isinstance(flags, Flag) else flags
23
20
 
24
21
  self._input_flags: FlagsGroup | None = None
25
22
 
26
23
 
27
- def get_string_entity(self):
28
- return self._command
24
+ def get_trigger(self) -> str:
25
+ return self._trigger
29
26
 
30
27
 
31
- def get_description(self):
28
+ def get_description(self) -> str:
32
29
  return self._description
33
30
 
34
31
 
35
- def get_registered_flags(self):
32
+ def get_registered_flags(self) -> FlagsGroup | None:
36
33
  return self._registered_flags
37
34
 
38
35
 
39
- def validate_commands_params(self):
40
- if not isinstance(self._command, str):
41
- raise InvalidCommandInstanceException(self._command)
42
- if not isinstance(self._description, str):
43
- raise InvalidDescriptionInstanceException()
44
- if not any([(isinstance(self._registered_flags, FlagsGroup)), not self._registered_flags]):
45
- raise InvalidFlagsInstanceException
46
-
47
-
48
36
  def validate_input_flag(self, flag: Flag):
49
37
  registered_flags: FlagsGroup | None = self.get_registered_flags()
50
38
  if registered_flags:
@@ -62,7 +50,7 @@ class Command(Generic[T]):
62
50
  return False
63
51
 
64
52
 
65
- def set_input_flags(self, input_flags: FlagsGroup):
53
+ def _set_input_flags(self, input_flags: FlagsGroup):
66
54
  self._input_flags = input_flags
67
55
 
68
56
  def get_input_flags(self) -> FlagsGroup:
@@ -93,9 +81,8 @@ class Command(Generic[T]):
93
81
  current_flag_value = _
94
82
  if current_flag_name and current_flag_value:
95
83
  flag_prefix_last_symbol_index = current_flag_name.rfind('-')
96
- flag_prefix = current_flag_name[:flag_prefix_last_symbol_index]
97
- flag_name = current_flag_name[flag_prefix_last_symbol_index:]
98
-
84
+ flag_prefix = current_flag_name[:flag_prefix_last_symbol_index+1]
85
+ flag_name = current_flag_name[flag_prefix_last_symbol_index+1:]
99
86
  input_flag = Flag(flag_name=flag_name,
100
87
  flag_prefix=flag_prefix)
101
88
  input_flag.set_value(current_flag_value)
@@ -111,10 +98,10 @@ class Command(Generic[T]):
111
98
  if any([current_flag_name, current_flag_value]):
112
99
  raise UnprocessedInputFlagException()
113
100
  if len(flags.get_flags()) == 0:
114
- return Command(command=command)
101
+ return Command(trigger=command)
115
102
  else:
116
- input_command = Command(command=command)
117
- input_command.set_input_flags(flags)
103
+ input_command = Command(trigger=command)
104
+ input_command._set_input_flags(flags)
118
105
  return input_command
119
106
 
120
107
 
@@ -1,21 +1,6 @@
1
1
  from .params.flag.entity import Flag
2
2
 
3
3
 
4
- class InvalidCommandInstanceException(Exception):
5
- def __str__(self):
6
- return "Invalid Command Instance"
7
-
8
-
9
- class InvalidDescriptionInstanceException(Exception):
10
- def __str__(self):
11
- return "Invalid Description Instance"
12
-
13
-
14
- class InvalidFlagsInstanceException(Exception):
15
- def __str__(self):
16
- return "Invalid Flags Instance"
17
-
18
-
19
4
  class UnprocessedInputFlagException(Exception):
20
5
  def __str__(self):
21
6
  return "Unprocessed Input Flags"
@@ -3,7 +3,7 @@ from typing import Literal, Pattern
3
3
 
4
4
  class Flag:
5
5
  def __init__(self, flag_name: str,
6
- flag_prefix: Literal['-', '--', '---'] = '-',
6
+ flag_prefix: Literal['-', '--', '---'] = '--',
7
7
  ignore_flag_value_register: bool = False,
8
8
  possible_flag_values: list[str] | Pattern[str] = False):
9
9
  self._flag_name = flag_name
@@ -11,7 +11,7 @@ class Flag:
11
11
  self.possible_flag_values = possible_flag_values
12
12
  self.ignore_flag_value_register = ignore_flag_value_register
13
13
 
14
- self._value = None
14
+ self._flag_value = None
15
15
 
16
16
  def get_string_entity(self):
17
17
  string_entity: str = self._flag_prefix + self._flag_name
@@ -24,10 +24,10 @@ class Flag:
24
24
  return self._flag_prefix
25
25
 
26
26
  def get_value(self):
27
- return self._value
27
+ return self._flag_value
28
28
 
29
29
  def set_value(self, value):
30
- self._value = value
30
+ self._flag_value = value
31
31
 
32
32
  def validate_input_flag_value(self, input_flag_value: str):
33
33
  if isinstance(self.possible_flag_values, Pattern):
@@ -5,7 +5,7 @@ class FlagsGroup:
5
5
  def __init__(self, flags: list[Flag] = None):
6
6
  self._flags: list[Flag] = [] if not flags else flags
7
7
 
8
- def get_flags(self):
8
+ def get_flags(self) -> list[Flag]:
9
9
  return self._flags
10
10
 
11
11
  def add_flag(self, flag: Flag):
@@ -14,6 +14,17 @@ class FlagsGroup:
14
14
  def add_flags(self, flags: list[Flag]):
15
15
  self._flags.extend(flags)
16
16
 
17
+ def unparse_to_dict(self):
18
+ result_dict: dict[str, dict] = {}
19
+ for flag in self._flags:
20
+ result_dict[flag.get_flag_name()] = {
21
+ 'name': flag.get_flag_name(),
22
+ 'string_entity': flag.get_string_entity(),
23
+ 'prefix': flag.get_flag_prefix(),
24
+ 'value': flag.get_value()
25
+ }
26
+ return result_dict
27
+
17
28
  def __iter__(self):
18
29
  return iter(self._flags)
19
30
 
@@ -1,2 +1 @@
1
- from .entity import Router
2
- from .exceptions import InvalidDescriptionInstanceException
1
+ from .entity import Router
argenta/router/entity.py CHANGED
@@ -4,7 +4,8 @@ from inspect import getfullargspec
4
4
  from ..command.entity import Command
5
5
  from ..command.params.flag.entity import Flag
6
6
  from ..command.params.flag.flags_group.entity import FlagsGroup
7
- from ..router.exceptions import (RepeatedCommandException, RepeatedFlagNameException,
7
+ from ..router.exceptions import (RepeatedCommandException,
8
+ RepeatedFlagNameException,
8
9
  TooManyTransferredArgsException,
9
10
  RequiredArgumentNotPassedException,
10
11
  IncorrectNumberOfHandlerArgsException)
@@ -15,8 +16,8 @@ class Router:
15
16
  title: str = 'Commands group title:',
16
17
  name: str = 'subordinate'):
17
18
 
18
- self.title = title
19
- self.name = name
19
+ self._title = title
20
+ self._name = name
20
21
 
21
22
  self._command_entities: list[dict[str, Callable[[], None] | Command]] = []
22
23
  self._ignore_command_register: bool = False
@@ -25,7 +26,6 @@ class Router:
25
26
 
26
27
 
27
28
  def command(self, command: Command) -> Callable[[Any], Any]:
28
- command.validate_commands_params()
29
29
  self._validate_command(command)
30
30
 
31
31
  def command_decorator(func):
@@ -47,10 +47,10 @@ class Router:
47
47
 
48
48
 
49
49
  def input_command_handler(self, input_command: Command):
50
- input_command_name: str = input_command.get_string_entity()
50
+ input_command_name: str = input_command.get_trigger()
51
51
  input_command_flags: FlagsGroup = input_command.get_input_flags()
52
52
  for command_entity in self._command_entities:
53
- if input_command_name.lower() == command_entity['command'].get_string_entity().lower():
53
+ if input_command_name.lower() == command_entity['command'].get_trigger().lower():
54
54
  if command_entity['command'].get_registered_flags():
55
55
  if input_command_flags:
56
56
  for flag in input_command_flags:
@@ -58,9 +58,9 @@ class Router:
58
58
  if not is_valid:
59
59
  self._not_valid_flag_handler(flag)
60
60
  return
61
- return command_entity['handler_func'](input_command_flags)
61
+ return command_entity['handler_func'](input_command_flags.unparse_to_dict())
62
62
  else:
63
- return command_entity['handler_func'](FlagsGroup(None))
63
+ return command_entity['handler_func']({})
64
64
  else:
65
65
  if input_command_flags:
66
66
  self._not_valid_flag_handler(input_command_flags[0])
@@ -70,7 +70,7 @@ class Router:
70
70
 
71
71
 
72
72
  def _validate_command(self, command: Command):
73
- command_name: str = command.get_string_entity()
73
+ command_name: str = command.get_trigger()
74
74
  if command_name in self.get_all_commands():
75
75
  raise RepeatedCommandException()
76
76
  if self._ignore_command_register:
@@ -106,16 +106,16 @@ class Router:
106
106
 
107
107
 
108
108
  def get_name(self) -> str:
109
- return self.name
109
+ return self._name
110
110
 
111
111
 
112
112
  def get_title(self) -> str:
113
- return self.title
113
+ return self._title
114
114
 
115
115
 
116
116
  def get_all_commands(self) -> list[str]:
117
117
  all_commands: list[str] = []
118
118
  for command_entity in self._command_entities:
119
- all_commands.append(command_entity['command'].get_string_entity())
119
+ all_commands.append(command_entity['command'].get_trigger())
120
120
 
121
121
  return all_commands
@@ -1,8 +1,3 @@
1
- class InvalidDescriptionInstanceException(Exception):
2
- def __str__(self):
3
- return "Invalid Description Instance"
4
-
5
-
6
1
  class RepeatedCommandException(Exception):
7
2
  def __str__(self):
8
3
  return "Commands in handler cannot be repeated"
@@ -23,11 +18,6 @@ class RequiredArgumentNotPassedException(Exception):
23
18
  return "Required argument not passed"
24
19
 
25
20
 
26
- class NotValidInputFlagHandlerHasBeenAlreadyCreatedException(Exception):
27
- def __str__(self):
28
- return "Invalid Input Flag Handler has already been created"
29
-
30
-
31
21
  class IncorrectNumberOfHandlerArgsException(Exception):
32
22
  def __str__(self):
33
- return "Incorrect Input Flags Handler has incorrect number of arguments"
23
+ return "Handler has incorrect number of arguments"
@@ -0,0 +1,452 @@
1
+ Metadata-Version: 2.3
2
+ Name: argenta
3
+ Version: 0.3.6
4
+ Summary: python library for creating custom shells
5
+ License: MIT
6
+ Author: kolo
7
+ Author-email: kolo.is.main@gmail.com
8
+ Requires-Python: >=3.11
9
+ Classifier: License :: OSI Approved :: MIT License
10
+ Classifier: Programming Language :: Python :: 3
11
+ Classifier: Programming Language :: Python :: 3.11
12
+ Classifier: Programming Language :: Python :: 3.12
13
+ Classifier: Programming Language :: Python :: 3.13
14
+ Description-Content-Type: text/markdown
15
+
16
+ # Argenta
17
+
18
+ ---
19
+
20
+ ## Описание
21
+ **Argenta** — Python library for creating custom shells
22
+
23
+ ---
24
+
25
+ # Установка
26
+ ```bash
27
+ pip install argenta
28
+ ```
29
+ or
30
+ ```bash
31
+ poetry add argenta
32
+ ```
33
+
34
+ ---
35
+
36
+ # Быстрый старт
37
+
38
+ Пример простейшей оболочки с командой без флагов
39
+ ```python
40
+ # routers.py
41
+ from argenta.router import Router
42
+ from argenta.command import Command
43
+
44
+
45
+ router = Router()
46
+
47
+ @router.command(Command("hello"))
48
+ def handler():
49
+ print("Hello, world!")
50
+ ```
51
+
52
+ ```python
53
+ # main.py
54
+ from argenta.app import App
55
+ from routers import router
56
+
57
+ app: App = App()
58
+
59
+ def main() -> None:
60
+ app.include_router(router)
61
+ app.start_polling()
62
+
63
+
64
+ if __name__ == '__main__':
65
+ main()
66
+ ```
67
+ Пример оболочки с командой, у которой зарегистрированы флаги
68
+
69
+ ```python
70
+ # routers.py
71
+ import re
72
+ from argenta.router import Router
73
+ from argenta.command import Command
74
+ from argenta.command.params.flag import FlagsGroup, Flag
75
+
76
+ router = Router()
77
+
78
+ list_of_flags = [
79
+ Flag(flag_name='host',
80
+ flag_prefix='--',
81
+ possible_flag_values=re.compile(r'^192.168.\d{1,3}.\d{1,3}$')),
82
+ Flag(flag_name='port',
83
+ flag_prefix='---',
84
+ possible_flag_values=re.compile(r'^[0-9]{1,4}$'))
85
+ ]
86
+
87
+
88
+ @router.command(Command("hello"))
89
+ def handler():
90
+ print("Hello, world!")
91
+
92
+
93
+ @router.command(Command(trigger="ssh",
94
+ description='connect via ssh',
95
+ flags=FlagsGroup(list_of_flags)))
96
+ def handler_with_flags(flags: dict):
97
+ for flag in flags:
98
+ print(f'Flag name: {flag['name']}\n
99
+ f'Flag value: {flag['value']}')
100
+ ```
101
+
102
+ ---
103
+
104
+ # *classes* :
105
+
106
+ ---
107
+
108
+ ## *class* :: `App`
109
+ Класс, определяющий поведение и состояние оболочки
110
+
111
+ ### Конструктор
112
+ ```python
113
+ App(prompt: str = 'Enter a command',
114
+ initial_greeting: str = '\nHello, I am Argenta\n',
115
+ farewell_message: str = '\nGoodBye\n',
116
+ exit_command: str = 'Q',
117
+ exit_command_description: str = 'Exit command',
118
+ system_points_title: str = 'System points:',
119
+ ignore_exit_command_register: bool = True,
120
+ ignore_command_register: bool = False,
121
+ line_separate: str = '',
122
+ command_group_description_separate: str = '',
123
+ repeat_command_groups: bool = True,
124
+ print_func: Callable[[str], None] = print)
125
+ ```
126
+ **Аргументы:**
127
+ - **name : mean**
128
+ - `prompt` (`str`): Сообщение перед вводом команды.
129
+ - `initial_greeting` (`str`): Приветственное сообщение при запуске.
130
+ - `farewell_message` (`str`): Сообщение при выходе.
131
+ - `exit_command` (`str`): Команда выхода (по умолчанию `'Q'`).
132
+ - `exit_command_description` (`str`): Описание команды выхода.
133
+ - `system_points_title` (`str`): Заголовок перед списком системных команд.
134
+ - `ignore_exit_command_register` (`bool`): Игнорировать регистр команды выхода.
135
+ - `ignore_command_register` (`bool`): Игнорировать регистр всех команд.
136
+ - `line_separate` (`str`): Разделительная строка между командами.
137
+ - `command_group_description_separate` (`str`): Разделитель между группами команд.
138
+ - `repeat_command_groups` (`bool`): Повторять описание команд перед вводом.
139
+ - `print_func` (`Callable[[str], None]`): Функция вывода текста в терминал (по умолчанию `print`).
140
+
141
+ ---
142
+
143
+ ### ***methods***
144
+
145
+ ---
146
+
147
+ **App().**`start_polling() -> None`
148
+
149
+ *method mean* **::** запускает жизненный цикл приложения
150
+
151
+ ---
152
+
153
+ **App().**`include_router(router: Router) -> None`
154
+
155
+ *param* `router: Router` **::** регистрируемый роутер
156
+
157
+ *method mean* **::** регистрирует роутер в приложении
158
+
159
+ ---
160
+
161
+ **App().**`set_initial_message(message: str) -> None`
162
+
163
+ *param* `message: str` **::** устанавливаемое приветственное сообщение
164
+ *example* **::** `"Hello, I'm a example app"`
165
+
166
+ *method mean* **::** устанавливает сообщение, которое будет отображено при запуске программы
167
+
168
+ ---
169
+
170
+ **App().**`set_farewell_message(message: str) -> None`
171
+
172
+ *param* `message: str` **::** устанавливаемое сообщение при выходе
173
+ *example* **::** `"GoodBye !"`
174
+
175
+ *method mean* **::** устанавливает сообщение, которое будет отображено при выходе
176
+
177
+ ---
178
+
179
+ **App().**`set_description_message_pattern(pattern: str) -> None`
180
+
181
+ *param* `pattern: str` **::** паттерн описания команды при её выводе в консоль
182
+ *example* **::** `"[{command}] *=*=* {description}"`
183
+
184
+ *method mean* **::** устанавливает паттерн описания команд, который будет использован
185
+ при выводе в консоль
186
+
187
+ ---
188
+
189
+ **App().**`set_repeated_input_flags_handler(handler: Callable[[str], None]) -> None`
190
+
191
+ *param* `handler: Callable[[str], None]` **::** функция или лямбда функция, которой будет передано управление при
192
+ вводе юзером повторяющихся флагов
193
+ *example* **::** `lambda raw_command: print_func(f'Repeated input flags: "{raw_command}"')`
194
+
195
+ *method mean* **::** устанавливает функцию, которой будет передано управление при
196
+ вводе юзером повторяющихся флагов
197
+
198
+ ---
199
+
200
+ **App().**`set_invalid_input_flags_handler(self, handler: Callable[[str], None]) -> None`
201
+
202
+ *param* `handler: Callable[[str], None]` **::** функция или лямбда функция, которой будет передано управление при
203
+ вводе юзером команды с некорректным синтаксисом флагов
204
+ *example* **::** `lambda raw_command: print_func(f'Incorrect flag syntax: "{raw_command}"')`
205
+
206
+ *method mean* **::** устанавливает функцию, которой будет передано управление при
207
+ вводе юзером команды с некорректным синтаксисом флагов
208
+
209
+ ---
210
+
211
+ **App().**`set_unknown_command_handler(self, handler: Callable[[str], None]) -> None`
212
+
213
+ *param* `handler: Callable[[str], None]` **::** функция или лямбда функция, которой будет передано управление при
214
+ вводе юзером неизвестной команды
215
+ *example* **::** `lambda command: print_func(f"Unknown command: {command.get_string_entity()}")`
216
+
217
+ *method mean* **::** устанавливает функцию, которой будет передано управление при
218
+ вводе юзером неизвестной команды
219
+
220
+ ---
221
+
222
+ **App().**`set_empty_command_handler(self, handler: Callable[[str], None]) -> None`
223
+
224
+ *param* `handler: Callable[[str], None]` **::** функция или лямбда функция, которой будет передано управление при
225
+ вводе юзером пустой команды
226
+ *example* **::** `lambda: print_func(f'Empty input command')`
227
+
228
+ *method mean* **::** устанавливает функцию, которой будет передано управление при
229
+ вводе юзером пустой команды
230
+
231
+ ---
232
+
233
+ ### Примечания
234
+
235
+ - В устанавливаемом паттерне сообщения описания команды необходимы быть два ключевых слова:
236
+ `command` и `description`, каждое из которых должно быть заключено в фигурные скобки, после обработки
237
+ паттерна на места этих ключевых слов будут подставлены соответствующие значения команды, при отсутствии
238
+ этих двух ключевых слов будет вызвано исключение `InvalidDescriptionMessagePatternException`
239
+
240
+ - Команды приложения не должны повторяться, при значении атрибута `ignore_command_register` равным `True`
241
+ допускается создание обработчиков для разных регистров одинаковых символов в команде, для примера `u` и `U`,
242
+ при значении атрибута `ignore_command_register` класса `App` равным `False` тот же пример вызывает исключение
243
+ `RepeatedCommandInDifferentRoutersException`. Исключение вызывается только при наличии пересекающихся команд
244
+ у __<u>разных</u>__ роутеров
245
+
246
+
247
+
248
+
249
+ ### Исключения
250
+
251
+ - `InvalidRouterInstanceException` — Переданный объект в метод `App().include_router()` не является экземпляром класса `Router`.
252
+ - `InvalidDescriptionMessagePatternException` — Неправильный формат паттерна описания команд.
253
+ - `IncorrectNumberOfHandlerArgsException` — У обработчика нестандартного поведения зарегистрировано неверное количество аргументов(в большинстве случаев у него должен быть один аргумент).
254
+ - `NoRegisteredRoutersException` — Отсутствуют зарегистрированные роутеры.
255
+ - `NoRegisteredHandlersException` — У роутера нет ни одного обработчика команд.
256
+ - `RepeatedCommandInDifferentRoutersException` — Одна и та же команда зарегистрирована в разных роутерах.
257
+
258
+ ---
259
+
260
+ ## *class* :: `Router`
261
+ Класс, который определяет и конфигурирует обработчики команд
262
+
263
+ ### Конструктор
264
+ ```python
265
+ Router(title: str = 'Commands group title:',
266
+ name: str = 'subordinate')
267
+ ```
268
+
269
+
270
+
271
+ **Аргументы:**
272
+ - **name : mean**
273
+ - `title` (`str`): Заголовок группы команд.
274
+ - `name` (`str`): Персональное название роутера
275
+
276
+ ---
277
+
278
+ ### ***methods***
279
+
280
+ ---
281
+
282
+ **`@`Router().**`command(command: Command)`
283
+
284
+ *param* `command: Command` **::** экземпляр класса `Command`, который определяет строковый триггер команды,
285
+ допустимые флаги команды и другое
286
+ *example* **::** `Command(command='ssh', description='connect via ssh')`
287
+
288
+ *method mean* **::** декоратор, который регистрирует функцию как обработчик команды
289
+
290
+ ---
291
+
292
+ **Router().**`get_name() -> str`
293
+
294
+ *method mean* **::** возвращает установленное название роутера
295
+
296
+ ---
297
+
298
+ **Router().**`get_title() -> str`
299
+
300
+ *method mean* **::** возвращает установленный заголовок группы команд данного роутера
301
+
302
+ ---
303
+
304
+ **Router().**`get_all_commands() -> list[str]`
305
+
306
+ *method mean* **::** возвращает все зарегистрированные команды для данного роутера
307
+
308
+ ---
309
+
310
+ ### Исключения
311
+ - `RepeatedCommandException` - Одна и та же команда зарегистрирована в одном роутере
312
+ - `RepeatedFlagNameException` - Повторяющиеся зарегистрированные флаги в команде
313
+ - `TooManyTransferredArgsException` - Слишком много зарегистрированных аргументов у обработчика команды
314
+ - `RequiredArgumentNotPassedException` - Не зарегистрирован обязательный аргумент у обработчика команды(аргумент, через который будут переданы флаги введённой команды)
315
+ - `IncorrectNumberOfHandlerArgsException` - У обработчика нестандартного поведения зарегистрировано неверное количество аргументов(в большинстве случаев у него должен быть один аргумент)
316
+
317
+ ---
318
+
319
+ ## *class* :: `Command`
320
+ Класс, экземпляр которого определяет строковый триггер хэндлера и конфигурирует его атрибуты
321
+
322
+ ### Конструктор
323
+ ```python
324
+ Command(trigger: str,
325
+ description: str = None,
326
+ flags: Flag | FlagsGroup = None)
327
+ ```
328
+
329
+ **Аргументы:**
330
+ - **name : mean**
331
+ - `trigger` (`str`): Строковый триггер
332
+ - `description` (`str`): Описание команды, которое будет выведено в консоль при запуске оболочки
333
+ - `flags` (`Flag | FlagsGroup`): Флаги, которые будут обработаны при их наличии во вводе юзера
334
+
335
+ ---
336
+
337
+ **Command().**`get_trigger() -> str`
338
+
339
+ *method mean* **::** возвращает строковый триггер экземпляра
340
+
341
+ ---
342
+
343
+ **Command().**`get_description() -> str`
344
+
345
+ *method mean* **::** возвращает описание команды
346
+
347
+ ---
348
+
349
+ **Command().**`get_registered_flags() -> FlagsGroup | None`
350
+
351
+ *method mean* **::** возвращает зарегистрированные флаги экземпляра
352
+
353
+ ---
354
+
355
+ ### Исключения
356
+ - `UnprocessedInputFlagException` - Некорректный синтаксис ввода команды
357
+ - `RepeatedInputFlagsException` - Повторяющиеся флаги во введённой команде
358
+ - `EmptyInputCommandException` - Введённая команда является пустой(не содержит символов)
359
+
360
+ **Примечание**
361
+ Все вышеуказанные исключения класса `Command` вызываются в рантайме запущенным экземпляром класса
362
+ `App`, а также по дефолту обрабатываются, при желании можно задать пользовательские
363
+ обработчики для этих исключений ([подробнее см.](#methods-))
364
+
365
+ ---
366
+
367
+ ## *class* :: `Flag`
368
+ Класс, экземпляры которого в большинстве случаев должны передаваться при создании
369
+ экземпляра класса `Command` для регистрации допустимого флага при вводе юзером команды
370
+
371
+ ### Конструктор
372
+ ```python
373
+ Flag(flag_name: str,
374
+ flag_prefix: Literal['-', '--', '---'] = '-',
375
+ ignore_flag_value_register: bool = False,
376
+ possible_flag_values: list[str] | Pattern[str] = False)
377
+ ```
378
+
379
+ ---
380
+
381
+ **Аргументы:**
382
+ - **name : mean**
383
+ - `flag_name` (`str`): Имя флага
384
+ - `flag_prefix` (`Literal['-', '--', '---']`): Префикс команды, допустимым значением является от одного до трёх минусов
385
+ - `ignore_flag_value_register` (`bool`): Будет ли игнорироваться регистр значения введённого флага
386
+ - `possible_flag_values` (`list[str] | Pattern[str]`): Множество допустимых значений флага, может быть задано
387
+ списком с допустимыми значениями или регулярным выражением (рекомендуется `re.compile(r'example exspression')`)
388
+
389
+ ---
390
+
391
+ ### ***methods***
392
+
393
+ ---
394
+
395
+ **Flag().**`get_sring_entity() -> str`
396
+
397
+ *method mean* **::** возвращает строковое представление флага(префикс + имя)
398
+
399
+ ---
400
+
401
+ **Flag().**`get_flag_name() -> str`
402
+
403
+ *method mean* **::** возвращает имя флага
404
+
405
+ ---
406
+
407
+ **Flag().**`get_flag_prefix() -> str`
408
+
409
+ *method mean* **::** возвращает префикс флага
410
+
411
+ ---
412
+
413
+ ## *class* :: `FlagsGroup`
414
+ Класс, объединяющий список флагов в один объект, используется в качестве
415
+ передаваемого аргумента `flags` экземпляру класса `Command`, при регистрации
416
+ хэндлера
417
+
418
+ ### Конструктор
419
+ ```python
420
+ FlagsGroup(flags: list[Flag] = None)
421
+ ```
422
+
423
+ ---
424
+
425
+ **Аргументы:**
426
+ - **name : mean**
427
+ - `flags` (`list[Flag]`): Список флагов, которые будут объединены в одну группу
428
+
429
+ ---
430
+
431
+ ### ***methods***
432
+
433
+ ---
434
+
435
+ **FlagsGroup().**`get_flags() -> list[Flag]`
436
+
437
+ *method mean* **::** возвращает зарегистрированные флаги
438
+
439
+ ---
440
+
441
+ # Тесты
442
+
443
+ Запуск тестов:
444
+
445
+ ```bash
446
+ python -m unittest discover
447
+ ```
448
+ or
449
+ ```bash
450
+ python -m unittest discover -v
451
+ ```
452
+
@@ -0,0 +1,19 @@
1
+ argenta/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
+ argenta/app/__init__.py,sha256=NoKJpO5inI4bEtptNj7BZtNpGQidCNoFSw2-JoK6P98,25
3
+ argenta/app/entity.py,sha256=f1UV8g92ZhyXeeTHvZYKNqPw0xCRUljYgXDg1qsaZa4,11508
4
+ argenta/app/exceptions.py,sha256=ruI_MwJQtBLrnWxJbKlSRE50c5FjnZ9qXJma34kPZhk,1253
5
+ argenta/command/__init__.py,sha256=yRSj5CtLjxwjKiokUGdSmuBZPOF_qheRyG0NW1pv7vo,27
6
+ argenta/command/entity.py,sha256=tssojZMXUdI7o5LKxf9a07LT1VOyMk2gwL_zCj2Bljg,4230
7
+ argenta/command/exceptions.py,sha256=ZCDnAmEvJRoOMpX02778YEQg3QCtDczRzu_fdkqKxus,547
8
+ argenta/command/params/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
9
+ argenta/command/params/flag/__init__.py,sha256=y6rJLdag5qxONg1CzcP7gi6rCeix9UsG1AVANX3fnJs,68
10
+ argenta/command/params/flag/entity.py,sha256=wqCLVCDUqvuPVQQyz2mOeslH6Xha0nwiKUqD1CCBpns,1737
11
+ argenta/command/params/flag/flags_group/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
12
+ argenta/command/params/flag/flags_group/entity.py,sha256=qcVbRkfWblR53a1N0C8tpZ8UOH5aNlQmkyxRfCrrwMo,1011
13
+ argenta/router/__init__.py,sha256=vIU2o3JJ7misRm9mUzUQw5HdverdMDfvHNzkWuYFRBY,26
14
+ argenta/router/entity.py,sha256=P-1rmXgzuo548uGUKzsVrQBvgDGTXlEBtokx-eEbJY8,4936
15
+ argenta/router/exceptions.py,sha256=dW3FIdHA_tZYt1-IEts7IY46KLBaKulfdW_ALKpvAic,657
16
+ argenta-0.3.6.dist-info/LICENSE,sha256=zmqoGh2n5rReBv4s8wPxF_gZEZDgauJYSPMuPczgOiU,1082
17
+ argenta-0.3.6.dist-info/METADATA,sha256=ZkHeDKFXdUqwoChdAdNv2UEwx6SQyhvkZT5HBz91WEo,17805
18
+ argenta-0.3.6.dist-info/WHEEL,sha256=IYZQI976HJqqOpQU6PHkJ8fb3tMNBFjg-Cn-pwAbaFM,88
19
+ argenta-0.3.6.dist-info/RECORD,,
@@ -1,289 +0,0 @@
1
- Metadata-Version: 2.3
2
- Name: argenta
3
- Version: 0.3.5
4
- Summary: python library for creating custom shells
5
- License: MIT
6
- Author: kolo
7
- Author-email: kolo.is.main@gmail.com
8
- Requires-Python: >=3.11
9
- Classifier: License :: OSI Approved :: MIT License
10
- Classifier: Programming Language :: Python :: 3
11
- Classifier: Programming Language :: Python :: 3.11
12
- Classifier: Programming Language :: Python :: 3.12
13
- Classifier: Programming Language :: Python :: 3.13
14
- Description-Content-Type: text/markdown
15
-
16
- # Argenta
17
-
18
- ---
19
-
20
- ## Описание
21
- **Argenta** — это библиотека для создания CLI-приложений на Python. Она предоставляет удобные инструменты для маршрутизации команд и обработки пользовательского ввода.
22
-
23
- ---
24
-
25
- # Установка
26
- ```bash
27
- pip install argenta
28
- ```
29
- or
30
- ```bash
31
- poetry add argenta
32
- ```
33
-
34
- ---
35
-
36
- # Быстрый старт
37
- Пример базового CLI-приложения с Argenta:
38
- ```python
39
- #routers.py
40
- from argenta.router import Router
41
-
42
- router = Router()
43
-
44
- @router.command("hello")
45
- def hello():
46
- print("Hello, world!")
47
-
48
- @router.unknown_command
49
- def unlnown_command(command):
50
- print(f'Command "{command}" undefined')
51
- ```
52
- ```python
53
- #main.py
54
- from argenta.app import App
55
- from routers import router
56
-
57
- app: App = App()
58
-
59
- def main() -> None:
60
- app.include_router(router)
61
- app.start_polling()
62
-
63
-
64
- if __name__ == '__main__':
65
- main()
66
- ```
67
-
68
- ---
69
-
70
- # Техническая документация
71
-
72
- ---
73
-
74
- ## declared *classes* :
75
-
76
- ---
77
-
78
- ### *class* :: `App`
79
- Класс, определяющий поведение и состояние приложения
80
-
81
- #### Конструктор
82
- ```python
83
- App(prompt: str = 'Enter a command',
84
- initial_greeting: str = '\nHello, I am Argenta\n',
85
- farewell_message: str = '\nGoodBye\n',
86
- exit_command: str = 'Q',
87
- exit_command_description: str = 'Exit command',
88
- exit_command_title: str = 'System points:',
89
- ignore_exit_command_register: bool = True,
90
- ignore_command_register: bool = False,
91
- line_separate: str = '',
92
- command_group_description_separate: str = '',
93
- repeat_command_groups: bool = True,
94
- print_func: Callable[[str], None] = print)
95
- ```
96
- **Аргументы:**
97
- - **name : mean**
98
- - `prompt` (`str`): Сообщение перед вводом команды.
99
- - `initial_greeting` (`str`): Приветственное сообщение при запуске.
100
- - `farewell_message` (`str`): Сообщение при выходе.
101
- - `exit_command` (`str`): Команда выхода (по умолчанию `'Q'`).
102
- - `exit_command_description` (`str`): Описание команды выхода.
103
- - `exit_command_title` (`str`): Заголовок перед списком команд выхода.
104
- - `ignore_exit_command_register` (`bool`): Игнорировать регистр команды выхода.
105
- - `ignore_command_register` (`bool`): Игнорировать регистр всех команд.
106
- - `line_separate` (`str`): Разделительная строка между командами.
107
- - `command_group_description_separate` (`str`): Разделитель между группами команд.
108
- - `repeat_command_groups` (`bool`): Повторять описание команд перед вводом.
109
- - `print_func` (`Callable[[str], None]`): Функция вывода текста в терминал (по умолчанию `print`).
110
-
111
- ---
112
-
113
- #### **declared *methods***
114
-
115
- ---
116
-
117
- **App().**`start_polling() -> None`
118
-
119
- *method mean* **::** запускает жизненный цикл приложения
120
-
121
- ---
122
-
123
- **App().**`include_router(router: Router, is_main: bool = False) -> None`
124
-
125
- *param* `router: Router` **::** регистрируемый роутер
126
-
127
- *param* `is_main: bool` **::** будет ли являться регистрируемый роутер главным
128
- *example* **::** `True` или `False`
129
-
130
- *method mean* **::** регистрирует роутер в приложении
131
-
132
- ---
133
-
134
- **App().**`set_initial_message(message: str) -> None`
135
-
136
- *param* `message: str` **::** устанавливаемое приветственное сообщение
137
- *example* **::** `"Hello, I'm a cli example app"`
138
-
139
- *method mean* **::** устанавливает сообщение, которое будет отображено при запуске программы
140
-
141
- ---
142
-
143
- **App().**`set_farewell_message(message: str) -> None`
144
-
145
- *param* `message: str` **::** устанавливаемое сообщение при выходе
146
- *example* **::** `"GoodBye !"`
147
-
148
- *method mean* **::** устанавливает сообщение, которое будет отображено при выходе
149
-
150
- ---
151
-
152
- **App().**`set_description_message_pattern(pattern: str) -> None`
153
-
154
- *param* `pattern: str` **::** паттерн описания команды при её выводе в консоль
155
- *example* **::** `"[{command}] *=*=* {description}"`
156
-
157
- *method mean* **::** устанавливает приветственное сообщение
158
-
159
- ---
160
-
161
- **App().**`get_main_router() -> Router`
162
-
163
- *method mean* **::** возвращает `Router()`, который является главным в приложении
164
-
165
- ---
166
-
167
- **App().**`get_all_app_commands() -> list[str]`
168
-
169
- *method mean* **::** возвращает список команд всех зарегистрированных роутеров, сохраняя их регистр
170
-
171
- ---
172
-
173
- #### Примечания
174
-
175
- - Среди зарегистрированных в приложении роутеров должен быть один главный, является ли роутер главным
176
- определяется значением аргумента `is_main` равным `True`, в методе `App().include_router()`, который по умолчанию равен
177
- `False`, если в приложении зарегистрирован лишь один роутер, то он неявно устанавливается главным, если
178
- зарегистрировано больше одного роутера, то требуется явное указание главного. При регистрации более одного
179
- главного роутера вызывается исключение `OnlyOneMainRouterIsAllowedException`. При регистрации более одного
180
- роутера и отсутствии указания главного вызывается исключение `MissingMainRouterException`
181
-
182
- - В устанавливаемом паттерне сообщения описания команды необходимы быть два ключевых слова:
183
- `command` и `description`, каждое из которых должно быть заключено в фигурные скобки, после обработки
184
- паттерна на места этих ключевых слов будут подставлены соответствующие значения команды, при отсутствии
185
- этих двух ключевых слов будет вызвано исключение `InvalidDescriptionMessagePatternException`
186
-
187
- - Команды приложения не должны повторяться, при значении атрибута `ignore_command_register` равным `True`
188
- допускается создание обработчиков для разных регистров одинаковых символов в команде, для примера `u` и `U`,
189
- при значении атрибута `ignore_command_register` класса `App` равным `False` тот же пример вызывает исключение
190
- `RepeatedCommandInDifferentRoutersException`. Исключение вызывается только при наличии пересекающихся команд
191
- у __<u>разных</u>__ роутеров
192
-
193
- - У главного обработчика должен быть зарегистрирован обработчик неизвестных команд:
194
- ```python
195
- router = Router()
196
-
197
- @router.unknown_command
198
- def unknown_command(command):
199
- print(f'Command "{command}" undefined')
200
- ```
201
- При отсутствии обработчика неизвестных команд у главного роутера будет вызвано исключение
202
- `MissingHandlerForUnknownCommandsException`. При регистрации обработчика неизвестных команд у
203
- __<u>не</u>__ главного роутера будет вызвано исключение `HandlerForUnknownCommandsOnNonMainRouterException`
204
-
205
-
206
-
207
-
208
- #### Исключения
209
-
210
- - `InvalidRouterInstanceException` — Переданный объект в метод `App().include_router()` не является экземпляром класса `Router`.
211
- - `InvalidDescriptionMessagePatternException` — Неправильный формат паттерна описания команд.
212
- - `OnlyOneMainRouterIsAllowedException` — Регистрация более одного главного роутера.
213
- - `MissingMainRouterException` — Отсутствует главный роутер.
214
- - `MissingHandlerForUnknownCommandsException` — В основном роутере отсутствует обработчик неизвестных команд.
215
- - `HandlerForUnknownCommandsOnNonMainRouterException` — Обработчик неизвестных команд определён не у основного роутера.
216
- - `NoRegisteredRoutersException` — Отсутствуют зарегистрированные роутеры.
217
- - `NoRegisteredHandlersException` — У роутера нет ни одного обработчика команд.
218
- - `RepeatedCommandInDifferentRoutersException` — Одна и та же команда зарегистрирована в разных роутерах.
219
-
220
- ---
221
-
222
- ### *class* :: `Router`
223
- Класс, который определяет и конфигурирует обработчики команд
224
-
225
- #### Конструктор
226
- ```python
227
- Router(title: str = 'Commands group title:',
228
- name: str = 'subordinate')
229
- ```
230
-
231
- **Аргументы:**
232
- - **name : mean**
233
- - `title` (`str`): Заголовок группы команд.
234
- - `name` (`str`): Персональное название роутера
235
-
236
-
237
-
238
- #### **declared *methods***
239
-
240
- ---
241
-
242
- **`@`Router().**`command(command: str, description: str = None)`
243
-
244
- *param* `command: str` **::** строковый триггер, который будет выполнять указанные действия
245
- *example* **::** `U` / `update` / `ExaMPLE`
246
-
247
- *param* `description: str` **::** описание команды, которое будет выведено в консоль
248
- *example* **::** `description for update command` или `example description`
249
-
250
- *method mean* **::** декоратор регистрирует функцию как обработчик команды
251
-
252
- ---
253
-
254
- **`@`Router().**`unknown_command`
255
-
256
- *method mean* **::** декоратор регистрирует функцию как обработчик неизвестных команд
257
-
258
- ---
259
-
260
- **Router().**`get_name() -> str`
261
-
262
- *method mean* **::** возвращает установленное название роутера
263
-
264
- ---
265
-
266
- **Router().**`get_title() -> str`
267
-
268
- *method mean* **::** возвращает установленный заголовок группы команд данного роутера
269
-
270
- ---
271
-
272
- **Router().**`get_router_info() -> dict`
273
-
274
- *method mean* **::** возвращает информацию о роутере
275
-
276
- ---
277
-
278
- **Router().**`get_all_commands() -> list[str]`
279
-
280
- *method mean* **::** возвращает все зарегистрированные команды для данного роутера
281
-
282
- ---
283
-
284
- #### Исключения
285
- - `InvalidCommandInstanceException` - Переданный объект для регистрации команды не является строкой
286
- - `InvalidDescriptionInstanceException` - Переданный объект для регистрации описания команды не является строкой
287
- - `UnknownCommandHandlerHasAlreadyBeenCreatedException` - Обработчик неизвестных команд уже создан
288
- - `RepeatedCommandException` - Одна и та же команда зарегистрирована в одном роутере
289
-
@@ -1,19 +0,0 @@
1
- argenta/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
- argenta/app/__init__.py,sha256=yOt8-2lholVRUtLPwAXuemh115q1unP1PKLBR_7cd4E,152
3
- argenta/app/entity.py,sha256=Vrg7C1EifCJK-96jlLOQ0Jd3EBgGhsotNrYimEkg72k,11250
4
- argenta/app/exceptions.py,sha256=ruI_MwJQtBLrnWxJbKlSRE50c5FjnZ9qXJma34kPZhk,1253
5
- argenta/command/__init__.py,sha256=yRSj5CtLjxwjKiokUGdSmuBZPOF_qheRyG0NW1pv7vo,27
6
- argenta/command/entity.py,sha256=nphBNvvXbl_4m6csWttXhU2DmNNCwjGCsGcBDV0u05s,4801
7
- argenta/command/exceptions.py,sha256=jo-jtGHtvwsblElioo5AVHrAmmYBa2xldPHwRKFeFiI,917
8
- argenta/command/params/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
9
- argenta/command/params/flag/__init__.py,sha256=y6rJLdag5qxONg1CzcP7gi6rCeix9UsG1AVANX3fnJs,68
10
- argenta/command/params/flag/entity.py,sha256=cBGUiA9h9ytcQDGp5HVMM4EOcx7jveYmhY6V_1CsOO4,1721
11
- argenta/command/params/flag/flags_group/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
12
- argenta/command/params/flag/flags_group/entity.py,sha256=vicuhXVyf9szr7mt1jokfjBCnaCac_HE8GUM_PJqMMM,591
13
- argenta/router/__init__.py,sha256=ZedowNgGR9OphLSg9fXp6-uvjyf23rbq-rEtuHScAIM,87
14
- argenta/router/entity.py,sha256=QcAwmwah1Noe5Zkf_gJoXiJ5YJeEwuUfRhyjOvCZlgg,4962
15
- argenta/router/exceptions.py,sha256=l9rD_ySeWLYBDPv7R8XYMBWpAE2QOKjYAcZPcTjfUMI,981
16
- argenta-0.3.5.dist-info/LICENSE,sha256=zmqoGh2n5rReBv4s8wPxF_gZEZDgauJYSPMuPczgOiU,1082
17
- argenta-0.3.5.dist-info/METADATA,sha256=jBTRzYbdrYYQJ1I5rENFgyAC7CDTUHalj5QqN56_XX4,12638
18
- argenta-0.3.5.dist-info/WHEEL,sha256=IYZQI976HJqqOpQU6PHkJ8fb3tMNBFjg-Cn-pwAbaFM,88
19
- argenta-0.3.5.dist-info/RECORD,,