argenta 1.0.5__py3-none-any.whl → 1.0.7__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/autocompleter/entity.py +1 -1
- argenta/app/defaults.py +1 -0
- argenta/app/models.py +107 -95
- argenta/app/registered_routers/entity.py +1 -1
- argenta/command/flag/__init__.py +15 -5
- argenta/command/flag/defaults.py +8 -7
- argenta/command/flag/models.py +16 -3
- argenta/command/models.py +8 -10
- argenta/metrics/main.py +5 -13
- argenta/orchestrator/entity.py +2 -2
- argenta/response/entity.py +1 -1
- argenta/router/command_handler/entity.py +1 -1
- argenta/router/entity.py +35 -31
- {argenta-1.0.5.dist-info → argenta-1.0.7.dist-info}/METADATA +1 -2
- {argenta-1.0.5.dist-info → argenta-1.0.7.dist-info}/RECORD +17 -17
- {argenta-1.0.5.dist-info → argenta-1.0.7.dist-info}/WHEEL +0 -0
- {argenta-1.0.5.dist-info → argenta-1.0.7.dist-info}/licenses/LICENSE +0 -0
@@ -5,7 +5,7 @@ from typing import Never
|
|
5
5
|
|
6
6
|
class AutoCompleter:
|
7
7
|
def __init__(
|
8
|
-
self, history_filename: str =
|
8
|
+
self, history_filename: str | None = None, autocomplete_button: str = "tab"
|
9
9
|
) -> None:
|
10
10
|
"""
|
11
11
|
Public. Configures and implements auto-completion of input command
|
argenta/app/defaults.py
CHANGED
@@ -5,6 +5,7 @@ class PredefinedMessages(StrEnum):
|
|
5
5
|
"""
|
6
6
|
Public. A dataclass with predetermined messages for quick use
|
7
7
|
"""
|
8
|
+
|
8
9
|
USAGE = "[b dim]Usage[/b dim]: [i]<command> <[green]flags[/green]>[/i]"
|
9
10
|
HELP = "[b dim]Help[/b dim]: [i]<command>[/i] [b red]--help[/b red]"
|
10
11
|
AUTOCOMPLETE = "[b dim]Autocomplete[/b dim]: [i]<part>[/i] [bold]<tab>"
|
argenta/app/models.py
CHANGED
@@ -21,9 +21,9 @@ from argenta.app.registered_routers.entity import RegisteredRouters
|
|
21
21
|
from argenta.response import Response
|
22
22
|
|
23
23
|
|
24
|
+
|
24
25
|
class BaseApp:
|
25
|
-
def __init__(self,
|
26
|
-
prompt: str,
|
26
|
+
def __init__(self, prompt: str,
|
27
27
|
initial_message: str,
|
28
28
|
farewell_message: str,
|
29
29
|
exit_command: Command,
|
@@ -47,18 +47,33 @@ class BaseApp:
|
|
47
47
|
self._farewell_message = farewell_message
|
48
48
|
self._initial_message = initial_message
|
49
49
|
|
50
|
-
self._description_message_gen: Callable[[str, str], str] =
|
50
|
+
self._description_message_gen: Callable[[str, str], str] = lambda command, description: f"{command} *=*=* {description}"
|
51
51
|
self._registered_routers: RegisteredRouters = RegisteredRouters()
|
52
52
|
self._messages_on_startup: list[str] = []
|
53
53
|
|
54
|
-
self.
|
55
|
-
self.
|
54
|
+
self._matching_lower_triggers_with_routers: dict[str, Router] = {}
|
55
|
+
self._matching_default_triggers_with_routers: dict[str, Router] = {}
|
56
|
+
|
57
|
+
if self._ignore_command_register:
|
58
|
+
self._current_matching_triggers_with_routers: dict[str, Router] = self._matching_lower_triggers_with_routers
|
59
|
+
else:
|
60
|
+
self._current_matching_triggers_with_routers: dict[str, Router] = self._matching_default_triggers_with_routers
|
56
61
|
|
57
|
-
self._incorrect_input_syntax_handler: Callable[[str], None] = (
|
58
|
-
|
59
|
-
|
60
|
-
self.
|
61
|
-
|
62
|
+
self._incorrect_input_syntax_handler: Callable[[str], None] = (
|
63
|
+
lambda raw_command: print_func(f"Incorrect flag syntax: {raw_command}")
|
64
|
+
)
|
65
|
+
self._repeated_input_flags_handler: Callable[[str], None] = (
|
66
|
+
lambda raw_command: print_func(f"Repeated input flags: {raw_command}")
|
67
|
+
)
|
68
|
+
self._empty_input_command_handler: Callable[[], None] = lambda: print_func(
|
69
|
+
"Empty input command"
|
70
|
+
)
|
71
|
+
self._unknown_command_handler: Callable[[InputCommand], None] = (
|
72
|
+
lambda command: print_func(f"Unknown command: {command.get_trigger()}")
|
73
|
+
)
|
74
|
+
self._exit_command_handler: Callable[[Response], None] = (
|
75
|
+
lambda response: print_func(self._farewell_message)
|
76
|
+
)
|
62
77
|
|
63
78
|
def set_description_message_pattern(self, _: Callable[[str, str], str]) -> None:
|
64
79
|
"""
|
@@ -194,27 +209,28 @@ class BaseApp:
|
|
194
209
|
"""
|
195
210
|
input_command_trigger = command.get_trigger()
|
196
211
|
if self._ignore_command_register:
|
197
|
-
if input_command_trigger.lower() in self.
|
212
|
+
if input_command_trigger.lower() in list(self._current_matching_triggers_with_routers.keys()):
|
198
213
|
return False
|
199
214
|
else:
|
200
|
-
if input_command_trigger in self.
|
215
|
+
if input_command_trigger in list(self._current_matching_triggers_with_routers.keys()):
|
201
216
|
return False
|
202
217
|
return True
|
203
218
|
|
204
|
-
def _error_handler(
|
219
|
+
def _error_handler(
|
220
|
+
self, error: BaseInputCommandException, raw_command: str
|
221
|
+
) -> None:
|
205
222
|
"""
|
206
223
|
Private. Handles parsing errors of the entered command
|
207
224
|
:param error: error being handled
|
208
225
|
:param raw_command: the raw input command
|
209
226
|
:return: None
|
210
227
|
"""
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
self._empty_input_command_handler()
|
228
|
+
if isinstance(error, UnprocessedInputFlagException):
|
229
|
+
self._incorrect_input_syntax_handler(raw_command)
|
230
|
+
elif isinstance(error, RepeatedInputFlagsException):
|
231
|
+
self._repeated_input_flags_handler(raw_command)
|
232
|
+
elif isinstance(error, EmptyInputCommandException):
|
233
|
+
self._empty_input_command_handler()
|
218
234
|
|
219
235
|
def _setup_system_router(self) -> None:
|
220
236
|
"""
|
@@ -232,11 +248,8 @@ class BaseApp:
|
|
232
248
|
self._registered_routers.add_registered_router(system_router)
|
233
249
|
|
234
250
|
def _most_similar_command(self, unknown_command: str) -> str | None:
|
235
|
-
all_commands = (
|
236
|
-
|
237
|
-
if self._ignore_command_register
|
238
|
-
else self._all_registered_triggers_in_default_case
|
239
|
-
)
|
251
|
+
all_commands = list(self._current_matching_triggers_with_routers.keys())
|
252
|
+
|
240
253
|
matches: list[str] | list = sorted(
|
241
254
|
cmd for cmd in all_commands if cmd.startswith(unknown_command)
|
242
255
|
)
|
@@ -256,35 +269,27 @@ class BaseApp:
|
|
256
269
|
Private. Sets up default app view
|
257
270
|
:return: None
|
258
271
|
"""
|
259
|
-
self._prompt = "[italic dim bold]
|
260
|
-
self._initial_message = (
|
261
|
-
f"\n[bold red]{text2art(self._initial_message, font='tarty1')}\n"
|
262
|
-
)
|
272
|
+
self._prompt = f"[italic dim bold]{self._prompt}"
|
273
|
+
self._initial_message = ("\n" + f"[bold red]{text2art(self._initial_message, font='tarty1')}" + "\n")
|
263
274
|
self._farewell_message = (
|
264
|
-
|
265
|
-
|
275
|
+
"[bold red]\n\n"
|
276
|
+
+ text2art(self._farewell_message, font="chanky")
|
277
|
+
+ "\n[/bold red]\n"
|
278
|
+
"[red i]github.com/koloideal/Argenta[/red i] | [red bold i]made by kolo[/red bold i]\n"
|
266
279
|
)
|
267
280
|
self._description_message_gen = lambda command, description: (
|
268
281
|
f"[bold red]{escape('[' + command + ']')}[/bold red] "
|
269
282
|
f"[blue dim]*=*=*[/blue dim] "
|
270
283
|
f"[bold yellow italic]{escape(description)}"
|
271
284
|
)
|
272
|
-
self._incorrect_input_syntax_handler = lambda raw_command: self._print_func(
|
273
|
-
|
274
|
-
)
|
275
|
-
self._repeated_input_flags_handler = lambda raw_command: self._print_func(
|
276
|
-
f"[red bold]Repeated input flags: {escape(raw_command)}"
|
277
|
-
)
|
278
|
-
self._empty_input_command_handler = lambda: self._print_func(
|
279
|
-
"[red bold]Empty input command"
|
280
|
-
)
|
285
|
+
self._incorrect_input_syntax_handler = lambda raw_command: self._print_func(f"[red bold]Incorrect flag syntax: {escape(raw_command)}")
|
286
|
+
self._repeated_input_flags_handler = lambda raw_command: self._print_func(f"[red bold]Repeated input flags: {escape(raw_command)}")
|
287
|
+
self._empty_input_command_handler = lambda: self._print_func("[red bold]Empty input command")
|
281
288
|
|
282
289
|
def unknown_command_handler(command: InputCommand) -> None:
|
283
290
|
cmd_trg: str = command.get_trigger()
|
284
291
|
mst_sim_cmd: str | None = self._most_similar_command(cmd_trg)
|
285
|
-
first_part_of_text = (
|
286
|
-
f"[red]Unknown command:[/red] [blue]{escape(cmd_trg)}[/blue]"
|
287
|
-
)
|
292
|
+
first_part_of_text = f"[red]Unknown command:[/red] [blue]{escape(cmd_trg)}[/blue]"
|
288
293
|
second_part_of_text = (
|
289
294
|
("[red], most similar:[/red] " + ("[blue]" + mst_sim_cmd + "[/blue]"))
|
290
295
|
if mst_sim_cmd
|
@@ -302,22 +307,22 @@ class BaseApp:
|
|
302
307
|
self._setup_system_router()
|
303
308
|
|
304
309
|
for router_entity in self._registered_routers:
|
305
|
-
|
306
|
-
|
310
|
+
router_triggers = router_entity.get_triggers()
|
311
|
+
router_aliases = router_entity.get_aliases()
|
312
|
+
combined = router_triggers + router_aliases
|
307
313
|
|
308
|
-
|
309
|
-
|
314
|
+
for trigger in combined:
|
315
|
+
self._matching_default_triggers_with_routers[trigger] = router_entity
|
316
|
+
self._matching_lower_triggers_with_routers[trigger.lower()] = router_entity
|
310
317
|
|
311
|
-
self._autocompleter.initial_setup(self.
|
318
|
+
self._autocompleter.initial_setup(list(self._current_matching_triggers_with_routers.keys()))
|
312
319
|
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
if self._all_registered_triggers_in_default_case.count(cmd) != 1:
|
320
|
-
Console().print(f"\n[b red]WARNING:[/b red] Overlapping trigger or alias: [b blue]{cmd}[/b blue]")
|
320
|
+
seen = {}
|
321
|
+
for item in list(self._current_matching_triggers_with_routers.keys()):
|
322
|
+
if item in seen:
|
323
|
+
Console().print(f"\n[b red]WARNING:[/b red] Overlapping trigger or alias: [b blue]{item}[/b blue]")
|
324
|
+
else:
|
325
|
+
seen[item] = True
|
321
326
|
|
322
327
|
if not self._override_system_messages:
|
323
328
|
self._setup_default_view()
|
@@ -333,18 +338,20 @@ class BaseApp:
|
|
333
338
|
|
334
339
|
|
335
340
|
class App(BaseApp):
|
336
|
-
def __init__(
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
341
|
+
def __init__(
|
342
|
+
self,
|
343
|
+
prompt: str = "What do you want to do?\n",
|
344
|
+
initial_message: str = "Argenta\n",
|
345
|
+
farewell_message: str = "\nSee you\n",
|
346
|
+
exit_command: Command = Command("Q", "Exit command"),
|
347
|
+
system_router_title: str | None = "System points:",
|
348
|
+
ignore_command_register: bool = True,
|
349
|
+
dividing_line: StaticDividingLine | DynamicDividingLine = StaticDividingLine(),
|
350
|
+
repeat_command_groups: bool = True,
|
351
|
+
override_system_messages: bool = False,
|
352
|
+
autocompleter: AutoCompleter = AutoCompleter(),
|
353
|
+
print_func: Callable[[str], None] = Console().print,
|
354
|
+
) -> None:
|
348
355
|
"""
|
349
356
|
Public. The essence of the application itself.
|
350
357
|
Configures and manages all aspects of the behavior and presentation of the user interacting with the user
|
@@ -361,17 +368,19 @@ class App(BaseApp):
|
|
361
368
|
:param print_func: system messages text output function
|
362
369
|
:return: None
|
363
370
|
"""
|
364
|
-
super().__init__(
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
371
|
+
super().__init__(
|
372
|
+
prompt=prompt,
|
373
|
+
initial_message=initial_message,
|
374
|
+
farewell_message=farewell_message,
|
375
|
+
exit_command=exit_command,
|
376
|
+
system_router_title=system_router_title,
|
377
|
+
ignore_command_register=ignore_command_register,
|
378
|
+
dividing_line=dividing_line,
|
379
|
+
repeat_command_groups=repeat_command_groups,
|
380
|
+
override_system_messages=override_system_messages,
|
381
|
+
autocompleter=autocompleter,
|
382
|
+
print_func=print_func,
|
383
|
+
)
|
375
384
|
|
376
385
|
def run_polling(self) -> None:
|
377
386
|
"""
|
@@ -386,9 +395,7 @@ class App(BaseApp):
|
|
386
395
|
raw_command: str = Console().input(self._prompt)
|
387
396
|
|
388
397
|
try:
|
389
|
-
input_command: InputCommand = InputCommand.parse(
|
390
|
-
raw_command=raw_command
|
391
|
-
)
|
398
|
+
input_command: InputCommand = InputCommand.parse(raw_command=raw_command)
|
392
399
|
except BaseInputCommandException as error:
|
393
400
|
with redirect_stdout(io.StringIO()) as f:
|
394
401
|
self._error_handler(error, raw_command)
|
@@ -398,14 +405,7 @@ class App(BaseApp):
|
|
398
405
|
|
399
406
|
if self._is_exit_command(input_command):
|
400
407
|
system_router.finds_appropriate_handler(input_command)
|
401
|
-
|
402
|
-
self._autocompleter.exit_setup(
|
403
|
-
self._all_registered_triggers_in_lower_case
|
404
|
-
)
|
405
|
-
else:
|
406
|
-
self._autocompleter.exit_setup(
|
407
|
-
self._all_registered_triggers_in_default_case
|
408
|
-
)
|
408
|
+
self._autocompleter.exit_setup(list(self._current_matching_triggers_with_routers.keys()))
|
409
409
|
return
|
410
410
|
|
411
411
|
if self._is_unknown_command(input_command):
|
@@ -415,11 +415,23 @@ class App(BaseApp):
|
|
415
415
|
self._print_framed_text(res)
|
416
416
|
continue
|
417
417
|
|
418
|
-
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
|
418
|
+
processing_router = self._current_matching_triggers_with_routers[input_command.get_trigger().lower()]
|
419
|
+
|
420
|
+
if processing_router.disable_redirect_stdout:
|
421
|
+
if isinstance(self._dividing_line, StaticDividingLine):
|
422
|
+
self._print_func(self._dividing_line.get_full_static_line(self._override_system_messages))
|
423
|
+
processing_router.finds_appropriate_handler(input_command)
|
424
|
+
self._print_func(self._dividing_line.get_full_static_line(self._override_system_messages))
|
425
|
+
else:
|
426
|
+
self._print_func(StaticDividingLine(self._dividing_line.get_unit_part()).get_full_static_line(self._override_system_messages))
|
427
|
+
processing_router.finds_appropriate_handler(input_command)
|
428
|
+
self._print_func(StaticDividingLine(self._dividing_line.get_unit_part()).get_full_static_line(self._override_system_messages))
|
429
|
+
else:
|
430
|
+
with redirect_stdout(io.StringIO()) as f:
|
431
|
+
processing_router.finds_appropriate_handler(input_command)
|
432
|
+
res: str = f.getvalue()
|
433
|
+
if res:
|
434
|
+
self._print_framed_text(res)
|
423
435
|
|
424
436
|
def include_router(self, router: Router) -> None:
|
425
437
|
"""
|
@@ -4,7 +4,7 @@ from argenta.router import Router
|
|
4
4
|
|
5
5
|
|
6
6
|
class RegisteredRouters:
|
7
|
-
def __init__(self, registered_routers: list[Router] = None) -> None:
|
7
|
+
def __init__(self, registered_routers: list[Router] | None = None) -> None:
|
8
8
|
"""
|
9
9
|
Private. Combines registered routers
|
10
10
|
:param registered_routers: list of the registered routers
|
argenta/command/flag/__init__.py
CHANGED
@@ -1,7 +1,17 @@
|
|
1
|
-
__all__ = [
|
1
|
+
__all__ = [
|
2
|
+
"Flag",
|
3
|
+
"InputFlag",
|
4
|
+
"UndefinedInputFlags",
|
5
|
+
"ValidInputFlags",
|
6
|
+
"InvalidValueInputFlags",
|
7
|
+
"Flags", "PossibleValues"
|
8
|
+
]
|
2
9
|
|
3
10
|
|
4
|
-
from argenta.command.flag.models import Flag, InputFlag
|
5
|
-
from argenta.command.flag.flags.models import (
|
6
|
-
|
7
|
-
|
11
|
+
from argenta.command.flag.models import Flag, InputFlag, PossibleValues
|
12
|
+
from argenta.command.flag.flags.models import (
|
13
|
+
UndefinedInputFlags,
|
14
|
+
ValidInputFlags,
|
15
|
+
Flags,
|
16
|
+
InvalidValueInputFlags,
|
17
|
+
)
|
argenta/command/flag/defaults.py
CHANGED
@@ -1,22 +1,23 @@
|
|
1
1
|
from dataclasses import dataclass
|
2
|
-
from argenta.command.flag.models import Flag
|
2
|
+
from argenta.command.flag.models import Flag, PossibleValues
|
3
3
|
import re
|
4
4
|
|
5
5
|
|
6
|
+
|
6
7
|
@dataclass
|
7
8
|
class PredefinedFlags:
|
8
9
|
"""
|
9
10
|
Public. A dataclass with predefined flags and most frequently used flags for quick use
|
10
11
|
"""
|
11
12
|
|
12
|
-
HELP = Flag(name="help", possible_values=
|
13
|
-
SHORT_HELP = Flag(name="H", prefix="-", possible_values=
|
13
|
+
HELP = Flag(name="help", possible_values=PossibleValues.DISABLE)
|
14
|
+
SHORT_HELP = Flag(name="H", prefix="-", possible_values=PossibleValues.DISABLE)
|
14
15
|
|
15
|
-
INFO = Flag(name="info", possible_values=
|
16
|
-
SHORT_INFO = Flag(name="I", prefix="-", possible_values=
|
16
|
+
INFO = Flag(name="info", possible_values=PossibleValues.DISABLE)
|
17
|
+
SHORT_INFO = Flag(name="I", prefix="-", possible_values=PossibleValues.DISABLE)
|
17
18
|
|
18
|
-
ALL = Flag(name="all", possible_values=
|
19
|
-
SHORT_ALL = Flag(name="A", prefix="-", possible_values=
|
19
|
+
ALL = Flag(name="all", possible_values=PossibleValues.DISABLE)
|
20
|
+
SHORT_ALL = Flag(name="A", prefix="-", possible_values=PossibleValues.DISABLE)
|
20
21
|
|
21
22
|
HOST = Flag(
|
22
23
|
name="host", possible_values=re.compile(r"^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$")
|
argenta/command/flag/models.py
CHANGED
@@ -1,6 +1,16 @@
|
|
1
|
+
from enum import Enum
|
1
2
|
from typing import Literal, Pattern
|
2
3
|
|
3
4
|
|
5
|
+
|
6
|
+
class PossibleValues(Enum):
|
7
|
+
DISABLE: Literal[False] = False
|
8
|
+
ALL: Literal[True] = True
|
9
|
+
|
10
|
+
def __eq__(self, other: bool) -> bool:
|
11
|
+
return self.value == other
|
12
|
+
|
13
|
+
|
4
14
|
class BaseFlag:
|
5
15
|
def __init__(self, name: str, prefix: Literal["-", "--", "---"] = "--") -> None:
|
6
16
|
"""
|
@@ -43,7 +53,7 @@ class Flag(BaseFlag):
|
|
43
53
|
self,
|
44
54
|
name: str,
|
45
55
|
prefix: Literal["-", "--", "---"] = "--",
|
46
|
-
possible_values: list[str] | Pattern[str] |
|
56
|
+
possible_values: list[str] | Pattern[str] | PossibleValues = PossibleValues.ALL,
|
47
57
|
) -> None:
|
48
58
|
"""
|
49
59
|
Public. The entity of the flag being registered for subsequent processing
|
@@ -61,7 +71,7 @@ class Flag(BaseFlag):
|
|
61
71
|
:param input_flag_value: The input flag value to validate
|
62
72
|
:return: whether the entered flag is valid as bool
|
63
73
|
"""
|
64
|
-
if self.possible_values
|
74
|
+
if self.possible_values == PossibleValues.DISABLE:
|
65
75
|
if input_flag_value is None:
|
66
76
|
return True
|
67
77
|
else:
|
@@ -87,7 +97,10 @@ class Flag(BaseFlag):
|
|
87
97
|
|
88
98
|
class InputFlag(BaseFlag):
|
89
99
|
def __init__(
|
90
|
-
self,
|
100
|
+
self,
|
101
|
+
name: str,
|
102
|
+
prefix: Literal["-", "--", "---"] = "--",
|
103
|
+
value: str | None = None,
|
91
104
|
):
|
92
105
|
"""
|
93
106
|
Public. The entity of the flag of the entered command
|
argenta/command/models.py
CHANGED
@@ -5,10 +5,7 @@ from argenta.command.exceptions import (
|
|
5
5
|
RepeatedInputFlagsException,
|
6
6
|
EmptyInputCommandException,
|
7
7
|
)
|
8
|
-
from typing import
|
9
|
-
|
10
|
-
|
11
|
-
InputCommandType = TypeVar("InputCommandType")
|
8
|
+
from typing import cast, Literal
|
12
9
|
|
13
10
|
|
14
11
|
class BaseCommand:
|
@@ -31,9 +28,9 @@ class Command(BaseCommand):
|
|
31
28
|
def __init__(
|
32
29
|
self,
|
33
30
|
trigger: str,
|
34
|
-
description: str = None,
|
35
|
-
flags: Flag | Flags = None,
|
36
|
-
aliases: list[str] = None,
|
31
|
+
description: str | None = None,
|
32
|
+
flags: Flag | Flags | None = None,
|
33
|
+
aliases: list[str] | None = None,
|
37
34
|
):
|
38
35
|
"""
|
39
36
|
Public. The command that can and should be registered in the Router
|
@@ -94,6 +91,7 @@ class Command(BaseCommand):
|
|
94
91
|
is_valid = registered_flag.validate_input_flag_value(
|
95
92
|
flag.get_value()
|
96
93
|
)
|
94
|
+
|
97
95
|
if is_valid:
|
98
96
|
return "Valid"
|
99
97
|
else:
|
@@ -109,8 +107,8 @@ class Command(BaseCommand):
|
|
109
107
|
return self._description
|
110
108
|
|
111
109
|
|
112
|
-
class InputCommand(BaseCommand
|
113
|
-
def __init__(self, trigger: str, input_flags: InputFlag | InputFlags = None):
|
110
|
+
class InputCommand(BaseCommand):
|
111
|
+
def __init__(self, trigger: str, input_flags: InputFlag | InputFlags | None = None):
|
114
112
|
"""
|
115
113
|
Private. The model of the input command, after parsing
|
116
114
|
:param trigger:the trigger of the command
|
@@ -142,7 +140,7 @@ class InputCommand(BaseCommand, Generic[InputCommandType]):
|
|
142
140
|
return self._input_flags
|
143
141
|
|
144
142
|
@staticmethod
|
145
|
-
def parse(raw_command: str) ->
|
143
|
+
def parse(raw_command: str) -> "InputCommand":
|
146
144
|
"""
|
147
145
|
Private. Parse the raw input command
|
148
146
|
:param raw_command: raw input command
|
argenta/metrics/main.py
CHANGED
@@ -2,25 +2,17 @@ import io
|
|
2
2
|
from contextlib import redirect_stdout
|
3
3
|
from time import time
|
4
4
|
|
5
|
-
from argenta.router import Router
|
6
|
-
from argenta.command import Command
|
7
|
-
from argenta.response import Response
|
8
|
-
from argenta.response.status import Status
|
9
|
-
from argenta.command.flag import Flag, Flags
|
10
5
|
from argenta.app import App
|
11
6
|
|
12
7
|
|
13
8
|
def get_time_of_pre_cycle_setup(app: App) -> float:
|
9
|
+
"""
|
10
|
+
Public. Return time of pre cycle setup
|
11
|
+
:param app: app instance for testing time of pre cycle setup
|
12
|
+
:return: time of pre cycle setup as float
|
13
|
+
"""
|
14
14
|
start = time()
|
15
15
|
with redirect_stdout(io.StringIO()):
|
16
16
|
app.pre_cycle_setup()
|
17
17
|
end = time()
|
18
18
|
return end - start
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
argenta/orchestrator/entity.py
CHANGED
@@ -5,13 +5,13 @@ from argenta.orchestrator.argparser import ArgParser
|
|
5
5
|
|
6
6
|
|
7
7
|
class Orchestrator:
|
8
|
-
def __init__(self, arg_parser: ArgParser =
|
8
|
+
def __init__(self, arg_parser: ArgParser | None = None):
|
9
9
|
"""
|
10
10
|
Public. An orchestrator and configurator that defines the behavior of an integrated system, one level higher than the App
|
11
11
|
:param arg_parser: Cmd argument parser and configurator at startup
|
12
12
|
:return: None
|
13
13
|
"""
|
14
|
-
self.arg_parser: ArgParser |
|
14
|
+
self.arg_parser: ArgParser | None = arg_parser
|
15
15
|
if arg_parser:
|
16
16
|
self.arg_parser.register_args()
|
17
17
|
|
argenta/response/entity.py
CHANGED
@@ -11,7 +11,7 @@ class Response:
|
|
11
11
|
|
12
12
|
def __init__(
|
13
13
|
self,
|
14
|
-
status: Status = None,
|
14
|
+
status: Status | None = None,
|
15
15
|
valid_flags: ValidInputFlags = ValidInputFlags(),
|
16
16
|
undefined_flags: UndefinedInputFlags = UndefinedInputFlags(),
|
17
17
|
invalid_value_flags: InvalidValueInputFlags = InvalidValueInputFlags(),
|
@@ -38,7 +38,7 @@ class CommandHandler:
|
|
38
38
|
|
39
39
|
|
40
40
|
class CommandHandlers:
|
41
|
-
def __init__(self, command_handlers: list[CommandHandler] = None):
|
41
|
+
def __init__(self, command_handlers: list[CommandHandler] | None = None):
|
42
42
|
"""
|
43
43
|
Private. The model that unites all CommandHandler of the routers
|
44
44
|
:param command_handlers: list of CommandHandlers for register
|
argenta/router/entity.py
CHANGED
@@ -22,13 +22,21 @@ from argenta.router.exceptions import (
|
|
22
22
|
|
23
23
|
|
24
24
|
class Router:
|
25
|
-
def __init__(
|
25
|
+
def __init__(
|
26
|
+
self, title: str | None = "Awesome title", disable_redirect_stdout: bool = False
|
27
|
+
):
|
26
28
|
"""
|
27
29
|
Public. Directly configures and manages handlers
|
28
30
|
:param title: the title of the router, displayed when displaying the available commands
|
31
|
+
:param disable_redirect_stdout: Disables stdout forwarding, if the argument value is True,
|
32
|
+
the StaticDividingLine will be forced to be used as a line separator for this router,
|
33
|
+
disabled forwarding is needed when there is text output in conjunction with a text input request (for example, input()),
|
34
|
+
if the argument value is True, the output of the input() prompt is intercepted and not displayed,
|
35
|
+
which is ambiguous behavior and can lead to unexpected work
|
29
36
|
:return: None
|
30
37
|
"""
|
31
38
|
self.title = title
|
39
|
+
self.disable_redirect_stdout = disable_redirect_stdout
|
32
40
|
|
33
41
|
self._command_handlers: CommandHandlers = CommandHandlers()
|
34
42
|
self._ignore_command_register: bool = False
|
@@ -39,13 +47,15 @@ class Router:
|
|
39
47
|
:param command: Registered command
|
40
48
|
:return: decorated handler as Callable
|
41
49
|
"""
|
42
|
-
self._validate_command(command)
|
43
50
|
if isinstance(command, str):
|
44
|
-
|
51
|
+
redefined_command = Command(command)
|
52
|
+
else:
|
53
|
+
redefined_command = command
|
54
|
+
self._validate_command(redefined_command)
|
45
55
|
|
46
56
|
def command_decorator(func):
|
47
57
|
Router._validate_func_args(func)
|
48
|
-
self._command_handlers.add_handler(CommandHandler(func,
|
58
|
+
self._command_handlers.add_handler(CommandHandler(func, redefined_command))
|
49
59
|
|
50
60
|
def wrapper(*args, **kwargs):
|
51
61
|
return func(*args, **kwargs)
|
@@ -83,9 +93,7 @@ class Router:
|
|
83
93
|
response: Response = Response()
|
84
94
|
if handle_command.get_registered_flags().get_flags():
|
85
95
|
if input_command_flags.get_flags():
|
86
|
-
response: Response = self._structuring_input_flags(
|
87
|
-
handle_command, input_command_flags
|
88
|
-
)
|
96
|
+
response: Response = self._structuring_input_flags( handle_command, input_command_flags )
|
89
97
|
command_handler.handling(response)
|
90
98
|
else:
|
91
99
|
response.status = Status.ALL_FLAGS_VALID
|
@@ -117,13 +125,12 @@ class Router:
|
|
117
125
|
flag_status: Literal["Undefined", "Valid", "Invalid"] = (
|
118
126
|
handled_command.validate_input_flag(flag)
|
119
127
|
)
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
invalid_value_input_flags.add_flag(flag)
|
128
|
+
if flag_status == "Valid":
|
129
|
+
valid_input_flags.add_flag(flag)
|
130
|
+
elif flag_status == "Undefined":
|
131
|
+
undefined_input_flags.add_flag(flag)
|
132
|
+
elif flag_status == "Invalid":
|
133
|
+
invalid_value_input_flags.add_flag(flag)
|
127
134
|
|
128
135
|
if (
|
129
136
|
not invalid_value_input_flags.get_flags()
|
@@ -151,25 +158,20 @@ class Router:
|
|
151
158
|
)
|
152
159
|
|
153
160
|
@staticmethod
|
154
|
-
def _validate_command(command: Command
|
161
|
+
def _validate_command(command: Command) -> None:
|
155
162
|
"""
|
156
163
|
Private. Validates the command registered in handler
|
157
164
|
:param command: validated command
|
158
165
|
:return: None if command is valid else raise exception
|
159
166
|
"""
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
if len(set(flags_name)) < len(flags_name):
|
169
|
-
raise RepeatedFlagNameException()
|
170
|
-
case "str":
|
171
|
-
if command.find(" ") != -1:
|
172
|
-
raise TriggerContainSpacesException()
|
167
|
+
command_name: str = command.get_trigger()
|
168
|
+
if command_name.find(" ") != -1:
|
169
|
+
raise TriggerContainSpacesException()
|
170
|
+
flags: Flags = command.get_registered_flags()
|
171
|
+
if flags:
|
172
|
+
flags_name: list = [x.get_string_entity().lower() for x in flags]
|
173
|
+
if len(set(flags_name)) < len(flags_name):
|
174
|
+
raise RepeatedFlagNameException()
|
173
175
|
|
174
176
|
@staticmethod
|
175
177
|
def _validate_func_args(func: Callable) -> None:
|
@@ -191,13 +193,15 @@ class Router:
|
|
191
193
|
if arg_annotation is Response:
|
192
194
|
pass
|
193
195
|
else:
|
194
|
-
file_path: str = getsourcefile(func)
|
196
|
+
file_path: str | None = getsourcefile(func)
|
195
197
|
source_line: int = getsourcelines(func)[1]
|
196
198
|
fprint = Console().print
|
197
|
-
fprint(
|
199
|
+
fprint(
|
200
|
+
f'\nFile "{file_path}", line {source_line}\n[b red]WARNING:[/b red] [i]The typehint '
|
198
201
|
f"of argument([green]{transferred_arg}[/green]) passed to the handler is [/i][bold blue]{Response}[/bold blue],"
|
199
202
|
f" [i]but[/i] [bold blue]{arg_annotation}[/bold blue] [i]is specified[/i]",
|
200
|
-
highlight=False
|
203
|
+
highlight=False,
|
204
|
+
)
|
201
205
|
|
202
206
|
def set_command_register_ignore(self, _: bool) -> None:
|
203
207
|
"""
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: argenta
|
3
|
-
Version: 1.0.
|
3
|
+
Version: 1.0.7
|
4
4
|
Summary: Python library for building modular CLI applications
|
5
5
|
Author-email: kolo <kolo.is.main@gmail.com>
|
6
6
|
License: MIT
|
@@ -73,7 +73,6 @@ if __name__ == '__main__':
|
|
73
73
|
# Features in development
|
74
74
|
|
75
75
|
- Full support for autocompleter on Linux
|
76
|
-
- Ability to configure stdout capture when handling input by the handler
|
77
76
|
|
78
77
|
## Full [docs](https://argenta-docs.vercel.app) | MIT 2025 kolo | made by [kolo](https://t.me/kolo_id)
|
79
78
|
|
@@ -1,39 +1,39 @@
|
|
1
1
|
argenta/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
2
2
|
argenta/app/__init__.py,sha256=I8FTXU17ajDI-hbC6Rw0LxLmvDYipdQaos3v1pmu14E,57
|
3
|
-
argenta/app/defaults.py,sha256=
|
4
|
-
argenta/app/models.py,sha256=
|
3
|
+
argenta/app/defaults.py,sha256=imtg6sOZ82xwttr7YCwBoMRFG_lhCkyk0tP63o1NSuI,381
|
4
|
+
argenta/app/models.py,sha256=y7XZ3MVw_q8wHyrLlZMhtl9LzgzzXIY_m6Ud8hsli2w,20150
|
5
5
|
argenta/app/autocompleter/__init__.py,sha256=VT_p3QA78UnczV7pYR2NnwQ0Atd8mnDUnLazvUQNqJk,93
|
6
|
-
argenta/app/autocompleter/entity.py,sha256=
|
6
|
+
argenta/app/autocompleter/entity.py,sha256=55yUwlCEPPF8Z4t7y8Fl4DgLyH27qeybynXphDJ6XvM,3562
|
7
7
|
argenta/app/dividing_line/__init__.py,sha256=jJZDDZix8XYCAUWW4FzGJH0JmJlchYcx0FPWifjgv1I,147
|
8
8
|
argenta/app/dividing_line/models.py,sha256=syBTrzcIIt6E6RiaKC9QH3kdAuWLBDNIX0cH7Bnn0mk,2265
|
9
9
|
argenta/app/registered_routers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
10
|
-
argenta/app/registered_routers/entity.py,sha256=
|
10
|
+
argenta/app/registered_routers/entity.py,sha256=xTRW3R2dWnSOz8QIsiUVmG8VuMJmyOMUqHzEDDpNX-0,1085
|
11
11
|
argenta/command/__init__.py,sha256=RvacrM84ZwBdVDy4MUwjLTyzQdDQrjjoikZxwh5ov-0,69
|
12
12
|
argenta/command/exceptions.py,sha256=86Gs_9-NutmbSkduEMljtxQHWHhDRFcqyyOKDhQ440o,1060
|
13
|
-
argenta/command/models.py,sha256=
|
14
|
-
argenta/command/flag/__init__.py,sha256=
|
15
|
-
argenta/command/flag/defaults.py,sha256=
|
16
|
-
argenta/command/flag/models.py,sha256=
|
13
|
+
argenta/command/models.py,sha256=TYmKVJUsX8vxBfCVnQw0rp7CvzStr5BrDcV0IlRyCyc,7116
|
14
|
+
argenta/command/flag/__init__.py,sha256=cXzUCEK_zGYd7d3YbymYVzfDAusrY9DMhjC48--PUdg,379
|
15
|
+
argenta/command/flag/defaults.py,sha256=dkzE750mC-w6DPIGZsdhfnmc87-y7P-FIKMT_PAcq_0,1155
|
16
|
+
argenta/command/flag/models.py,sha256=hGmgVX__ZgfNSB8KCqIT6SF-BOiZ_A0b2C031a_pSac,4158
|
17
17
|
argenta/command/flag/flags/__init__.py,sha256=-HfdBZ3WXrjMrM8vEDWg0LLOLuQafqncrjw9KVFyqoE,294
|
18
18
|
argenta/command/flag/flags/models.py,sha256=U4nOwCqsCOURGigTKiQx07zBUKj0EoY0fCwgTNq4GIg,2332
|
19
19
|
argenta/metrics/__init__.py,sha256=PPLFPxhe4j7r6hP1P1pk0A_gnXgylbTaHqopky872AU,109
|
20
|
-
argenta/metrics/main.py,sha256=
|
20
|
+
argenta/metrics/main.py,sha256=vkvvI4xFbIcs0bNumtyiA_o3v66FF5LI38QoNnLCD6c,472
|
21
21
|
argenta/orchestrator/__init__.py,sha256=vFtJEJTjFfoYP3DZx0gNlhoa0Tk8u-yzkGIUN3SiABA,86
|
22
|
-
argenta/orchestrator/entity.py,sha256=
|
22
|
+
argenta/orchestrator/entity.py,sha256=I0HWZnpoD0Pen5azeTBh8s-CFU8vs0bTILpgRls-1hI,1098
|
23
23
|
argenta/orchestrator/argparser/__init__.py,sha256=akbTPC5CfNrgJTVVu1A2E9KeI8KPN4JnMM8M8U21jc8,90
|
24
24
|
argenta/orchestrator/argparser/entity.py,sha256=i3lCsCr_8JT09OosvxRuRD7KKP1MgeNFYz5kTTTqu9Q,2087
|
25
25
|
argenta/orchestrator/argparser/arguments/__init__.py,sha256=lRsKyJeiibPYhFZoeB3BRfIYM4mlUFp6nZpy9RdbgYg,213
|
26
26
|
argenta/orchestrator/argparser/arguments/models.py,sha256=wF4rIaEAx9Rt-c6rAeq6kZLfNPTn4v9WBNt9JHzJ0RA,1548
|
27
27
|
argenta/response/__init__.py,sha256=u4NuwUQkWa55aX67hTQs_B_gIaZ9Dn4Fe7xhSFQ_Rpw,128
|
28
|
-
argenta/response/entity.py,sha256=
|
28
|
+
argenta/response/entity.py,sha256=vUVeiOp8BbuUW2VRtyQlFMQ_-KkQPjOgz9p7DxwyoeE,1054
|
29
29
|
argenta/response/status.py,sha256=bWFMHvyIHpOA4LxUQFoSpld-F8gu183M9nY-zN-MiZM,244
|
30
30
|
argenta/router/__init__.py,sha256=rvqAx80IXHFdVw7cWBRGaTtb94a4OQQEsMJ5f7YA1gU,68
|
31
31
|
argenta/router/defaults.py,sha256=vvkwFYCQdwjtMntfyrJuisxFX8XxeyhDMA-RwteHZGg,87
|
32
|
-
argenta/router/entity.py,sha256=
|
32
|
+
argenta/router/entity.py,sha256=5eIn6OwUM4oNdFOtmC_jxDyxD54U3wl8c7W2AU2hyqE,10071
|
33
33
|
argenta/router/exceptions.py,sha256=5k0mTHYYItWHzGC0NU5oHHYrHxU0M5fEbO5wne_wFg8,860
|
34
34
|
argenta/router/command_handler/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
35
|
-
argenta/router/command_handler/entity.py,sha256=
|
36
|
-
argenta-1.0.
|
37
|
-
argenta-1.0.
|
38
|
-
argenta-1.0.
|
39
|
-
argenta-1.0.
|
35
|
+
argenta/router/command_handler/entity.py,sha256=ascEf3AzYcWh-G5cml08WOoRr2q9QkfLP2IaKC1iKWM,2394
|
36
|
+
argenta-1.0.7.dist-info/METADATA,sha256=4uN_xlRCoJWKU0TY48l78TD6-jllclnWonMqknFX6-8,1576
|
37
|
+
argenta-1.0.7.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
38
|
+
argenta-1.0.7.dist-info/licenses/LICENSE,sha256=zmqoGh2n5rReBv4s8wPxF_gZEZDgauJYSPMuPczgOiU,1082
|
39
|
+
argenta-1.0.7.dist-info/RECORD,,
|
File without changes
|
File without changes
|