argenta 1.0.0b1__py3-none-any.whl → 1.0.1__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 +30 -11
- argenta/app/defaults.py +3 -3
- argenta/app/dividing_line/models.py +8 -10
- argenta/app/models.py +181 -114
- argenta/app/registered_routers/entity.py +1 -1
- argenta/command/__init__.py +1 -1
- argenta/command/exceptions.py +9 -2
- argenta/command/flag/defaults.py +17 -10
- argenta/command/flag/models.py +18 -9
- argenta/command/flags/__init__.py +14 -8
- argenta/command/flags/models.py +22 -7
- argenta/command/models.py +61 -36
- argenta/orchestrator/argparser/__init__.py +1 -1
- argenta/orchestrator/argparser/arguments/__init__.py +5 -3
- argenta/orchestrator/argparser/arguments/models.py +3 -2
- argenta/orchestrator/argparser/entity.py +22 -12
- argenta/orchestrator/entity.py +0 -1
- argenta/response/entity.py +14 -5
- argenta/response/status.py +4 -5
- argenta/router/__init__.py +1 -1
- argenta/router/command_handler/entity.py +1 -1
- argenta/router/defaults.py +1 -1
- argenta/router/entity.py +83 -67
- argenta/router/exceptions.py +4 -0
- argenta-1.0.1.dist-info/METADATA +71 -0
- argenta-1.0.1.dist-info/RECORD +37 -0
- argenta-1.0.0b1.dist-info/METADATA +0 -1340
- argenta-1.0.0b1.dist-info/RECORD +0 -37
- {argenta-1.0.0b1.dist-info → argenta-1.0.1.dist-info}/WHEEL +0 -0
- {argenta-1.0.0b1.dist-info → argenta-1.0.1.dist-info}/licenses/LICENSE +0 -0
argenta/router/entity.py
CHANGED
@@ -1,38 +1,47 @@
|
|
1
1
|
from typing import Callable, Literal, Type
|
2
|
-
from inspect import getfullargspec, get_annotations
|
2
|
+
from inspect import getfullargspec, get_annotations, getsourcefile, getsourcelines
|
3
3
|
from rich.console import Console
|
4
4
|
|
5
5
|
from argenta.command import Command
|
6
6
|
from argenta.command.models import InputCommand
|
7
7
|
from argenta.response import Response, Status
|
8
8
|
from argenta.router.command_handler.entity import CommandHandlers, CommandHandler
|
9
|
-
from argenta.command.flags.models import
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
9
|
+
from argenta.command.flags.models import (
|
10
|
+
Flags,
|
11
|
+
InputFlags,
|
12
|
+
UndefinedInputFlags,
|
13
|
+
ValidInputFlags,
|
14
|
+
InvalidValueInputFlags,
|
15
|
+
)
|
16
|
+
from argenta.router.exceptions import (
|
17
|
+
RepeatedFlagNameException,
|
18
|
+
TooManyTransferredArgsException,
|
19
|
+
RequiredArgumentNotPassedException,
|
20
|
+
TriggerContainSpacesException,
|
21
|
+
)
|
14
22
|
|
15
23
|
|
16
24
|
class Router:
|
17
|
-
def __init__(self, title: str =
|
25
|
+
def __init__(self, title: str | None = "Awesome title"):
|
18
26
|
"""
|
19
27
|
Public. Directly configures and manages handlers
|
20
28
|
:param title: the title of the router, displayed when displaying the available commands
|
21
29
|
:return: None
|
22
30
|
"""
|
23
|
-
self.
|
31
|
+
self.title = title
|
24
32
|
|
25
33
|
self._command_handlers: CommandHandlers = CommandHandlers()
|
26
34
|
self._ignore_command_register: bool = False
|
27
35
|
|
28
|
-
|
29
|
-
def command(self, command: Command) -> Callable:
|
36
|
+
def command(self, command: Command | str) -> Callable:
|
30
37
|
"""
|
31
38
|
Public. Registers handler
|
32
39
|
:param command: Registered command
|
33
40
|
:return: decorated handler as Callable
|
34
41
|
"""
|
35
42
|
self._validate_command(command)
|
43
|
+
if isinstance(command, str):
|
44
|
+
command = Command(command)
|
36
45
|
|
37
46
|
def command_decorator(func):
|
38
47
|
Router._validate_func_args(func)
|
@@ -40,11 +49,11 @@ class Router:
|
|
40
49
|
|
41
50
|
def wrapper(*args, **kwargs):
|
42
51
|
return func(*args, **kwargs)
|
52
|
+
|
43
53
|
return wrapper
|
44
54
|
|
45
55
|
return command_decorator
|
46
56
|
|
47
|
-
|
48
57
|
def finds_appropriate_handler(self, input_command: InputCommand) -> None:
|
49
58
|
"""
|
50
59
|
Private. Finds the appropriate handler for given input command and passes control to it
|
@@ -61,8 +70,9 @@ class Router:
|
|
61
70
|
if input_command_name.lower() in handle_command.get_aliases():
|
62
71
|
self.process_input_command(input_command_flags, command_handler)
|
63
72
|
|
64
|
-
|
65
|
-
|
73
|
+
def process_input_command(
|
74
|
+
self, input_command_flags: InputFlags, command_handler: CommandHandler
|
75
|
+
) -> None:
|
66
76
|
"""
|
67
77
|
Private. Processes input command with the appropriate handler
|
68
78
|
:param input_command_flags: input command flags as InputFlags
|
@@ -73,9 +83,9 @@ class Router:
|
|
73
83
|
response: Response = Response()
|
74
84
|
if handle_command.get_registered_flags().get_flags():
|
75
85
|
if input_command_flags.get_flags():
|
76
|
-
|
77
|
-
|
78
|
-
|
86
|
+
response: Response = self._structuring_input_flags(
|
87
|
+
handle_command, input_command_flags
|
88
|
+
)
|
79
89
|
command_handler.handling(response)
|
80
90
|
else:
|
81
91
|
response.status = Status.ALL_FLAGS_VALID
|
@@ -90,60 +100,76 @@ class Router:
|
|
90
100
|
response.status = Status.ALL_FLAGS_VALID
|
91
101
|
command_handler.handling(response)
|
92
102
|
|
93
|
-
|
94
103
|
@staticmethod
|
95
|
-
def
|
96
|
-
|
97
|
-
|
98
|
-
Status]:
|
104
|
+
def _structuring_input_flags(
|
105
|
+
handled_command: Command, input_flags: InputFlags
|
106
|
+
) -> Response:
|
99
107
|
"""
|
100
108
|
Private. Validates flags of input command
|
101
109
|
:param handled_command: entity of the handled command
|
102
110
|
:param input_flags:
|
103
|
-
:return:
|
111
|
+
:return: entity of response as Response
|
104
112
|
"""
|
105
113
|
valid_input_flags: ValidInputFlags = ValidInputFlags()
|
106
114
|
invalid_value_input_flags: InvalidValueInputFlags = InvalidValueInputFlags()
|
107
115
|
undefined_input_flags: UndefinedInputFlags = UndefinedInputFlags()
|
108
116
|
for flag in input_flags:
|
109
|
-
flag_status: Literal[
|
117
|
+
flag_status: Literal["Undefined", "Valid", "Invalid"] = (
|
118
|
+
handled_command.validate_input_flag(flag)
|
119
|
+
)
|
110
120
|
match flag_status:
|
111
|
-
case
|
121
|
+
case "Valid":
|
112
122
|
valid_input_flags.add_flag(flag)
|
113
|
-
case
|
123
|
+
case "Undefined":
|
114
124
|
undefined_input_flags.add_flag(flag)
|
115
|
-
case
|
125
|
+
case "Invalid":
|
116
126
|
invalid_value_input_flags.add_flag(flag)
|
117
127
|
|
118
|
-
if
|
128
|
+
if (
|
129
|
+
not invalid_value_input_flags.get_flags()
|
130
|
+
and not undefined_input_flags.get_flags()
|
131
|
+
):
|
119
132
|
status = Status.ALL_FLAGS_VALID
|
120
|
-
elif
|
133
|
+
elif (
|
134
|
+
invalid_value_input_flags.get_flags()
|
135
|
+
and not undefined_input_flags.get_flags()
|
136
|
+
):
|
121
137
|
status = Status.INVALID_VALUE_FLAGS
|
122
|
-
elif
|
138
|
+
elif (
|
139
|
+
not invalid_value_input_flags.get_flags()
|
140
|
+
and undefined_input_flags.get_flags()
|
141
|
+
):
|
123
142
|
status = Status.UNDEFINED_FLAGS
|
124
143
|
else:
|
125
144
|
status = Status.UNDEFINED_AND_INVALID_FLAGS
|
126
145
|
|
127
|
-
return (
|
128
|
-
|
146
|
+
return Response(
|
147
|
+
invalid_value_flags=invalid_value_input_flags,
|
148
|
+
valid_flags=valid_input_flags,
|
149
|
+
status=status,
|
150
|
+
undefined_flags=undefined_input_flags,
|
151
|
+
)
|
129
152
|
|
130
153
|
@staticmethod
|
131
|
-
def _validate_command(command: Command) -> None:
|
154
|
+
def _validate_command(command: Command | str) -> None:
|
132
155
|
"""
|
133
156
|
Private. Validates the command registered in handler
|
134
157
|
:param command: validated command
|
135
158
|
:return: None if command is valid else raise exception
|
136
159
|
"""
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
160
|
+
match type(command).__name__:
|
161
|
+
case "Command":
|
162
|
+
command_name: str = command.get_trigger()
|
163
|
+
if command_name.find(" ") != -1:
|
164
|
+
raise TriggerContainSpacesException()
|
165
|
+
flags: Flags = command.get_registered_flags()
|
166
|
+
if flags:
|
167
|
+
flags_name: list = [x.get_string_entity().lower() for x in flags]
|
168
|
+
if len(set(flags_name)) < len(flags_name):
|
169
|
+
raise RepeatedFlagNameException()
|
170
|
+
case "str":
|
171
|
+
if command.find(" ") != -1:
|
172
|
+
raise TriggerContainSpacesException()
|
147
173
|
|
148
174
|
@staticmethod
|
149
175
|
def _validate_func_args(func: Callable) -> None:
|
@@ -158,12 +184,22 @@ class Router:
|
|
158
184
|
elif len(transferred_args) == 0:
|
159
185
|
raise RequiredArgumentNotPassedException()
|
160
186
|
|
161
|
-
|
162
|
-
|
163
|
-
Console().print(f'\n\n[b red]WARNING:[/b red] [i]The type of argument passed to the handler is [/i][blue]{Response}[/blue],'
|
164
|
-
f' [i]but[/i] [bold blue]{arg_annotation}[/bold blue] [i]is specified[/i]', highlight=False)
|
165
|
-
|
187
|
+
transferred_arg: str = transferred_args[0]
|
188
|
+
func_annotations: dict[str, Type] = get_annotations(func)
|
166
189
|
|
190
|
+
if arg_annotation := func_annotations.get(transferred_arg):
|
191
|
+
if arg_annotation is Response:
|
192
|
+
pass
|
193
|
+
else:
|
194
|
+
file_path: str = getsourcefile(func)
|
195
|
+
source_line: int = getsourcelines(func)[1] + 1
|
196
|
+
fprint = Console().print
|
197
|
+
fprint(
|
198
|
+
f'\nFile "{file_path}", line {source_line}\n[b red]WARNING:[/b red] [i]The typehint '
|
199
|
+
f"of argument([green]{transferred_arg}[/green]) passed to the handler is [/i][bold blue]{Response}[/bold blue],"
|
200
|
+
f" [i]but[/i] [bold blue]{arg_annotation}[/bold blue] [i]is specified[/i]\n",
|
201
|
+
highlight=False,
|
202
|
+
)
|
167
203
|
|
168
204
|
def set_command_register_ignore(self, _: bool) -> None:
|
169
205
|
"""
|
@@ -173,7 +209,6 @@ class Router:
|
|
173
209
|
"""
|
174
210
|
self._ignore_command_register = _
|
175
211
|
|
176
|
-
|
177
212
|
def get_triggers(self) -> list[str]:
|
178
213
|
"""
|
179
214
|
Public. Gets registered triggers
|
@@ -184,7 +219,6 @@ class Router:
|
|
184
219
|
all_triggers.append(command_handler.get_handled_command().get_trigger())
|
185
220
|
return all_triggers
|
186
221
|
|
187
|
-
|
188
222
|
def get_aliases(self) -> list[str]:
|
189
223
|
"""
|
190
224
|
Public. Gets registered aliases
|
@@ -196,27 +230,9 @@ class Router:
|
|
196
230
|
all_aliases.extend(command_handler.get_handled_command().get_aliases())
|
197
231
|
return all_aliases
|
198
232
|
|
199
|
-
|
200
233
|
def get_command_handlers(self) -> CommandHandlers:
|
201
234
|
"""
|
202
235
|
Private. Gets registered command handlers
|
203
236
|
:return: registered command handlers as CommandHandlers
|
204
237
|
"""
|
205
238
|
return self._command_handlers
|
206
|
-
|
207
|
-
|
208
|
-
def get_title(self) -> str | None:
|
209
|
-
"""
|
210
|
-
Public. Gets title of the router
|
211
|
-
:return: the title of the router as str or None
|
212
|
-
"""
|
213
|
-
return self._title
|
214
|
-
|
215
|
-
|
216
|
-
def set_title(self, title: str) -> None:
|
217
|
-
"""
|
218
|
-
Public. Sets the title of the router
|
219
|
-
:param title: title that will be setted
|
220
|
-
:return: None
|
221
|
-
"""
|
222
|
-
self._title = title
|
argenta/router/exceptions.py
CHANGED
@@ -2,6 +2,7 @@ class RepeatedFlagNameException(Exception):
|
|
2
2
|
"""
|
3
3
|
Private. Raised when a repeated flag name is registered
|
4
4
|
"""
|
5
|
+
|
5
6
|
def __str__(self):
|
6
7
|
return "Repeated registered flag names in register command"
|
7
8
|
|
@@ -10,6 +11,7 @@ class TooManyTransferredArgsException(Exception):
|
|
10
11
|
"""
|
11
12
|
Private. Raised when too many arguments are passed
|
12
13
|
"""
|
14
|
+
|
13
15
|
def __str__(self):
|
14
16
|
return "Too many transferred arguments"
|
15
17
|
|
@@ -18,6 +20,7 @@ class RequiredArgumentNotPassedException(Exception):
|
|
18
20
|
"""
|
19
21
|
Private. Raised when a required argument is not passed
|
20
22
|
"""
|
23
|
+
|
21
24
|
def __str__(self):
|
22
25
|
return "Required argument not passed"
|
23
26
|
|
@@ -26,5 +29,6 @@ class TriggerContainSpacesException(Exception):
|
|
26
29
|
"""
|
27
30
|
Private. Raised when there is a space in the trigger being registered
|
28
31
|
"""
|
32
|
+
|
29
33
|
def __str__(self):
|
30
34
|
return "Command trigger cannot contain spaces"
|
@@ -0,0 +1,71 @@
|
|
1
|
+
Metadata-Version: 2.4
|
2
|
+
Name: argenta
|
3
|
+
Version: 1.0.1
|
4
|
+
Summary: Python library for building modular CLI applications
|
5
|
+
Author-email: kolo <kolo.is.main@gmail.com>
|
6
|
+
License: MIT
|
7
|
+
License-File: LICENSE
|
8
|
+
Requires-Python: <4.0,>=3.11
|
9
|
+
Requires-Dist: art<7.0,>=6.4
|
10
|
+
Requires-Dist: pyreadline3>=3.5.4
|
11
|
+
Requires-Dist: rich<15.0.0,>=14.0.0
|
12
|
+
Description-Content-Type: text/markdown
|
13
|
+
|
14
|
+
# Argenta
|
15
|
+
|
16
|
+
### Библиотека для создания модульных CLI приложeний
|
17
|
+
|
18
|
+

|
19
|
+
|
20
|
+
---
|
21
|
+
|
22
|
+
# Установка
|
23
|
+
```bash
|
24
|
+
pip install argenta
|
25
|
+
```
|
26
|
+
or
|
27
|
+
```bash
|
28
|
+
poetry add argenta
|
29
|
+
```
|
30
|
+
|
31
|
+
---
|
32
|
+
|
33
|
+
# Быстрый старт
|
34
|
+
|
35
|
+
Пример простейшего приложения
|
36
|
+
```python
|
37
|
+
# routers.py
|
38
|
+
from argenta.router import Router
|
39
|
+
from argenta.command import Command
|
40
|
+
from argenta.response import Response
|
41
|
+
|
42
|
+
|
43
|
+
router = Router()
|
44
|
+
|
45
|
+
@router.command(Command("hello"))
|
46
|
+
def handler(response: Response):
|
47
|
+
print("Hello, world!")
|
48
|
+
```
|
49
|
+
|
50
|
+
```python
|
51
|
+
# main.py
|
52
|
+
from argenta.app import App
|
53
|
+
from argenta.orchestrator import Orchestrator
|
54
|
+
from routers import router
|
55
|
+
|
56
|
+
app: App = App()
|
57
|
+
orchestrator: Orchestrator = Orchestrator()
|
58
|
+
|
59
|
+
|
60
|
+
def main() -> None:
|
61
|
+
app.include_router(router)
|
62
|
+
orchestrator.start_polling(app)
|
63
|
+
|
64
|
+
|
65
|
+
if __name__ == '__main__':
|
66
|
+
main()
|
67
|
+
```
|
68
|
+
## Полная [документация](https://argenta-docs.vercel.app) | MIT 2025 kolo | made by [kolo](https://t.me/kolo_id)
|
69
|
+
|
70
|
+
|
71
|
+
|
@@ -0,0 +1,37 @@
|
|
1
|
+
argenta/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
2
|
+
argenta/app/__init__.py,sha256=I8FTXU17ajDI-hbC6Rw0LxLmvDYipdQaos3v1pmu14E,57
|
3
|
+
argenta/app/defaults.py,sha256=z65HUXd1ogTk95-IWwluPDPz4MkZk1_3jfaSjdTZ4ME,393
|
4
|
+
argenta/app/models.py,sha256=yG3IhR9IrEd2YwrtqoZni6wht2rDOyocfoe5SmPv6cw,19153
|
5
|
+
argenta/app/autocompleter/__init__.py,sha256=VT_p3QA78UnczV7pYR2NnwQ0Atd8mnDUnLazvUQNqJk,93
|
6
|
+
argenta/app/autocompleter/entity.py,sha256=QgEZ2Tzfp9liWBCd-BdRpUE-ELUOxAhPpW7KBLVcPRE,3556
|
7
|
+
argenta/app/dividing_line/__init__.py,sha256=jJZDDZix8XYCAUWW4FzGJH0JmJlchYcx0FPWifjgv1I,147
|
8
|
+
argenta/app/dividing_line/models.py,sha256=syBTrzcIIt6E6RiaKC9QH3kdAuWLBDNIX0cH7Bnn0mk,2265
|
9
|
+
argenta/app/registered_routers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
10
|
+
argenta/app/registered_routers/entity.py,sha256=OH7plYfjQrlyVliXE6OLVD2ftOAd5U1VO6SlyvLNikk,1078
|
11
|
+
argenta/command/__init__.py,sha256=RvacrM84ZwBdVDy4MUwjLTyzQdDQrjjoikZxwh5ov-0,69
|
12
|
+
argenta/command/exceptions.py,sha256=86Gs_9-NutmbSkduEMljtxQHWHhDRFcqyyOKDhQ440o,1060
|
13
|
+
argenta/command/models.py,sha256=9zzOEJt-jn1ke9HcQGnTOIvNZYrXn347rDzVzm2Ve5Y,7180
|
14
|
+
argenta/command/flag/__init__.py,sha256=4MOxfv8f2SkBzIfVo5LAZUTu4iH1jcs5WzPq60PhFMs,94
|
15
|
+
argenta/command/flag/defaults.py,sha256=1F9bEngv6tB_yn5lLQg5pxWZSuinryfGGdXnWD7EvuY,1035
|
16
|
+
argenta/command/flag/models.py,sha256=KAzyoNWVOVLiIT4f8auI15D0TCHosGXHGw_xXRuEtgY,3875
|
17
|
+
argenta/command/flags/__init__.py,sha256=XFi7_xYjpjnet7FGO93PTcUexeTQ9QwFHuUg_19Ferk,289
|
18
|
+
argenta/command/flags/models.py,sha256=U4nOwCqsCOURGigTKiQx07zBUKj0EoY0fCwgTNq4GIg,2332
|
19
|
+
argenta/orchestrator/__init__.py,sha256=vFtJEJTjFfoYP3DZx0gNlhoa0Tk8u-yzkGIUN3SiABA,86
|
20
|
+
argenta/orchestrator/entity.py,sha256=kgTHGrbWdsTDR7aAKv2Bvm8pO7LKFv7v8Dv1LDsdrTo,1093
|
21
|
+
argenta/orchestrator/argparser/__init__.py,sha256=akbTPC5CfNrgJTVVu1A2E9KeI8KPN4JnMM8M8U21jc8,90
|
22
|
+
argenta/orchestrator/argparser/entity.py,sha256=i3lCsCr_8JT09OosvxRuRD7KKP1MgeNFYz5kTTTqu9Q,2087
|
23
|
+
argenta/orchestrator/argparser/arguments/__init__.py,sha256=lRsKyJeiibPYhFZoeB3BRfIYM4mlUFp6nZpy9RdbgYg,213
|
24
|
+
argenta/orchestrator/argparser/arguments/models.py,sha256=wF4rIaEAx9Rt-c6rAeq6kZLfNPTn4v9WBNt9JHzJ0RA,1548
|
25
|
+
argenta/response/__init__.py,sha256=u4NuwUQkWa55aX67hTQs_B_gIaZ9Dn4Fe7xhSFQ_Rpw,128
|
26
|
+
argenta/response/entity.py,sha256=YcuKLnr7iiFewNqUH7bsdv-PccHfpitq-sm06tmSCjE,1042
|
27
|
+
argenta/response/status.py,sha256=bWFMHvyIHpOA4LxUQFoSpld-F8gu183M9nY-zN-MiZM,244
|
28
|
+
argenta/router/__init__.py,sha256=rvqAx80IXHFdVw7cWBRGaTtb94a4OQQEsMJ5f7YA1gU,68
|
29
|
+
argenta/router/defaults.py,sha256=vvkwFYCQdwjtMntfyrJuisxFX8XxeyhDMA-RwteHZGg,87
|
30
|
+
argenta/router/entity.py,sha256=Z3QZpntlZgt2bkJCb3zUsQ1_a05c61iN59-PBG0r7wg,9656
|
31
|
+
argenta/router/exceptions.py,sha256=5k0mTHYYItWHzGC0NU5oHHYrHxU0M5fEbO5wne_wFg8,860
|
32
|
+
argenta/router/command_handler/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
33
|
+
argenta/router/command_handler/entity.py,sha256=xmHgbXBvD_-JMLpUPc5w3VVe-upTJ-y4lR13rUiiygo,2387
|
34
|
+
argenta-1.0.1.dist-info/METADATA,sha256=IH4CZ1jn49gksobDBswJMcdMqDj7CtGY9-QzeWF2BKY,1448
|
35
|
+
argenta-1.0.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
36
|
+
argenta-1.0.1.dist-info/licenses/LICENSE,sha256=zmqoGh2n5rReBv4s8wPxF_gZEZDgauJYSPMuPczgOiU,1082
|
37
|
+
argenta-1.0.1.dist-info/RECORD,,
|