spakky-fastapi 0.7.19__py3-none-any.whl → 0.8.0__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.
@@ -3,9 +3,10 @@ from typing import Callable, Awaitable, TypeAlias
3
3
  from fastapi import Request
4
4
  from fastapi.responses import ORJSONResponse
5
5
  from pydantic import BaseModel
6
- from spakky_fastapi.error import InternalServerError, SpakkyFastAPIError
7
- from starlette.middleware.base import BaseHTTPMiddleware
6
+ from starlette.middleware.base import BaseHTTPMiddleware, DispatchFunction
8
7
  from starlette.responses import Response
8
+ from starlette.types import ASGIApp
9
+ from spakky_fastapi.error import InternalServerError, SpakkyFastAPIError
9
10
 
10
11
  Next: TypeAlias = Callable[[Request], Awaitable[Response]]
11
12
 
@@ -13,9 +14,21 @@ Next: TypeAlias = Callable[[Request], Awaitable[Response]]
13
14
  class ErrorResponse(BaseModel):
14
15
  message: str
15
16
  args: list[str]
17
+ traceback: str = ""
16
18
 
17
19
 
18
20
  class ErrorHandlingMiddleware(BaseHTTPMiddleware):
21
+ __debug: bool
22
+
23
+ def __init__(
24
+ self,
25
+ app: ASGIApp,
26
+ dispatch: DispatchFunction | None = None,
27
+ debug: bool = False,
28
+ ) -> None:
29
+ super().__init__(app, dispatch)
30
+ self.__debug = debug
31
+
19
32
  async def dispatch(self, request: Request, call_next: Next) -> Response:
20
33
  try:
21
34
  return await call_next(request)
@@ -34,6 +47,7 @@ class ErrorHandlingMiddleware(BaseHTTPMiddleware):
34
47
  content=ErrorResponse(
35
48
  message=error.message,
36
49
  args=[str(x) for x in error.args],
50
+ traceback=error.traceback if self.__debug else "",
37
51
  ).model_dump(),
38
52
  status_code=error.status_code,
39
53
  )
@@ -8,8 +8,11 @@ from fastapi.exceptions import FastAPIError
8
8
  from fastapi.utils import create_response_field # type: ignore
9
9
  from spakky.bean.interfaces.bean_container import IBeanContainer
10
10
  from spakky.bean.interfaces.bean_processor import IBeanPostProcessor
11
- from spakky_fastapi.routing import Route, WebSocketRoute
12
- from spakky_fastapi.stereotypes.api_controller import ApiController
11
+ from spakky_fastapi.stereotypes.api_controller import (
12
+ ApiController,
13
+ Route,
14
+ WebSocketRoute,
15
+ )
13
16
 
14
17
 
15
18
  class FastAPIBeanPostProcessor(IBeanPostProcessor):
@@ -32,6 +35,7 @@ class FastAPIBeanPostProcessor(IBeanPostProcessor):
32
35
  if route is None and websocket_route is None:
33
36
  continue
34
37
  if route is not None:
38
+ # pylint: disable=line-too-long
35
39
  self.__logger.info(
36
40
  f"[{type(self).__name__}] {route.methods!r} {controller.prefix}{route.path} -> {method.__qualname__}"
37
41
  )
@@ -50,6 +54,7 @@ class FastAPIBeanPostProcessor(IBeanPostProcessor):
50
54
  route.response_model = return_annotation
51
55
  router.add_api_route(endpoint=method, **asdict(route))
52
56
  if websocket_route is not None:
57
+ # pylint: disable=line-too-long
53
58
  self.__logger.info(
54
59
  f"[{type(self).__name__}] [WebSocket] {controller.prefix}{websocket_route.path} -> {method.__qualname__}"
55
60
  )
@@ -1,7 +1,506 @@
1
1
  from enum import Enum
2
+ from typing import Any, Callable, Sequence, TypeAlias
2
3
  from dataclasses import dataclass
3
4
 
5
+ from fastapi import Response, params
6
+ from fastapi.responses import JSONResponse
7
+ from fastapi.routing import APIRoute
8
+ from spakky.core.annotation import FunctionAnnotation
9
+ from spakky.core.types import FuncT
4
10
  from spakky.stereotype.controller import Controller
11
+ from starlette.routing import Route as StarletteRoute
12
+
13
+ SetIntStr: TypeAlias = set[int | str]
14
+ DictIntStrAny: TypeAlias = dict[int | str, Any]
15
+
16
+
17
+ class HTTPMethod(str, Enum):
18
+ GET = "GET"
19
+ POST = "POST"
20
+ PUT = "PUT"
21
+ PATCH = "PATCH"
22
+ DELETE = "DELETE"
23
+ HEAD = "HEAD"
24
+ OPTIONS = "OPTIONS"
25
+ TRACE = "TRACE"
26
+
27
+ def __repr__(self) -> str:
28
+ return self.value
29
+
30
+
31
+ @dataclass
32
+ class Route(FunctionAnnotation):
33
+ path: str
34
+ response_model: type[Any] | None = None
35
+ status_code: int | None = None
36
+ tags: list[str] | None = None
37
+ dependencies: Sequence[params.Depends] | None = None
38
+ summary: str | None = None
39
+ description: str | None = None
40
+ response_description: str = "Successful Response"
41
+ responses: dict[int | str, dict[str, Any]] | None = None
42
+ deprecated: bool | None = None
43
+ methods: set[HTTPMethod] | list[HTTPMethod] | None = None
44
+ operation_id: str | None = None
45
+ response_model_include: SetIntStr | DictIntStrAny | None = None
46
+ response_model_exclude: SetIntStr | DictIntStrAny | None = None
47
+ response_model_by_alias: bool = True
48
+ response_model_exclude_unset: bool = False
49
+ response_model_exclude_defaults: bool = False
50
+ response_model_exclude_none: bool = False
51
+ include_in_schema: bool = True
52
+ response_class: type[Response] = JSONResponse
53
+ name: str | None = None
54
+ route_class_override: type[APIRoute] | None = None
55
+ callbacks: list[StarletteRoute] | None = None
56
+ openapi_extra: dict[str, Any] | None = None
57
+
58
+
59
+ @dataclass
60
+ class WebSocketRoute(FunctionAnnotation):
61
+ path: str
62
+ name: str | None = None
63
+ dependencies: Sequence[params.Depends] | None = None
64
+
65
+
66
+ def route(
67
+ path: str,
68
+ response_model: type[Any] | None = None,
69
+ status_code: int | None = None,
70
+ tags: list[str] | None = None,
71
+ dependencies: Sequence[params.Depends] | None = None,
72
+ summary: str | None = None,
73
+ description: str | None = None,
74
+ response_description: str = "Successful Response",
75
+ responses: dict[int | str, dict[str, Any]] | None = None,
76
+ deprecated: bool | None = None,
77
+ methods: set[HTTPMethod] | list[HTTPMethod] | None = None,
78
+ operation_id: str | None = None,
79
+ response_model_include: SetIntStr | DictIntStrAny | None = None,
80
+ response_model_exclude: SetIntStr | DictIntStrAny | None = None,
81
+ response_model_by_alias: bool = True,
82
+ response_model_exclude_unset: bool = False,
83
+ response_model_exclude_defaults: bool = False,
84
+ response_model_exclude_none: bool = False,
85
+ include_in_schema: bool = True,
86
+ response_class: type[Response] = JSONResponse,
87
+ name: str | None = None,
88
+ route_class_override: type[APIRoute] | None = None,
89
+ callbacks: list[StarletteRoute] | None = None,
90
+ openapi_extra: dict[str, Any] | None = None,
91
+ ) -> Callable[[FuncT], FuncT]:
92
+ def wrapper(method: FuncT) -> FuncT:
93
+ return Route(
94
+ path=path,
95
+ response_model=response_model,
96
+ status_code=status_code,
97
+ tags=tags,
98
+ dependencies=dependencies,
99
+ summary=summary,
100
+ description=description,
101
+ response_description=response_description,
102
+ responses=responses,
103
+ deprecated=deprecated,
104
+ methods=methods,
105
+ operation_id=operation_id,
106
+ response_model_include=response_model_include,
107
+ response_model_exclude=response_model_exclude,
108
+ response_model_by_alias=response_model_by_alias,
109
+ response_model_exclude_unset=response_model_exclude_unset,
110
+ response_model_exclude_defaults=response_model_exclude_defaults,
111
+ response_model_exclude_none=response_model_exclude_none,
112
+ include_in_schema=include_in_schema,
113
+ response_class=response_class,
114
+ name=name,
115
+ route_class_override=route_class_override,
116
+ callbacks=callbacks,
117
+ openapi_extra=openapi_extra,
118
+ )(method)
119
+
120
+ return wrapper
121
+
122
+
123
+ def get(
124
+ path: str,
125
+ response_model: type[Any] | None = None,
126
+ status_code: int | None = None,
127
+ tags: list[str] | None = None,
128
+ dependencies: Sequence[params.Depends] | None = None,
129
+ summary: str | None = None,
130
+ description: str | None = None,
131
+ response_description: str = "Successful Response",
132
+ responses: dict[int | str, dict[str, Any]] | None = None,
133
+ deprecated: bool | None = None,
134
+ operation_id: str | None = None,
135
+ response_model_include: SetIntStr | DictIntStrAny | None = None,
136
+ response_model_exclude: SetIntStr | DictIntStrAny | None = None,
137
+ response_model_by_alias: bool = True,
138
+ response_model_exclude_unset: bool = False,
139
+ response_model_exclude_defaults: bool = False,
140
+ response_model_exclude_none: bool = False,
141
+ include_in_schema: bool = True,
142
+ response_class: type[Response] = JSONResponse,
143
+ name: str | None = None,
144
+ route_class_override: type[APIRoute] | None = None,
145
+ callbacks: list[StarletteRoute] | None = None,
146
+ openapi_extra: dict[str, Any] | None = None,
147
+ ) -> Callable[[FuncT], FuncT]:
148
+ return route(
149
+ path=path,
150
+ methods=[HTTPMethod.GET],
151
+ response_model=response_model,
152
+ status_code=status_code,
153
+ tags=tags,
154
+ dependencies=dependencies,
155
+ summary=summary,
156
+ description=description,
157
+ response_description=response_description,
158
+ responses=responses,
159
+ deprecated=deprecated,
160
+ operation_id=operation_id,
161
+ response_model_include=response_model_include,
162
+ response_model_exclude=response_model_exclude,
163
+ response_model_by_alias=response_model_by_alias,
164
+ response_model_exclude_unset=response_model_exclude_unset,
165
+ response_model_exclude_defaults=response_model_exclude_defaults,
166
+ response_model_exclude_none=response_model_exclude_none,
167
+ include_in_schema=include_in_schema,
168
+ response_class=response_class,
169
+ name=name,
170
+ route_class_override=route_class_override,
171
+ callbacks=callbacks,
172
+ openapi_extra=openapi_extra,
173
+ )
174
+
175
+
176
+ def post(
177
+ path: str,
178
+ response_model: type[Any] | None = None,
179
+ status_code: int | None = None,
180
+ tags: list[str] | None = None,
181
+ dependencies: Sequence[params.Depends] | None = None,
182
+ summary: str | None = None,
183
+ description: str | None = None,
184
+ response_description: str = "Successful Response",
185
+ responses: dict[int | str, dict[str, Any]] | None = None,
186
+ deprecated: bool | None = None,
187
+ operation_id: str | None = None,
188
+ response_model_include: SetIntStr | DictIntStrAny | None = None,
189
+ response_model_exclude: SetIntStr | DictIntStrAny | None = None,
190
+ response_model_by_alias: bool = True,
191
+ response_model_exclude_unset: bool = False,
192
+ response_model_exclude_defaults: bool = False,
193
+ response_model_exclude_none: bool = False,
194
+ include_in_schema: bool = True,
195
+ response_class: type[Response] = JSONResponse,
196
+ name: str | None = None,
197
+ route_class_override: type[APIRoute] | None = None,
198
+ callbacks: list[StarletteRoute] | None = None,
199
+ openapi_extra: dict[str, Any] | None = None,
200
+ ) -> Callable[[FuncT], FuncT]:
201
+ return route(
202
+ path=path,
203
+ methods=[HTTPMethod.POST],
204
+ response_model=response_model,
205
+ status_code=status_code,
206
+ tags=tags,
207
+ dependencies=dependencies,
208
+ summary=summary,
209
+ description=description,
210
+ response_description=response_description,
211
+ responses=responses,
212
+ deprecated=deprecated,
213
+ operation_id=operation_id,
214
+ response_model_include=response_model_include,
215
+ response_model_exclude=response_model_exclude,
216
+ response_model_by_alias=response_model_by_alias,
217
+ response_model_exclude_unset=response_model_exclude_unset,
218
+ response_model_exclude_defaults=response_model_exclude_defaults,
219
+ response_model_exclude_none=response_model_exclude_none,
220
+ include_in_schema=include_in_schema,
221
+ response_class=response_class,
222
+ name=name,
223
+ route_class_override=route_class_override,
224
+ callbacks=callbacks,
225
+ openapi_extra=openapi_extra,
226
+ )
227
+
228
+
229
+ def put(
230
+ path: str,
231
+ response_model: type[Any] | None = None,
232
+ status_code: int | None = None,
233
+ tags: list[str] | None = None,
234
+ dependencies: Sequence[params.Depends] | None = None,
235
+ summary: str | None = None,
236
+ description: str | None = None,
237
+ response_description: str = "Successful Response",
238
+ responses: dict[int | str, dict[str, Any]] | None = None,
239
+ deprecated: bool | None = None,
240
+ operation_id: str | None = None,
241
+ response_model_include: SetIntStr | DictIntStrAny | None = None,
242
+ response_model_exclude: SetIntStr | DictIntStrAny | None = None,
243
+ response_model_by_alias: bool = True,
244
+ response_model_exclude_unset: bool = False,
245
+ response_model_exclude_defaults: bool = False,
246
+ response_model_exclude_none: bool = False,
247
+ include_in_schema: bool = True,
248
+ response_class: type[Response] = JSONResponse,
249
+ name: str | None = None,
250
+ route_class_override: type[APIRoute] | None = None,
251
+ callbacks: list[StarletteRoute] | None = None,
252
+ openapi_extra: dict[str, Any] | None = None,
253
+ ) -> Callable[[FuncT], FuncT]:
254
+ return route(
255
+ path=path,
256
+ methods=[HTTPMethod.PUT],
257
+ response_model=response_model,
258
+ status_code=status_code,
259
+ tags=tags,
260
+ dependencies=dependencies,
261
+ summary=summary,
262
+ description=description,
263
+ response_description=response_description,
264
+ responses=responses,
265
+ deprecated=deprecated,
266
+ operation_id=operation_id,
267
+ response_model_include=response_model_include,
268
+ response_model_exclude=response_model_exclude,
269
+ response_model_by_alias=response_model_by_alias,
270
+ response_model_exclude_unset=response_model_exclude_unset,
271
+ response_model_exclude_defaults=response_model_exclude_defaults,
272
+ response_model_exclude_none=response_model_exclude_none,
273
+ include_in_schema=include_in_schema,
274
+ response_class=response_class,
275
+ name=name,
276
+ route_class_override=route_class_override,
277
+ callbacks=callbacks,
278
+ openapi_extra=openapi_extra,
279
+ )
280
+
281
+
282
+ def patch(
283
+ path: str,
284
+ response_model: type[Any] | None = None,
285
+ status_code: int | None = None,
286
+ tags: list[str] | None = None,
287
+ dependencies: Sequence[params.Depends] | None = None,
288
+ summary: str | None = None,
289
+ description: str | None = None,
290
+ response_description: str = "Successful Response",
291
+ responses: dict[int | str, dict[str, Any]] | None = None,
292
+ deprecated: bool | None = None,
293
+ operation_id: str | None = None,
294
+ response_model_include: SetIntStr | DictIntStrAny | None = None,
295
+ response_model_exclude: SetIntStr | DictIntStrAny | None = None,
296
+ response_model_by_alias: bool = True,
297
+ response_model_exclude_unset: bool = False,
298
+ response_model_exclude_defaults: bool = False,
299
+ response_model_exclude_none: bool = False,
300
+ include_in_schema: bool = True,
301
+ response_class: type[Response] = JSONResponse,
302
+ name: str | None = None,
303
+ route_class_override: type[APIRoute] | None = None,
304
+ callbacks: list[StarletteRoute] | None = None,
305
+ openapi_extra: dict[str, Any] | None = None,
306
+ ) -> Callable[[FuncT], FuncT]:
307
+ return route(
308
+ path=path,
309
+ methods=[HTTPMethod.PATCH],
310
+ response_model=response_model,
311
+ status_code=status_code,
312
+ tags=tags,
313
+ dependencies=dependencies,
314
+ summary=summary,
315
+ description=description,
316
+ response_description=response_description,
317
+ responses=responses,
318
+ deprecated=deprecated,
319
+ operation_id=operation_id,
320
+ response_model_include=response_model_include,
321
+ response_model_exclude=response_model_exclude,
322
+ response_model_by_alias=response_model_by_alias,
323
+ response_model_exclude_unset=response_model_exclude_unset,
324
+ response_model_exclude_defaults=response_model_exclude_defaults,
325
+ response_model_exclude_none=response_model_exclude_none,
326
+ include_in_schema=include_in_schema,
327
+ response_class=response_class,
328
+ name=name,
329
+ route_class_override=route_class_override,
330
+ callbacks=callbacks,
331
+ openapi_extra=openapi_extra,
332
+ )
333
+
334
+
335
+ def delete(
336
+ path: str,
337
+ response_model: type[Any] | None = None,
338
+ status_code: int | None = None,
339
+ tags: list[str] | None = None,
340
+ dependencies: Sequence[params.Depends] | None = None,
341
+ summary: str | None = None,
342
+ description: str | None = None,
343
+ response_description: str = "Successful Response",
344
+ responses: dict[int | str, dict[str, Any]] | None = None,
345
+ deprecated: bool | None = None,
346
+ operation_id: str | None = None,
347
+ response_model_include: SetIntStr | DictIntStrAny | None = None,
348
+ response_model_exclude: SetIntStr | DictIntStrAny | None = None,
349
+ response_model_by_alias: bool = True,
350
+ response_model_exclude_unset: bool = False,
351
+ response_model_exclude_defaults: bool = False,
352
+ response_model_exclude_none: bool = False,
353
+ include_in_schema: bool = True,
354
+ response_class: type[Response] = JSONResponse,
355
+ name: str | None = None,
356
+ route_class_override: type[APIRoute] | None = None,
357
+ callbacks: list[StarletteRoute] | None = None,
358
+ openapi_extra: dict[str, Any] | None = None,
359
+ ) -> Callable[[FuncT], FuncT]:
360
+ return route(
361
+ path=path,
362
+ methods=[HTTPMethod.DELETE],
363
+ response_model=response_model,
364
+ status_code=status_code,
365
+ tags=tags,
366
+ dependencies=dependencies,
367
+ summary=summary,
368
+ description=description,
369
+ response_description=response_description,
370
+ responses=responses,
371
+ deprecated=deprecated,
372
+ operation_id=operation_id,
373
+ response_model_include=response_model_include,
374
+ response_model_exclude=response_model_exclude,
375
+ response_model_by_alias=response_model_by_alias,
376
+ response_model_exclude_unset=response_model_exclude_unset,
377
+ response_model_exclude_defaults=response_model_exclude_defaults,
378
+ response_model_exclude_none=response_model_exclude_none,
379
+ include_in_schema=include_in_schema,
380
+ response_class=response_class,
381
+ name=name,
382
+ route_class_override=route_class_override,
383
+ callbacks=callbacks,
384
+ openapi_extra=openapi_extra,
385
+ )
386
+
387
+
388
+ def head(
389
+ path: str,
390
+ response_model: type[Any] | None = None,
391
+ status_code: int | None = None,
392
+ tags: list[str] | None = None,
393
+ dependencies: Sequence[params.Depends] | None = None,
394
+ summary: str | None = None,
395
+ description: str | None = None,
396
+ response_description: str = "Successful Response",
397
+ responses: dict[int | str, dict[str, Any]] | None = None,
398
+ deprecated: bool | None = None,
399
+ operation_id: str | None = None,
400
+ response_model_include: SetIntStr | DictIntStrAny | None = None,
401
+ response_model_exclude: SetIntStr | DictIntStrAny | None = None,
402
+ response_model_by_alias: bool = True,
403
+ response_model_exclude_unset: bool = False,
404
+ response_model_exclude_defaults: bool = False,
405
+ response_model_exclude_none: bool = False,
406
+ include_in_schema: bool = True,
407
+ response_class: type[Response] = JSONResponse,
408
+ name: str | None = None,
409
+ route_class_override: type[APIRoute] | None = None,
410
+ callbacks: list[StarletteRoute] | None = None,
411
+ openapi_extra: dict[str, Any] | None = None,
412
+ ) -> Callable[[FuncT], FuncT]:
413
+ return route(
414
+ path=path,
415
+ methods=[HTTPMethod.HEAD],
416
+ response_model=response_model,
417
+ status_code=status_code,
418
+ tags=tags,
419
+ dependencies=dependencies,
420
+ summary=summary,
421
+ description=description,
422
+ response_description=response_description,
423
+ responses=responses,
424
+ deprecated=deprecated,
425
+ operation_id=operation_id,
426
+ response_model_include=response_model_include,
427
+ response_model_exclude=response_model_exclude,
428
+ response_model_by_alias=response_model_by_alias,
429
+ response_model_exclude_unset=response_model_exclude_unset,
430
+ response_model_exclude_defaults=response_model_exclude_defaults,
431
+ response_model_exclude_none=response_model_exclude_none,
432
+ include_in_schema=include_in_schema,
433
+ response_class=response_class,
434
+ name=name,
435
+ route_class_override=route_class_override,
436
+ callbacks=callbacks,
437
+ openapi_extra=openapi_extra,
438
+ )
439
+
440
+
441
+ def options(
442
+ path: str,
443
+ response_model: type[Any] | None = None,
444
+ status_code: int | None = None,
445
+ tags: list[str] | None = None,
446
+ dependencies: Sequence[params.Depends] | None = None,
447
+ summary: str | None = None,
448
+ description: str | None = None,
449
+ response_description: str = "Successful Response",
450
+ responses: dict[int | str, dict[str, Any]] | None = None,
451
+ deprecated: bool | None = None,
452
+ operation_id: str | None = None,
453
+ response_model_include: SetIntStr | DictIntStrAny | None = None,
454
+ response_model_exclude: SetIntStr | DictIntStrAny | None = None,
455
+ response_model_by_alias: bool = True,
456
+ response_model_exclude_unset: bool = False,
457
+ response_model_exclude_defaults: bool = False,
458
+ response_model_exclude_none: bool = False,
459
+ include_in_schema: bool = True,
460
+ response_class: type[Response] = JSONResponse,
461
+ name: str | None = None,
462
+ route_class_override: type[APIRoute] | None = None,
463
+ callbacks: list[StarletteRoute] | None = None,
464
+ openapi_extra: dict[str, Any] | None = None,
465
+ ) -> Callable[[FuncT], FuncT]:
466
+ return route(
467
+ path=path,
468
+ methods=[HTTPMethod.OPTIONS],
469
+ response_model=response_model,
470
+ status_code=status_code,
471
+ tags=tags,
472
+ dependencies=dependencies,
473
+ summary=summary,
474
+ description=description,
475
+ response_description=response_description,
476
+ responses=responses,
477
+ deprecated=deprecated,
478
+ operation_id=operation_id,
479
+ response_model_include=response_model_include,
480
+ response_model_exclude=response_model_exclude,
481
+ response_model_by_alias=response_model_by_alias,
482
+ response_model_exclude_unset=response_model_exclude_unset,
483
+ response_model_exclude_defaults=response_model_exclude_defaults,
484
+ response_model_exclude_none=response_model_exclude_none,
485
+ include_in_schema=include_in_schema,
486
+ response_class=response_class,
487
+ name=name,
488
+ route_class_override=route_class_override,
489
+ callbacks=callbacks,
490
+ openapi_extra=openapi_extra,
491
+ )
492
+
493
+
494
+ def websocket(
495
+ path: str,
496
+ name: str | None = None,
497
+ dependencies: Sequence[params.Depends] | None = None,
498
+ ) -> Callable[[FuncT], FuncT]:
499
+ return WebSocketRoute(
500
+ path=path,
501
+ name=name,
502
+ dependencies=dependencies,
503
+ )
5
504
 
6
505
 
7
506
  @dataclass
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: spakky-fastapi
3
- Version: 0.7.19
3
+ Version: 0.8.0
4
4
  Summary: Highly abstracted Framework core to use DDD & DI/IoC & AOP & Etc...
5
5
  Author: Spakky
6
6
  Author-email: sejong418@icloud.com
@@ -11,7 +11,7 @@ Classifier: Programming Language :: Python :: 3.11
11
11
  Classifier: Programming Language :: Python :: 3.12
12
12
  Requires-Dist: fastapi (>=0.109.2,<0.110.0)
13
13
  Requires-Dist: orjson (>=3.9.15,<4.0.0)
14
- Requires-Dist: spakky-core (>=0.7.14)
14
+ Requires-Dist: spakky-core (>=0.10.1)
15
15
  Requires-Dist: websockets (>=12.0,<13.0)
16
16
  Description-Content-Type: text/markdown
17
17
 
@@ -0,0 +1,12 @@
1
+ spakky_fastapi/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
+ spakky_fastapi/error.py,sha256=SWyNZk1kxbTCiy-tLxB8saLpX5rBxwvy7q7JRCtNQV0,1124
3
+ spakky_fastapi/jwt_auth.py,sha256=Ug3DPEHQQn14gFb-j_o_NW0SUF-4NyfR67FLngjPCCQ,2822
4
+ spakky_fastapi/middlewares/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
+ spakky_fastapi/middlewares/error_handling.py,sha256=7tslQBKdh3y7oMNTyDbT4fp2WyR0Tt3SDy-VgHnVU40,1711
6
+ spakky_fastapi/post_processor.py,sha256=M2fGXhAFvCy1wHKnGxymfPiR7kuy5Iw85AhKsGUpD3o,2968
7
+ spakky_fastapi/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
8
+ spakky_fastapi/stereotypes/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
9
+ spakky_fastapi/stereotypes/api_controller.py,sha256=NM0gyTQfuHnENtvyfm5T9Y427gQdxdUcVYDzAXryF2M,19320
10
+ spakky_fastapi-0.8.0.dist-info/METADATA,sha256=pdrDLGNdyOWhi_cJNWs5el4gD9NUCH_X7RMrAt1re8A,1701
11
+ spakky_fastapi-0.8.0.dist-info/WHEEL,sha256=FMvqSimYX_P7y0a7UY-_Mc83r5zkBZsCYPm7Lr0Bsq4,88
12
+ spakky_fastapi-0.8.0.dist-info/RECORD,,
spakky_fastapi/routing.py DELETED
@@ -1,502 +0,0 @@
1
- from enum import Enum
2
- from typing import Any, Callable, Sequence, TypeAlias
3
- from dataclasses import dataclass
4
-
5
- from fastapi import Response, params
6
- from fastapi.responses import JSONResponse
7
- from fastapi.routing import APIRoute
8
- from spakky.core.annotation import FunctionAnnotation
9
- from spakky.core.types import FuncT
10
- from starlette.routing import Route as StarletteRoute
11
-
12
- SetIntStr: TypeAlias = set[int | str]
13
- DictIntStrAny: TypeAlias = dict[int | str, Any]
14
-
15
-
16
- class HTTPMethod(str, Enum):
17
- GET = "GET"
18
- POST = "POST"
19
- PUT = "PUT"
20
- PATCH = "PATCH"
21
- DELETE = "DELETE"
22
- HEAD = "HEAD"
23
- OPTIONS = "OPTIONS"
24
- TRACE = "TRACE"
25
-
26
- def __repr__(self) -> str:
27
- return self.value
28
-
29
-
30
- @dataclass
31
- class Route(FunctionAnnotation):
32
- path: str
33
- response_model: type[Any] | None = None
34
- status_code: int | None = None
35
- tags: list[str] | None = None
36
- dependencies: Sequence[params.Depends] | None = None
37
- summary: str | None = None
38
- description: str | None = None
39
- response_description: str = "Successful Response"
40
- responses: dict[int | str, dict[str, Any]] | None = None
41
- deprecated: bool | None = None
42
- methods: set[HTTPMethod] | list[HTTPMethod] | None = None
43
- operation_id: str | None = None
44
- response_model_include: SetIntStr | DictIntStrAny | None = None
45
- response_model_exclude: SetIntStr | DictIntStrAny | None = None
46
- response_model_by_alias: bool = True
47
- response_model_exclude_unset: bool = False
48
- response_model_exclude_defaults: bool = False
49
- response_model_exclude_none: bool = False
50
- include_in_schema: bool = True
51
- response_class: type[Response] = JSONResponse
52
- name: str | None = None
53
- route_class_override: type[APIRoute] | None = None
54
- callbacks: list[StarletteRoute] | None = None
55
- openapi_extra: dict[str, Any] | None = None
56
-
57
-
58
- @dataclass
59
- class WebSocketRoute(FunctionAnnotation):
60
- path: str
61
- name: str | None = None
62
- dependencies: Sequence[params.Depends] | None = None
63
-
64
-
65
- def route(
66
- path: str,
67
- response_model: type[Any] | None = None,
68
- status_code: int | None = None,
69
- tags: list[str] | None = None,
70
- dependencies: Sequence[params.Depends] | None = None,
71
- summary: str | None = None,
72
- description: str | None = None,
73
- response_description: str = "Successful Response",
74
- responses: dict[int | str, dict[str, Any]] | None = None,
75
- deprecated: bool | None = None,
76
- methods: set[HTTPMethod] | list[HTTPMethod] | None = None,
77
- operation_id: str | None = None,
78
- response_model_include: SetIntStr | DictIntStrAny | None = None,
79
- response_model_exclude: SetIntStr | DictIntStrAny | None = None,
80
- response_model_by_alias: bool = True,
81
- response_model_exclude_unset: bool = False,
82
- response_model_exclude_defaults: bool = False,
83
- response_model_exclude_none: bool = False,
84
- include_in_schema: bool = True,
85
- response_class: type[Response] = JSONResponse,
86
- name: str | None = None,
87
- route_class_override: type[APIRoute] | None = None,
88
- callbacks: list[StarletteRoute] | None = None,
89
- openapi_extra: dict[str, Any] | None = None,
90
- ) -> Callable[[FuncT], FuncT]:
91
- def wrapper(method: FuncT) -> FuncT:
92
- return Route(
93
- path=path,
94
- response_model=response_model,
95
- status_code=status_code,
96
- tags=tags,
97
- dependencies=dependencies,
98
- summary=summary,
99
- description=description,
100
- response_description=response_description,
101
- responses=responses,
102
- deprecated=deprecated,
103
- methods=methods,
104
- operation_id=operation_id,
105
- response_model_include=response_model_include,
106
- response_model_exclude=response_model_exclude,
107
- response_model_by_alias=response_model_by_alias,
108
- response_model_exclude_unset=response_model_exclude_unset,
109
- response_model_exclude_defaults=response_model_exclude_defaults,
110
- response_model_exclude_none=response_model_exclude_none,
111
- include_in_schema=include_in_schema,
112
- response_class=response_class,
113
- name=name,
114
- route_class_override=route_class_override,
115
- callbacks=callbacks,
116
- openapi_extra=openapi_extra,
117
- )(method)
118
-
119
- return wrapper
120
-
121
-
122
- def get(
123
- path: str,
124
- response_model: type[Any] | None = None,
125
- status_code: int | None = None,
126
- tags: list[str] | None = None,
127
- dependencies: Sequence[params.Depends] | None = None,
128
- summary: str | None = None,
129
- description: str | None = None,
130
- response_description: str = "Successful Response",
131
- responses: dict[int | str, dict[str, Any]] | None = None,
132
- deprecated: bool | None = None,
133
- operation_id: str | None = None,
134
- response_model_include: SetIntStr | DictIntStrAny | None = None,
135
- response_model_exclude: SetIntStr | DictIntStrAny | None = None,
136
- response_model_by_alias: bool = True,
137
- response_model_exclude_unset: bool = False,
138
- response_model_exclude_defaults: bool = False,
139
- response_model_exclude_none: bool = False,
140
- include_in_schema: bool = True,
141
- response_class: type[Response] = JSONResponse,
142
- name: str | None = None,
143
- route_class_override: type[APIRoute] | None = None,
144
- callbacks: list[StarletteRoute] | None = None,
145
- openapi_extra: dict[str, Any] | None = None,
146
- ) -> Callable[[FuncT], FuncT]:
147
- return route(
148
- path=path,
149
- methods=[HTTPMethod.GET],
150
- response_model=response_model,
151
- status_code=status_code,
152
- tags=tags,
153
- dependencies=dependencies,
154
- summary=summary,
155
- description=description,
156
- response_description=response_description,
157
- responses=responses,
158
- deprecated=deprecated,
159
- operation_id=operation_id,
160
- response_model_include=response_model_include,
161
- response_model_exclude=response_model_exclude,
162
- response_model_by_alias=response_model_by_alias,
163
- response_model_exclude_unset=response_model_exclude_unset,
164
- response_model_exclude_defaults=response_model_exclude_defaults,
165
- response_model_exclude_none=response_model_exclude_none,
166
- include_in_schema=include_in_schema,
167
- response_class=response_class,
168
- name=name,
169
- route_class_override=route_class_override,
170
- callbacks=callbacks,
171
- openapi_extra=openapi_extra,
172
- )
173
-
174
-
175
- def post(
176
- path: str,
177
- response_model: type[Any] | None = None,
178
- status_code: int | None = None,
179
- tags: list[str] | None = None,
180
- dependencies: Sequence[params.Depends] | None = None,
181
- summary: str | None = None,
182
- description: str | None = None,
183
- response_description: str = "Successful Response",
184
- responses: dict[int | str, dict[str, Any]] | None = None,
185
- deprecated: bool | None = None,
186
- operation_id: str | None = None,
187
- response_model_include: SetIntStr | DictIntStrAny | None = None,
188
- response_model_exclude: SetIntStr | DictIntStrAny | None = None,
189
- response_model_by_alias: bool = True,
190
- response_model_exclude_unset: bool = False,
191
- response_model_exclude_defaults: bool = False,
192
- response_model_exclude_none: bool = False,
193
- include_in_schema: bool = True,
194
- response_class: type[Response] = JSONResponse,
195
- name: str | None = None,
196
- route_class_override: type[APIRoute] | None = None,
197
- callbacks: list[StarletteRoute] | None = None,
198
- openapi_extra: dict[str, Any] | None = None,
199
- ) -> Callable[[FuncT], FuncT]:
200
- return route(
201
- path=path,
202
- methods=[HTTPMethod.POST],
203
- response_model=response_model,
204
- status_code=status_code,
205
- tags=tags,
206
- dependencies=dependencies,
207
- summary=summary,
208
- description=description,
209
- response_description=response_description,
210
- responses=responses,
211
- deprecated=deprecated,
212
- operation_id=operation_id,
213
- response_model_include=response_model_include,
214
- response_model_exclude=response_model_exclude,
215
- response_model_by_alias=response_model_by_alias,
216
- response_model_exclude_unset=response_model_exclude_unset,
217
- response_model_exclude_defaults=response_model_exclude_defaults,
218
- response_model_exclude_none=response_model_exclude_none,
219
- include_in_schema=include_in_schema,
220
- response_class=response_class,
221
- name=name,
222
- route_class_override=route_class_override,
223
- callbacks=callbacks,
224
- openapi_extra=openapi_extra,
225
- )
226
-
227
-
228
- def put(
229
- path: str,
230
- response_model: type[Any] | None = None,
231
- status_code: int | None = None,
232
- tags: list[str] | None = None,
233
- dependencies: Sequence[params.Depends] | None = None,
234
- summary: str | None = None,
235
- description: str | None = None,
236
- response_description: str = "Successful Response",
237
- responses: dict[int | str, dict[str, Any]] | None = None,
238
- deprecated: bool | None = None,
239
- operation_id: str | None = None,
240
- response_model_include: SetIntStr | DictIntStrAny | None = None,
241
- response_model_exclude: SetIntStr | DictIntStrAny | None = None,
242
- response_model_by_alias: bool = True,
243
- response_model_exclude_unset: bool = False,
244
- response_model_exclude_defaults: bool = False,
245
- response_model_exclude_none: bool = False,
246
- include_in_schema: bool = True,
247
- response_class: type[Response] = JSONResponse,
248
- name: str | None = None,
249
- route_class_override: type[APIRoute] | None = None,
250
- callbacks: list[StarletteRoute] | None = None,
251
- openapi_extra: dict[str, Any] | None = None,
252
- ) -> Callable[[FuncT], FuncT]:
253
- return route(
254
- path=path,
255
- methods=[HTTPMethod.PUT],
256
- response_model=response_model,
257
- status_code=status_code,
258
- tags=tags,
259
- dependencies=dependencies,
260
- summary=summary,
261
- description=description,
262
- response_description=response_description,
263
- responses=responses,
264
- deprecated=deprecated,
265
- operation_id=operation_id,
266
- response_model_include=response_model_include,
267
- response_model_exclude=response_model_exclude,
268
- response_model_by_alias=response_model_by_alias,
269
- response_model_exclude_unset=response_model_exclude_unset,
270
- response_model_exclude_defaults=response_model_exclude_defaults,
271
- response_model_exclude_none=response_model_exclude_none,
272
- include_in_schema=include_in_schema,
273
- response_class=response_class,
274
- name=name,
275
- route_class_override=route_class_override,
276
- callbacks=callbacks,
277
- openapi_extra=openapi_extra,
278
- )
279
-
280
-
281
- def patch(
282
- path: str,
283
- response_model: type[Any] | None = None,
284
- status_code: int | None = None,
285
- tags: list[str] | None = None,
286
- dependencies: Sequence[params.Depends] | None = None,
287
- summary: str | None = None,
288
- description: str | None = None,
289
- response_description: str = "Successful Response",
290
- responses: dict[int | str, dict[str, Any]] | None = None,
291
- deprecated: bool | None = None,
292
- operation_id: str | None = None,
293
- response_model_include: SetIntStr | DictIntStrAny | None = None,
294
- response_model_exclude: SetIntStr | DictIntStrAny | None = None,
295
- response_model_by_alias: bool = True,
296
- response_model_exclude_unset: bool = False,
297
- response_model_exclude_defaults: bool = False,
298
- response_model_exclude_none: bool = False,
299
- include_in_schema: bool = True,
300
- response_class: type[Response] = JSONResponse,
301
- name: str | None = None,
302
- route_class_override: type[APIRoute] | None = None,
303
- callbacks: list[StarletteRoute] | None = None,
304
- openapi_extra: dict[str, Any] | None = None,
305
- ) -> Callable[[FuncT], FuncT]:
306
- return route(
307
- path=path,
308
- methods=[HTTPMethod.PATCH],
309
- response_model=response_model,
310
- status_code=status_code,
311
- tags=tags,
312
- dependencies=dependencies,
313
- summary=summary,
314
- description=description,
315
- response_description=response_description,
316
- responses=responses,
317
- deprecated=deprecated,
318
- operation_id=operation_id,
319
- response_model_include=response_model_include,
320
- response_model_exclude=response_model_exclude,
321
- response_model_by_alias=response_model_by_alias,
322
- response_model_exclude_unset=response_model_exclude_unset,
323
- response_model_exclude_defaults=response_model_exclude_defaults,
324
- response_model_exclude_none=response_model_exclude_none,
325
- include_in_schema=include_in_schema,
326
- response_class=response_class,
327
- name=name,
328
- route_class_override=route_class_override,
329
- callbacks=callbacks,
330
- openapi_extra=openapi_extra,
331
- )
332
-
333
-
334
- def delete(
335
- path: str,
336
- response_model: type[Any] | None = None,
337
- status_code: int | None = None,
338
- tags: list[str] | None = None,
339
- dependencies: Sequence[params.Depends] | None = None,
340
- summary: str | None = None,
341
- description: str | None = None,
342
- response_description: str = "Successful Response",
343
- responses: dict[int | str, dict[str, Any]] | None = None,
344
- deprecated: bool | None = None,
345
- operation_id: str | None = None,
346
- response_model_include: SetIntStr | DictIntStrAny | None = None,
347
- response_model_exclude: SetIntStr | DictIntStrAny | None = None,
348
- response_model_by_alias: bool = True,
349
- response_model_exclude_unset: bool = False,
350
- response_model_exclude_defaults: bool = False,
351
- response_model_exclude_none: bool = False,
352
- include_in_schema: bool = True,
353
- response_class: type[Response] = JSONResponse,
354
- name: str | None = None,
355
- route_class_override: type[APIRoute] | None = None,
356
- callbacks: list[StarletteRoute] | None = None,
357
- openapi_extra: dict[str, Any] | None = None,
358
- ) -> Callable[[FuncT], FuncT]:
359
- return route(
360
- path=path,
361
- methods=[HTTPMethod.DELETE],
362
- response_model=response_model,
363
- status_code=status_code,
364
- tags=tags,
365
- dependencies=dependencies,
366
- summary=summary,
367
- description=description,
368
- response_description=response_description,
369
- responses=responses,
370
- deprecated=deprecated,
371
- operation_id=operation_id,
372
- response_model_include=response_model_include,
373
- response_model_exclude=response_model_exclude,
374
- response_model_by_alias=response_model_by_alias,
375
- response_model_exclude_unset=response_model_exclude_unset,
376
- response_model_exclude_defaults=response_model_exclude_defaults,
377
- response_model_exclude_none=response_model_exclude_none,
378
- include_in_schema=include_in_schema,
379
- response_class=response_class,
380
- name=name,
381
- route_class_override=route_class_override,
382
- callbacks=callbacks,
383
- openapi_extra=openapi_extra,
384
- )
385
-
386
-
387
- def head(
388
- path: str,
389
- response_model: type[Any] | None = None,
390
- status_code: int | None = None,
391
- tags: list[str] | None = None,
392
- dependencies: Sequence[params.Depends] | None = None,
393
- summary: str | None = None,
394
- description: str | None = None,
395
- response_description: str = "Successful Response",
396
- responses: dict[int | str, dict[str, Any]] | None = None,
397
- deprecated: bool | None = None,
398
- operation_id: str | None = None,
399
- response_model_include: SetIntStr | DictIntStrAny | None = None,
400
- response_model_exclude: SetIntStr | DictIntStrAny | None = None,
401
- response_model_by_alias: bool = True,
402
- response_model_exclude_unset: bool = False,
403
- response_model_exclude_defaults: bool = False,
404
- response_model_exclude_none: bool = False,
405
- include_in_schema: bool = True,
406
- response_class: type[Response] = JSONResponse,
407
- name: str | None = None,
408
- route_class_override: type[APIRoute] | None = None,
409
- callbacks: list[StarletteRoute] | None = None,
410
- openapi_extra: dict[str, Any] | None = None,
411
- ) -> Callable[[FuncT], FuncT]:
412
- return route(
413
- path=path,
414
- methods=[HTTPMethod.HEAD],
415
- response_model=response_model,
416
- status_code=status_code,
417
- tags=tags,
418
- dependencies=dependencies,
419
- summary=summary,
420
- description=description,
421
- response_description=response_description,
422
- responses=responses,
423
- deprecated=deprecated,
424
- operation_id=operation_id,
425
- response_model_include=response_model_include,
426
- response_model_exclude=response_model_exclude,
427
- response_model_by_alias=response_model_by_alias,
428
- response_model_exclude_unset=response_model_exclude_unset,
429
- response_model_exclude_defaults=response_model_exclude_defaults,
430
- response_model_exclude_none=response_model_exclude_none,
431
- include_in_schema=include_in_schema,
432
- response_class=response_class,
433
- name=name,
434
- route_class_override=route_class_override,
435
- callbacks=callbacks,
436
- openapi_extra=openapi_extra,
437
- )
438
-
439
-
440
- def options(
441
- path: str,
442
- response_model: type[Any] | None = None,
443
- status_code: int | None = None,
444
- tags: list[str] | None = None,
445
- dependencies: Sequence[params.Depends] | None = None,
446
- summary: str | None = None,
447
- description: str | None = None,
448
- response_description: str = "Successful Response",
449
- responses: dict[int | str, dict[str, Any]] | None = None,
450
- deprecated: bool | None = None,
451
- operation_id: str | None = None,
452
- response_model_include: SetIntStr | DictIntStrAny | None = None,
453
- response_model_exclude: SetIntStr | DictIntStrAny | None = None,
454
- response_model_by_alias: bool = True,
455
- response_model_exclude_unset: bool = False,
456
- response_model_exclude_defaults: bool = False,
457
- response_model_exclude_none: bool = False,
458
- include_in_schema: bool = True,
459
- response_class: type[Response] = JSONResponse,
460
- name: str | None = None,
461
- route_class_override: type[APIRoute] | None = None,
462
- callbacks: list[StarletteRoute] | None = None,
463
- openapi_extra: dict[str, Any] | None = None,
464
- ) -> Callable[[FuncT], FuncT]:
465
- return route(
466
- path=path,
467
- methods=[HTTPMethod.OPTIONS],
468
- response_model=response_model,
469
- status_code=status_code,
470
- tags=tags,
471
- dependencies=dependencies,
472
- summary=summary,
473
- description=description,
474
- response_description=response_description,
475
- responses=responses,
476
- deprecated=deprecated,
477
- operation_id=operation_id,
478
- response_model_include=response_model_include,
479
- response_model_exclude=response_model_exclude,
480
- response_model_by_alias=response_model_by_alias,
481
- response_model_exclude_unset=response_model_exclude_unset,
482
- response_model_exclude_defaults=response_model_exclude_defaults,
483
- response_model_exclude_none=response_model_exclude_none,
484
- include_in_schema=include_in_schema,
485
- response_class=response_class,
486
- name=name,
487
- route_class_override=route_class_override,
488
- callbacks=callbacks,
489
- openapi_extra=openapi_extra,
490
- )
491
-
492
-
493
- def websocket(
494
- path: str,
495
- name: str | None = None,
496
- dependencies: Sequence[params.Depends] | None = None,
497
- ) -> Callable[[FuncT], FuncT]:
498
- return WebSocketRoute(
499
- path=path,
500
- name=name,
501
- dependencies=dependencies,
502
- )
@@ -1,13 +0,0 @@
1
- spakky_fastapi/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
- spakky_fastapi/error.py,sha256=SWyNZk1kxbTCiy-tLxB8saLpX5rBxwvy7q7JRCtNQV0,1124
3
- spakky_fastapi/jwt_auth.py,sha256=Ug3DPEHQQn14gFb-j_o_NW0SUF-4NyfR67FLngjPCCQ,2822
4
- spakky_fastapi/middlewares/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
- spakky_fastapi/middlewares/error_handling.py,sha256=w_zy4PtEdGkFNN79AHh7TfwWUGSQ1JFNvPo3Dy8ojDM,1325
6
- spakky_fastapi/post_processor.py,sha256=33czA6PLYzNxnwQ5dKz0fXjpM_7kyMf9kaY88b_GoCI,2889
7
- spakky_fastapi/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
8
- spakky_fastapi/routing.py,sha256=3OhnnDIzaDeNhuIMWpPG17--98ti6LsgdfENsWr332g,19181
9
- spakky_fastapi/stereotypes/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10
- spakky_fastapi/stereotypes/api_controller.py,sha256=hLeIYM-olZHwvFZkd1joQ-5-OQAiZXznFu4CEhrcskk,196
11
- spakky_fastapi-0.7.19.dist-info/METADATA,sha256=Epf3M5LlqNrHnnwrv0UDDnIuSKW4wRqo11C91P2BS38,1702
12
- spakky_fastapi-0.7.19.dist-info/WHEEL,sha256=FMvqSimYX_P7y0a7UY-_Mc83r5zkBZsCYPm7Lr0Bsq4,88
13
- spakky_fastapi-0.7.19.dist-info/RECORD,,