u-toolkit 0.1.14__py3-none-any.whl → 0.1.17__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/decorators.py +13 -4
- u_toolkit/fastapi/cbv.py +47 -27
- {u_toolkit-0.1.14.dist-info → u_toolkit-0.1.17.dist-info}/METADATA +1 -1
- {u_toolkit-0.1.14.dist-info → u_toolkit-0.1.17.dist-info}/RECORD +6 -6
- {u_toolkit-0.1.14.dist-info → u_toolkit-0.1.17.dist-info}/WHEEL +0 -0
- {u_toolkit-0.1.14.dist-info → u_toolkit-0.1.17.dist-info}/entry_points.txt +0 -0
u_toolkit/decorators.py
CHANGED
@@ -53,19 +53,25 @@ def define_method_handler(
|
|
53
53
|
|
54
54
|
_P = ParamSpec("_P")
|
55
55
|
|
56
|
+
_T2 = TypeVar("_T2")
|
57
|
+
|
56
58
|
|
57
59
|
def create_decorator(
|
58
|
-
handle: Callable[_P] | None = None,
|
60
|
+
handle: Callable[_P, _T2] | None = None,
|
61
|
+
use_handle_return: bool | None = None,
|
59
62
|
):
|
60
63
|
def decorator(fn: Callable[_P, _T]):
|
61
64
|
if inspect.iscoroutinefunction(fn):
|
62
65
|
|
63
66
|
@wraps(fn)
|
64
67
|
async def async_wrapper(*args, **kwargs):
|
68
|
+
handle_result = None
|
65
69
|
if inspect.iscoroutinefunction(handle):
|
66
|
-
await handle(*args, **kwargs)
|
70
|
+
handle_result = await handle(*args, **kwargs)
|
67
71
|
elif handle:
|
68
|
-
handle(*args, **kwargs)
|
72
|
+
handle_result = handle(*args, **kwargs)
|
73
|
+
if use_handle_return:
|
74
|
+
return handle_result
|
69
75
|
return await fn(*args, **kwargs)
|
70
76
|
|
71
77
|
return async_wrapper
|
@@ -73,7 +79,10 @@ def create_decorator(
|
|
73
79
|
@wraps(fn)
|
74
80
|
def wrapper(*args: _P.args, **kwargs: _P.kwargs):
|
75
81
|
if handle:
|
76
|
-
handle(*args, **kwargs)
|
82
|
+
handle_result = handle(*args, **kwargs)
|
83
|
+
if use_handle_return:
|
84
|
+
return handle_result
|
85
|
+
|
77
86
|
return fn(*args, **kwargs)
|
78
87
|
|
79
88
|
return wrapper
|
u_toolkit/fastapi/cbv.py
CHANGED
@@ -163,21 +163,31 @@ class CBVRoutesInfo(TypedDict):
|
|
163
163
|
deprecated: NotRequired[bool | None]
|
164
164
|
|
165
165
|
|
166
|
+
CBVRoutesInfoT = TypeVar("CBVRoutesInfoT", bound=CBVRoutesInfo)
|
167
|
+
|
168
|
+
|
166
169
|
class CBVRouteInfo(CBVRoutesInfo, Generic[_T]):
|
167
170
|
methods: NotRequired[list[RequestMethod] | None]
|
168
171
|
response_model: NotRequired[type[_T] | None]
|
169
172
|
status: NotRequired[int | None]
|
173
|
+
summary: NotRequired[str | None]
|
174
|
+
description: NotRequired[str | None]
|
175
|
+
name: NotRequired[str | None]
|
170
176
|
|
171
177
|
|
172
|
-
class CBV:
|
178
|
+
class CBV(Generic[CBVRoutesInfoT]):
|
173
179
|
def __init__(self, router: APIRouter | None = None) -> None:
|
174
180
|
self.router = router or APIRouter()
|
175
181
|
|
176
|
-
self.
|
177
|
-
self.
|
178
|
-
type,
|
182
|
+
self.state: dict[type, dict[_FnName, CBVRouteInfo]] = {}
|
183
|
+
self.routes_extra: dict[
|
184
|
+
type,
|
185
|
+
tuple[
|
186
|
+
CBVRoutesInfoT | None,
|
187
|
+
Callable[[type[_T]], _T] | None, # type: ignore
|
188
|
+
],
|
179
189
|
] = {}
|
180
|
-
self.
|
190
|
+
self.initialed_state: dict[type[_T], _T] = {} # type: ignore
|
181
191
|
|
182
192
|
def create_route(
|
183
193
|
self,
|
@@ -187,41 +197,44 @@ class CBV:
|
|
187
197
|
method: RequestMethod,
|
188
198
|
method_name: str,
|
189
199
|
):
|
190
|
-
class_routes_info = self.
|
200
|
+
class_routes_info = self.routes_extra[cls][0] or {}
|
191
201
|
|
192
202
|
class_tags = class_routes_info.get("tags") or []
|
193
203
|
endpoint_tags: list[str | Enum] = (
|
194
|
-
self.
|
204
|
+
self.state[cls][method_name].get("tags") or []
|
195
205
|
)
|
196
206
|
tags = class_tags + endpoint_tags
|
197
207
|
|
198
208
|
class_dependencies = class_routes_info.get("dependencies") or []
|
199
209
|
endpoint_dependencies = (
|
200
|
-
self.
|
210
|
+
self.state[cls][method_name].get("dependencies") or []
|
201
211
|
)
|
202
212
|
dependencies = class_dependencies + endpoint_dependencies
|
203
213
|
|
204
214
|
class_responses = class_routes_info.get("responses") or []
|
205
215
|
endpoint_responses = (
|
206
|
-
self.
|
216
|
+
self.state[cls][method_name].get("responses") or []
|
207
217
|
)
|
208
218
|
responses = build_responses(*class_responses, *endpoint_responses)
|
209
219
|
|
210
|
-
status_code = self.
|
220
|
+
status_code = self.state[cls][method_name].get("status")
|
211
221
|
|
212
|
-
deprecated = self.
|
222
|
+
deprecated = self.state[cls][method_name].get(
|
213
223
|
"deprecated", class_routes_info.get("deprecated")
|
214
224
|
)
|
215
225
|
|
216
|
-
response_model = self.
|
226
|
+
response_model = self.state[cls][method_name].get("response_model")
|
217
227
|
|
218
228
|
endpoint_methods = [
|
219
229
|
i.upper()
|
220
|
-
for i in (self.
|
230
|
+
for i in (self.state[cls][method_name].get("methods") or [method])
|
221
231
|
]
|
222
232
|
|
223
|
-
path = self.
|
233
|
+
path = self.state[cls][method_name].get("path") or path
|
224
234
|
|
235
|
+
summary = self.state[cls][method_name].get("summary")
|
236
|
+
description = self.state[cls][method_name].get("description")
|
237
|
+
name = self.state[cls][method_name].get("name")
|
225
238
|
return self.router.api_route(
|
226
239
|
path,
|
227
240
|
methods=endpoint_methods,
|
@@ -231,9 +244,12 @@ class CBV:
|
|
231
244
|
responses=responses,
|
232
245
|
status_code=status_code,
|
233
246
|
deprecated=deprecated,
|
247
|
+
summary=summary,
|
248
|
+
description=description,
|
249
|
+
name=name,
|
234
250
|
)
|
235
251
|
|
236
|
-
def info(
|
252
|
+
def info( # noqa: PLR0913
|
237
253
|
self,
|
238
254
|
*,
|
239
255
|
path: str | None = None,
|
@@ -242,10 +258,13 @@ class CBV:
|
|
242
258
|
dependencies: list | None = None,
|
243
259
|
responses: list[Response] | None = None,
|
244
260
|
response_model: type[_T] | None = None,
|
261
|
+
summary: str | None = None,
|
262
|
+
description: str | None = None,
|
263
|
+
name: str | None = None,
|
245
264
|
status: int | None = None,
|
246
265
|
deprecated: bool | None = None,
|
247
266
|
):
|
248
|
-
state = self.
|
267
|
+
state = self.state
|
249
268
|
initial_state = self._initial_state
|
250
269
|
data = CBVRouteInfo(
|
251
270
|
path=path,
|
@@ -256,6 +275,9 @@ class CBV:
|
|
256
275
|
response_model=response_model,
|
257
276
|
status=status,
|
258
277
|
deprecated=deprecated,
|
278
|
+
summary=summary,
|
279
|
+
description=description,
|
280
|
+
name=name,
|
259
281
|
)
|
260
282
|
|
261
283
|
def handle(params: DefineMethodParams):
|
@@ -268,22 +290,20 @@ class CBV:
|
|
268
290
|
return define_method_handler(handle)
|
269
291
|
|
270
292
|
def _initial_state(self, cls: type[_T]) -> _T:
|
271
|
-
if result := self.
|
293
|
+
if result := self.initialed_state.get(cls):
|
272
294
|
return cast(_T, result)
|
273
295
|
|
274
296
|
default_data = {}
|
275
297
|
for endpoint in iter_endpoints(cls):
|
276
298
|
default_data[endpoint.original_handle_name] = {}
|
277
299
|
|
278
|
-
self.
|
300
|
+
self.state.setdefault(cls, default_data)
|
279
301
|
result = self._build_cls(cls)
|
280
|
-
self.
|
302
|
+
self.initialed_state[cls] = result
|
281
303
|
return result
|
282
304
|
|
283
305
|
def _build_cls(self, cls: type[_T]) -> _T:
|
284
|
-
if cls in self.
|
285
|
-
build := self._cls_routes_extra[cls][1]
|
286
|
-
):
|
306
|
+
if cls in self.routes_extra and (build := self.routes_extra[cls][1]):
|
287
307
|
return build(cls) # type: ignore
|
288
308
|
return cls()
|
289
309
|
|
@@ -366,24 +386,24 @@ class CBV:
|
|
366
386
|
def __call__(
|
367
387
|
self,
|
368
388
|
*,
|
369
|
-
info:
|
389
|
+
info: CBVRoutesInfoT | None = None,
|
370
390
|
build: Callable[[type[_T]], _T] | None = None,
|
371
391
|
) -> Callable[[type[_T]], type[_T]]: ...
|
372
392
|
|
373
393
|
def __call__(self, *args, **kwargs):
|
374
|
-
info
|
394
|
+
info = None
|
375
395
|
build: Callable | None = None
|
376
396
|
|
377
397
|
def decorator(cls: type[_T]) -> type[_T]:
|
378
398
|
instance = self._initial_state(cls)
|
379
|
-
self.
|
399
|
+
self.routes_extra[cls] = info, build
|
380
400
|
|
381
401
|
decorator = self.__create_class_dependencies_injector(cls)
|
382
402
|
|
383
403
|
def valid_method(
|
384
404
|
name: str, _handle: Callable
|
385
405
|
) -> None | list[_MethodInfo]:
|
386
|
-
if (cls_state := self.
|
406
|
+
if (cls_state := self.state.get(cls)) and (
|
387
407
|
method_state := cls_state.get(name)
|
388
408
|
):
|
389
409
|
methods: list[RequestMethod] = (
|
@@ -414,7 +434,7 @@ class CBV:
|
|
414
434
|
if args:
|
415
435
|
return decorator(args[0])
|
416
436
|
|
417
|
-
info
|
437
|
+
info = kwargs.get("info") or None
|
418
438
|
build = kwargs.get("build")
|
419
439
|
|
420
440
|
return decorator
|
@@ -1,7 +1,7 @@
|
|
1
1
|
u_toolkit/__init__.py,sha256=7f_bFg1UERA4gyh3HjCAjOZo2cBUgElpwgX5x-Xk2WA,238
|
2
2
|
u_toolkit/alias_generators.py,sha256=KmPL1ViGJjptONffZUAX4ENvkldrwDylm_Ly5RYE8b4,963
|
3
3
|
u_toolkit/datetime.py,sha256=GOG0xa6yKeqvFXJkImK5Pt7wsPXnHMlNKju8deniGJ4,644
|
4
|
-
u_toolkit/decorators.py,sha256=
|
4
|
+
u_toolkit/decorators.py,sha256=rBZfXtWVfja6YMDqF9izjAiabRVyp4pAWOlwnN0HkUw,2396
|
5
5
|
u_toolkit/enum.py,sha256=2yWmK8V1q0P5S3ltBED-TF2H09BmRbsBuqu3Th3G1NE,862
|
6
6
|
u_toolkit/function.py,sha256=GAE6TIm5jpemUiNUPjzk7pIHrxwSSX7sHl1V5E735dE,252
|
7
7
|
u_toolkit/helpers.py,sha256=K3FCz93K1nT4o7gWKVpMKy3k3BnirTPCSb8F8EFUrWk,112
|
@@ -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=vRYGeopzduO7Gmf5O5oz76zGOYqFtD8aGAe1oCcK8R4,12910
|
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.17.dist-info/METADATA,sha256=uQ1VONPPf54w3xIyljJ9-j8Mz3YMQdes1CksSF26ZB8,366
|
34
|
+
u_toolkit-0.1.17.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
35
|
+
u_toolkit-0.1.17.dist-info/entry_points.txt,sha256=hTfAYCd5vvRiqgnJk2eBsoRIiIVB9pK8WZm3Q3jjKFU,45
|
36
|
+
u_toolkit-0.1.17.dist-info/RECORD,,
|
File without changes
|
File without changes
|