u-toolkit 0.1.10__py3-none-any.whl → 0.1.12__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.
- u_toolkit/fastapi/cbv.py +61 -22
- {u_toolkit-0.1.10.dist-info → u_toolkit-0.1.12.dist-info}/METADATA +1 -1
- {u_toolkit-0.1.10.dist-info → u_toolkit-0.1.12.dist-info}/RECORD +5 -5
- {u_toolkit-0.1.10.dist-info → u_toolkit-0.1.12.dist-info}/WHEEL +0 -0
- {u_toolkit-0.1.10.dist-info → u_toolkit-0.1.12.dist-info}/entry_points.txt +0 -0
u_toolkit/fastapi/cbv.py
CHANGED
@@ -39,7 +39,7 @@ EndpointsClassInterfaceT = TypeVar(
|
|
39
39
|
)
|
40
40
|
|
41
41
|
|
42
|
-
|
42
|
+
LiteralUpperMethod = Literal[
|
43
43
|
"GET",
|
44
44
|
"POST",
|
45
45
|
"PATCH",
|
@@ -49,7 +49,7 @@ LiteralUpperMethods = Literal[
|
|
49
49
|
"HEAD",
|
50
50
|
"TRACE",
|
51
51
|
]
|
52
|
-
|
52
|
+
LiteralLowerMethod = Literal[
|
53
53
|
"get",
|
54
54
|
"post",
|
55
55
|
"patch",
|
@@ -72,23 +72,31 @@ class Methods(StrEnum):
|
|
72
72
|
TRACE = auto()
|
73
73
|
|
74
74
|
|
75
|
+
RequestMethod = Methods | LiteralLowerMethod | LiteralUpperMethod
|
76
|
+
|
77
|
+
|
75
78
|
METHOD_PATTERNS = {
|
76
79
|
method: re.compile(f"^({method}_|{method})", re.IGNORECASE)
|
77
80
|
for method in Methods
|
78
81
|
}
|
79
82
|
|
83
|
+
|
80
84
|
_FnName = str
|
81
85
|
|
82
86
|
|
83
87
|
class EndpointInfo(NamedTuple):
|
84
|
-
|
85
|
-
|
86
|
-
|
88
|
+
handle: Callable
|
89
|
+
original_handle_name: str
|
90
|
+
handle_name: str
|
91
|
+
method: RequestMethod
|
87
92
|
method_pattern: re.Pattern
|
88
93
|
path: str
|
89
94
|
|
90
95
|
|
91
|
-
|
96
|
+
_MethodInfo = tuple[RequestMethod, re.Pattern[str]]
|
97
|
+
|
98
|
+
|
99
|
+
def get_method(name: str) -> _MethodInfo | None:
|
92
100
|
for method, method_pattern in METHOD_PATTERNS.items():
|
93
101
|
if method_pattern.search(name):
|
94
102
|
return method, method_pattern
|
@@ -100,29 +108,43 @@ def valid_endpoint(name: str):
|
|
100
108
|
raise ValueError("Invalid endpoint function.")
|
101
109
|
|
102
110
|
|
103
|
-
def iter_endpoints(
|
104
|
-
|
111
|
+
def iter_endpoints(
|
112
|
+
cls: type[_T],
|
113
|
+
valid_method: Callable[[str, Callable], list[_MethodInfo] | None]
|
114
|
+
| None = None,
|
115
|
+
):
|
116
|
+
prefix = ""
|
105
117
|
|
106
118
|
if not cls.__name__.startswith("_"):
|
107
|
-
prefix += f"{to_snake(cls.__name__)}"
|
119
|
+
prefix += f"/{to_snake(cls.__name__)}"
|
108
120
|
|
109
|
-
for name,
|
121
|
+
for name, handle in inspect.getmembers(
|
110
122
|
cls,
|
111
123
|
lambda arg: inspect.ismethoddescriptor(arg) or inspect.isfunction(arg),
|
112
124
|
):
|
113
125
|
paths = [prefix]
|
114
126
|
|
127
|
+
methods: list[_MethodInfo] = []
|
128
|
+
from_valid_method = False
|
115
129
|
if method := get_method(name):
|
116
|
-
|
130
|
+
methods.append(method)
|
131
|
+
elif valid_method:
|
132
|
+
methods.extend(valid_method(name, handle) or [])
|
133
|
+
from_valid_method = True
|
134
|
+
|
135
|
+
for method, pattern in methods:
|
136
|
+
handle_name = name if from_valid_method else pattern.sub("", name)
|
137
|
+
path = handle_name.replace("__", "/")
|
117
138
|
if path:
|
118
139
|
paths.append(path)
|
119
140
|
|
120
141
|
yield EndpointInfo(
|
121
|
-
|
122
|
-
|
142
|
+
handle=handle,
|
143
|
+
original_handle_name=name,
|
144
|
+
handle_name=handle_name,
|
123
145
|
path="/".join(paths),
|
124
|
-
method=method
|
125
|
-
method_pattern=
|
146
|
+
method=method,
|
147
|
+
method_pattern=pattern,
|
126
148
|
)
|
127
149
|
|
128
150
|
|
@@ -171,7 +193,7 @@ class CBV:
|
|
171
193
|
*,
|
172
194
|
cls: type[EndpointsClassInterfaceT],
|
173
195
|
path: str,
|
174
|
-
method:
|
196
|
+
method: RequestMethod,
|
175
197
|
method_name: str,
|
176
198
|
):
|
177
199
|
class_tags = list(cls.tags) if cls.tags else []
|
@@ -221,8 +243,7 @@ class CBV:
|
|
221
243
|
self,
|
222
244
|
*,
|
223
245
|
path: str | None = None,
|
224
|
-
methods: list[
|
225
|
-
| None = None,
|
246
|
+
methods: list[RequestMethod] | None = None,
|
226
247
|
tags: list[str | Enum] | None = None,
|
227
248
|
dependencies: list | None = None,
|
228
249
|
responses: list[Response] | None = None,
|
@@ -261,7 +282,7 @@ class CBV:
|
|
261
282
|
|
262
283
|
default_data = {}
|
263
284
|
for endpoint in iter_endpoints(n_cls):
|
264
|
-
default_data[endpoint.
|
285
|
+
default_data[endpoint.original_handle_name] = {}
|
265
286
|
|
266
287
|
self._state.setdefault(n_cls, default_data)
|
267
288
|
result = self._build_cls(n_cls)
|
@@ -361,15 +382,33 @@ class CBV:
|
|
361
382
|
|
362
383
|
decorator = self.__create_class_dependencies_injector(cls_)
|
363
384
|
|
364
|
-
|
385
|
+
def valid_method(
|
386
|
+
name: str, _handle: Callable
|
387
|
+
) -> None | list[_MethodInfo]:
|
388
|
+
if (cls_state := self._state.get(cls_)) and (
|
389
|
+
method_state := cls_state.get(name)
|
390
|
+
):
|
391
|
+
methods: list[RequestMethod] = (
|
392
|
+
method_state.get("methods") or []
|
393
|
+
)
|
394
|
+
result: list[_MethodInfo] = []
|
395
|
+
for i in methods:
|
396
|
+
method = Methods(i.lower())
|
397
|
+
result.append((method, METHOD_PATTERNS[method]))
|
398
|
+
return result
|
399
|
+
|
400
|
+
return None
|
401
|
+
|
402
|
+
for endpoint_info in iter_endpoints(cls, valid_method):
|
365
403
|
route = self.create_route(
|
366
404
|
cls=cast(type[EndpointsClassInterface], cls),
|
367
405
|
path=endpoint_info.path,
|
368
406
|
method=endpoint_info.method,
|
369
|
-
method_name=endpoint_info.
|
407
|
+
method_name=endpoint_info.original_handle_name,
|
370
408
|
)
|
371
|
-
method = getattr(instance, endpoint_info.
|
409
|
+
method = getattr(instance, endpoint_info.original_handle_name)
|
372
410
|
endpoint = decorator(method)
|
411
|
+
endpoint.__name__ = endpoint_info.handle_name
|
373
412
|
route(endpoint)
|
374
413
|
|
375
414
|
return cls
|
@@ -11,7 +11,7 @@ u_toolkit/object.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
11
11
|
u_toolkit/path.py,sha256=IkyIHcU9hKBCOZfF30FrKf4CfL-MH91fjeYF9EY7eos,128
|
12
12
|
u_toolkit/signature.py,sha256=-Q6n28PYBYYdd2OXBKESeVkL2rYpV6EaY3IVwQmzezQ,2161
|
13
13
|
u_toolkit/fastapi/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
14
|
-
u_toolkit/fastapi/cbv.py,sha256=
|
14
|
+
u_toolkit/fastapi/cbv.py,sha256=s8si0Oc7pE_4M8wX-911aEZw5TJ-4-MtTLQHN71htcU,12097
|
15
15
|
u_toolkit/fastapi/config.py,sha256=kGpokR9XXr1KxMA1GVKYkCdKwqIQAIwOJ-v6sGbqzAQ,267
|
16
16
|
u_toolkit/fastapi/exception.py,sha256=P9apEEQvbBMmffiHX57768gmemMeAy69-nb-1JQZAZE,4624
|
17
17
|
u_toolkit/fastapi/helpers.py,sha256=BCMMLxa1c6BMA_rKq-hCi0iyEjrR3Z5rPMeTvgaVJB0,447
|
@@ -30,7 +30,7 @@ u_toolkit/sqlalchemy/type_vars.py,sha256=m2VeV41CBIK_1QX3w2kgz-n556sILAGZ-Kaz3TD
|
|
30
30
|
u_toolkit/sqlalchemy/orm/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
31
31
|
u_toolkit/sqlalchemy/orm/fields.py,sha256=3zoYil23I6YLtc_59aHDt9w5l1NBTkePT9AfXI3DMiY,593
|
32
32
|
u_toolkit/sqlalchemy/orm/models.py,sha256=V8vf4ps3phAmwxyaFYK7pw8Igz7h097o4QBjKB0gwC8,705
|
33
|
-
u_toolkit-0.1.
|
34
|
-
u_toolkit-0.1.
|
35
|
-
u_toolkit-0.1.
|
36
|
-
u_toolkit-0.1.
|
33
|
+
u_toolkit-0.1.12.dist-info/METADATA,sha256=Vtf8jjzNczvmnfEM3I0ZRPW6EPYl9W7x5JbGERtj5Yg,366
|
34
|
+
u_toolkit-0.1.12.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
35
|
+
u_toolkit-0.1.12.dist-info/entry_points.txt,sha256=hTfAYCd5vvRiqgnJk2eBsoRIiIVB9pK8WZm3Q3jjKFU,45
|
36
|
+
u_toolkit-0.1.12.dist-info/RECORD,,
|
File without changes
|
File without changes
|