qena-shared-lib 0.1.17__py3-none-any.whl → 0.1.19__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.
Files changed (46) hide show
  1. qena_shared_lib/__init__.py +20 -2
  2. qena_shared_lib/alias.py +27 -0
  3. qena_shared_lib/application.py +4 -4
  4. qena_shared_lib/background.py +9 -7
  5. qena_shared_lib/cache.py +61 -0
  6. qena_shared_lib/enums.py +8 -0
  7. qena_shared_lib/eventbus.py +373 -0
  8. qena_shared_lib/exception_handling.py +409 -0
  9. qena_shared_lib/exceptions.py +167 -57
  10. qena_shared_lib/http/__init__.py +110 -0
  11. qena_shared_lib/{http.py → http/_base.py} +36 -36
  12. qena_shared_lib/http/_exception_handlers.py +202 -0
  13. qena_shared_lib/http/_request.py +24 -0
  14. qena_shared_lib/http/_response.py +24 -0
  15. qena_shared_lib/kafka/__init__.py +21 -0
  16. qena_shared_lib/kafka/_base.py +233 -0
  17. qena_shared_lib/kafka/_consumer.py +597 -0
  18. qena_shared_lib/kafka/_exception_handlers.py +124 -0
  19. qena_shared_lib/kafka/_producer.py +133 -0
  20. qena_shared_lib/logging.py +17 -13
  21. qena_shared_lib/mongodb.py +575 -0
  22. qena_shared_lib/rabbitmq/__init__.py +6 -6
  23. qena_shared_lib/rabbitmq/_base.py +68 -132
  24. qena_shared_lib/rabbitmq/_channel.py +2 -4
  25. qena_shared_lib/rabbitmq/_exception_handlers.py +69 -142
  26. qena_shared_lib/rabbitmq/_listener.py +245 -180
  27. qena_shared_lib/rabbitmq/_publisher.py +5 -5
  28. qena_shared_lib/rabbitmq/_rpc_client.py +21 -22
  29. qena_shared_lib/rabbitmq/message/__init__.py +19 -0
  30. qena_shared_lib/rabbitmq/message/_inbound.py +13 -0
  31. qena_shared_lib/rabbitmq/message/_outbound.py +13 -0
  32. qena_shared_lib/redis.py +47 -0
  33. qena_shared_lib/remotelogging/_base.py +34 -28
  34. qena_shared_lib/remotelogging/logstash/_base.py +3 -2
  35. qena_shared_lib/remotelogging/logstash/_http_sender.py +2 -4
  36. qena_shared_lib/remotelogging/logstash/_tcp_sender.py +2 -2
  37. qena_shared_lib/scheduler.py +24 -15
  38. qena_shared_lib/security.py +39 -32
  39. qena_shared_lib/sync.py +91 -0
  40. qena_shared_lib/utils.py +13 -11
  41. {qena_shared_lib-0.1.17.dist-info → qena_shared_lib-0.1.19.dist-info}/METADATA +395 -32
  42. qena_shared_lib-0.1.19.dist-info/RECORD +50 -0
  43. qena_shared_lib-0.1.19.dist-info/WHEEL +4 -0
  44. qena_shared_lib/exception_handlers.py +0 -235
  45. qena_shared_lib-0.1.17.dist-info/RECORD +0 -31
  46. qena_shared_lib-0.1.17.dist-info/WHEEL +0 -4
@@ -2,6 +2,9 @@ from enum import Enum
2
2
  from typing import Any
3
3
 
4
4
  from fastapi import status
5
+ from typing_extensions import Self
6
+
7
+ from .enums import ServiceType
5
8
 
6
9
  __all__ = [
7
10
  "BadGateway",
@@ -18,6 +21,7 @@ __all__ = [
18
21
  "IAmATeapot",
19
22
  "InsufficientStorage",
20
23
  "InternalServerError",
24
+ "KafkaDisconnectedError",
21
25
  "LengthRequired",
22
26
  "Locked",
23
27
  "LoopDetected",
@@ -64,8 +68,8 @@ class Severity(Enum):
64
68
 
65
69
 
66
70
  class ServiceException(Exception):
67
- _GENERAL_SEVERITY: Severity | None = None
68
- _GENERAL_EXTRACT_EXC_INFO: bool | None = None
71
+ GENERAL_SEVERITY: Severity | None = None
72
+ GENERAL_EXTRACT_EXC_INFO: bool | None = None
69
73
 
70
74
  def __init__(
71
75
  self,
@@ -80,8 +84,8 @@ class ServiceException(Exception):
80
84
 
81
85
  if severity is not None:
82
86
  self._severity = severity
83
- elif self._GENERAL_SEVERITY is not None:
84
- self._severity = self._GENERAL_SEVERITY
87
+ elif self.GENERAL_SEVERITY is not None:
88
+ self._severity = self.GENERAL_SEVERITY
85
89
  else:
86
90
  self._severity = Severity.LOW
87
91
 
@@ -95,8 +99,8 @@ class ServiceException(Exception):
95
99
 
96
100
  if extract_exc_info is not None:
97
101
  self._extract_exc_info = extract_exc_info
98
- elif self._GENERAL_EXTRACT_EXC_INFO is not None:
99
- self._extract_exc_info = self._GENERAL_EXTRACT_EXC_INFO
102
+ elif self.GENERAL_EXTRACT_EXC_INFO is not None:
103
+ self._extract_exc_info = self.GENERAL_EXTRACT_EXC_INFO
100
104
  else:
101
105
  self._extract_exc_info = False
102
106
 
@@ -132,7 +136,7 @@ class ServiceException(Exception):
132
136
 
133
137
 
134
138
  class HTTPServiceError(ServiceException):
135
- _GENERAL_STATUS_CODE: int | None = None
139
+ GENERAL_STATUS_CODE: int | None = None
136
140
 
137
141
  def __init__(
138
142
  self,
@@ -163,7 +167,7 @@ class HTTPServiceError(ServiceException):
163
167
  if status_code is not None:
164
168
  self._status_code = status_code
165
169
  else:
166
- self._status_code = self._GENERAL_STATUS_CODE
170
+ self._status_code = self.GENERAL_STATUS_CODE
167
171
 
168
172
  self._headers = headers
169
173
  self._response_code = response_code
@@ -197,179 +201,179 @@ class HTTPServiceError(ServiceException):
197
201
 
198
202
 
199
203
  class ClientError(HTTPServiceError):
200
- _GENERAL_SEVERITY = Severity.MEDIUM
201
- _GENERAL_EXTRACT_EXC_INFO = False
204
+ GENERAL_SEVERITY = Severity.MEDIUM
205
+ GENERAL_EXTRACT_EXC_INFO = False
202
206
 
203
207
 
204
208
  class BadRequest(ClientError):
205
- _GENERAL_STATUS_CODE = status.HTTP_400_BAD_REQUEST
209
+ GENERAL_STATUS_CODE = status.HTTP_400_BAD_REQUEST
206
210
 
207
211
 
208
212
  class Unauthorized(ClientError):
209
- _GENERAL_STATUS_CODE = status.HTTP_401_UNAUTHORIZED
213
+ GENERAL_STATUS_CODE = status.HTTP_401_UNAUTHORIZED
210
214
 
211
215
 
212
216
  class PaymentRequired(ClientError):
213
- _GENERAL_STATUS_CODE = status.HTTP_402_PAYMENT_REQUIRED
217
+ GENERAL_STATUS_CODE = status.HTTP_402_PAYMENT_REQUIRED
214
218
 
215
219
 
216
220
  class Forbidden(ClientError):
217
- _GENERAL_STATUS_CODE = status.HTTP_403_FORBIDDEN
221
+ GENERAL_STATUS_CODE = status.HTTP_403_FORBIDDEN
218
222
 
219
223
 
220
224
  class NotFound(ClientError):
221
- _GENERAL_STATUS_CODE = status.HTTP_404_NOT_FOUND
225
+ GENERAL_STATUS_CODE = status.HTTP_404_NOT_FOUND
222
226
 
223
227
 
224
228
  class MethodNotAllowed(ClientError):
225
- _GENERAL_STATUS_CODE = status.HTTP_405_METHOD_NOT_ALLOWED
229
+ GENERAL_STATUS_CODE = status.HTTP_405_METHOD_NOT_ALLOWED
226
230
 
227
231
 
228
232
  class NotAcceptable(ClientError):
229
- _GENERAL_STATUS_CODE = status.HTTP_406_NOT_ACCEPTABLE
233
+ GENERAL_STATUS_CODE = status.HTTP_406_NOT_ACCEPTABLE
230
234
 
231
235
 
232
236
  class ProxyAuthenticationRequired(ClientError):
233
- _GENERAL_STATUS_CODE = status.HTTP_407_PROXY_AUTHENTICATION_REQUIRED
237
+ GENERAL_STATUS_CODE = status.HTTP_407_PROXY_AUTHENTICATION_REQUIRED
234
238
 
235
239
 
236
240
  class RequestTimeout(ClientError):
237
- _GENERAL_STATUS_CODE = status.HTTP_408_REQUEST_TIMEOUT
241
+ GENERAL_STATUS_CODE = status.HTTP_408_REQUEST_TIMEOUT
238
242
 
239
243
 
240
244
  class Conflict(ClientError):
241
- _GENERAL_STATUS_CODE = status.HTTP_409_CONFLICT
245
+ GENERAL_STATUS_CODE = status.HTTP_409_CONFLICT
242
246
 
243
247
 
244
248
  class Gone(ClientError):
245
- _GENERAL_STATUS_CODE = status.HTTP_410_GONE
249
+ GENERAL_STATUS_CODE = status.HTTP_410_GONE
246
250
 
247
251
 
248
252
  class LengthRequired(ClientError):
249
- _GENERAL_STATUS_CODE = status.HTTP_411_LENGTH_REQUIRED
253
+ GENERAL_STATUS_CODE = status.HTTP_411_LENGTH_REQUIRED
250
254
 
251
255
 
252
256
  class PreconditionFailed(ClientError):
253
- _GENERAL_STATUS_CODE = status.HTTP_412_PRECONDITION_FAILED
257
+ GENERAL_STATUS_CODE = status.HTTP_412_PRECONDITION_FAILED
254
258
 
255
259
 
256
260
  class PayloadTooLarge(ClientError):
257
- _GENERAL_STATUS_CODE = status.HTTP_413_REQUEST_ENTITY_TOO_LARGE
261
+ GENERAL_STATUS_CODE = status.HTTP_413_REQUEST_ENTITY_TOO_LARGE
258
262
 
259
263
 
260
264
  class URITooLong(ClientError):
261
- _GENERAL_STATUS_CODE = status.HTTP_414_REQUEST_URI_TOO_LONG
265
+ GENERAL_STATUS_CODE = status.HTTP_414_REQUEST_URI_TOO_LONG
262
266
 
263
267
 
264
268
  class UnsupportedMediaType(ClientError):
265
- _GENERAL_STATUS_CODE = status.HTTP_415_UNSUPPORTED_MEDIA_TYPE
269
+ GENERAL_STATUS_CODE = status.HTTP_415_UNSUPPORTED_MEDIA_TYPE
266
270
 
267
271
 
268
272
  class RangeNotSatisfiable(ClientError):
269
- _GENERAL_STATUS_CODE = status.HTTP_416_REQUESTED_RANGE_NOT_SATISFIABLE
273
+ GENERAL_STATUS_CODE = status.HTTP_416_REQUESTED_RANGE_NOT_SATISFIABLE
270
274
 
271
275
 
272
276
  class ExpectationFailed(ClientError):
273
- _GENERAL_STATUS_CODE = status.HTTP_417_EXPECTATION_FAILED
277
+ GENERAL_STATUS_CODE = status.HTTP_417_EXPECTATION_FAILED
274
278
 
275
279
 
276
280
  class IAmATeapot(ClientError):
277
- _GENERAL_STATUS_CODE = status.HTTP_418_IM_A_TEAPOT
281
+ GENERAL_STATUS_CODE = status.HTTP_418_IM_A_TEAPOT
278
282
 
279
283
 
280
284
  class MisdirectedRequest(ClientError):
281
- _GENERAL_STATUS_CODE = status.HTTP_421_MISDIRECTED_REQUEST
285
+ GENERAL_STATUS_CODE = status.HTTP_421_MISDIRECTED_REQUEST
282
286
 
283
287
 
284
288
  class UnprocessableEntity(ClientError):
285
- _GENERAL_STATUS_CODE = status.HTTP_422_UNPROCESSABLE_ENTITY
289
+ GENERAL_STATUS_CODE = status.HTTP_422_UNPROCESSABLE_ENTITY
286
290
 
287
291
 
288
292
  class Locked(ClientError):
289
- _GENERAL_STATUS_CODE = status.HTTP_423_LOCKED
293
+ GENERAL_STATUS_CODE = status.HTTP_423_LOCKED
290
294
 
291
295
 
292
296
  class FailedDependency(ClientError):
293
- _GENERAL_STATUS_CODE = status.HTTP_424_FAILED_DEPENDENCY
297
+ GENERAL_STATUS_CODE = status.HTTP_424_FAILED_DEPENDENCY
294
298
 
295
299
 
296
300
  class TooEarly(ClientError):
297
- _GENERAL_STATUS_CODE = status.HTTP_425_TOO_EARLY
301
+ GENERAL_STATUS_CODE = status.HTTP_425_TOO_EARLY
298
302
 
299
303
 
300
304
  class UpgradeRequired(ClientError):
301
- _GENERAL_STATUS_CODE = status.HTTP_426_UPGRADE_REQUIRED
305
+ GENERAL_STATUS_CODE = status.HTTP_426_UPGRADE_REQUIRED
302
306
 
303
307
 
304
308
  class PreconditionRequired(ClientError):
305
- _GENERAL_STATUS_CODE = status.HTTP_428_PRECONDITION_REQUIRED
309
+ GENERAL_STATUS_CODE = status.HTTP_428_PRECONDITION_REQUIRED
306
310
 
307
311
 
308
312
  class TooManyRequests(ClientError):
309
- _GENERAL_STATUS_CODE = status.HTTP_429_TOO_MANY_REQUESTS
313
+ GENERAL_STATUS_CODE = status.HTTP_429_TOO_MANY_REQUESTS
310
314
 
311
315
 
312
316
  class RequestHeaderFieldsTooLarge(ClientError):
313
- _GENERAL_STATUS_CODE = status.HTTP_431_REQUEST_HEADER_FIELDS_TOO_LARGE
317
+ GENERAL_STATUS_CODE = status.HTTP_431_REQUEST_HEADER_FIELDS_TOO_LARGE
314
318
 
315
319
 
316
320
  class UnavailableForLegalReasons(ClientError):
317
- _GENERAL_STATUS_CODE = status.HTTP_451_UNAVAILABLE_FOR_LEGAL_REASONS
321
+ GENERAL_STATUS_CODE = status.HTTP_451_UNAVAILABLE_FOR_LEGAL_REASONS
318
322
 
319
323
 
320
324
  class ServerError(HTTPServiceError):
321
- _GENERAL_SEVERITY = Severity.HIGH
322
- _GENERAL_EXTRACT_EXC_INFO = True
325
+ GENERAL_SEVERITY = Severity.HIGH
326
+ GENERAL_EXTRACT_EXC_INFO = True
323
327
 
324
328
 
325
329
  class InternalServerError(ServerError):
326
- _GENERAL_STATUS_CODE = status.HTTP_500_INTERNAL_SERVER_ERROR
330
+ GENERAL_STATUS_CODE = status.HTTP_500_INTERNAL_SERVER_ERROR
327
331
 
328
332
 
329
333
  class NotImplemented(ServerError):
330
- _GENERAL_STATUS_CODE = status.HTTP_501_NOT_IMPLEMENTED
334
+ GENERAL_STATUS_CODE = status.HTTP_501_NOT_IMPLEMENTED
331
335
 
332
336
 
333
337
  class BadGateway(ServerError):
334
- _GENERAL_STATUS_CODE = status.HTTP_502_BAD_GATEWAY
338
+ GENERAL_STATUS_CODE = status.HTTP_502_BAD_GATEWAY
335
339
 
336
340
 
337
341
  class ServiceUnavailable(ServerError):
338
- _GENERAL_STATUS_CODE = status.HTTP_503_SERVICE_UNAVAILABLE
342
+ GENERAL_STATUS_CODE = status.HTTP_503_SERVICE_UNAVAILABLE
339
343
 
340
344
 
341
345
  class GatewayTimeout(ServerError):
342
- _GENERAL_STATUS_CODE = status.HTTP_504_GATEWAY_TIMEOUT
346
+ GENERAL_STATUS_CODE = status.HTTP_504_GATEWAY_TIMEOUT
343
347
 
344
348
 
345
349
  class HTTPVersionNotSupported(ServerError):
346
- _GENERAL_STATUS_CODE = status.HTTP_505_HTTP_VERSION_NOT_SUPPORTED
350
+ GENERAL_STATUS_CODE = status.HTTP_505_HTTP_VERSION_NOT_SUPPORTED
347
351
 
348
352
 
349
353
  class VariantAlsoNegotiates(ServerError):
350
- _GENERAL_STATUS_CODE = status.HTTP_506_VARIANT_ALSO_NEGOTIATES
354
+ GENERAL_STATUS_CODE = status.HTTP_506_VARIANT_ALSO_NEGOTIATES
351
355
 
352
356
 
353
357
  class InsufficientStorage(ServerError):
354
- _GENERAL_STATUS_CODE = status.HTTP_507_INSUFFICIENT_STORAGE
358
+ GENERAL_STATUS_CODE = status.HTTP_507_INSUFFICIENT_STORAGE
355
359
 
356
360
 
357
361
  class LoopDetected(ServerError):
358
- _GENERAL_STATUS_CODE = status.HTTP_508_LOOP_DETECTED
362
+ GENERAL_STATUS_CODE = status.HTTP_508_LOOP_DETECTED
359
363
 
360
364
 
361
365
  class NotExtended(ServerError):
362
- _GENERAL_STATUS_CODE = status.HTTP_510_NOT_EXTENDED
366
+ GENERAL_STATUS_CODE = status.HTTP_510_NOT_EXTENDED
363
367
 
364
368
 
365
369
  class NetworkAuthenticationRequired(ServerError):
366
- _GENERAL_STATUS_CODE = status.HTTP_511_NETWORK_AUTHENTICATION_REQUIRED
370
+ GENERAL_STATUS_CODE = status.HTTP_511_NETWORK_AUTHENTICATION_REQUIRED
367
371
 
368
372
 
369
373
  class RabbitMQServiceException(ServiceException):
370
- _GENERAL_SEVERITY = Severity.HIGH
371
- _GENERAL_EXTRACT_EXC_INFO = True
372
- _GENERAL_CODE: int | None = None
374
+ GENERAL_SEVERITY = Severity.HIGH
375
+ GENERAL_EXTRACT_EXC_INFO = True
376
+ GENERAL_CODE: int | None = None
373
377
 
374
378
  def __init__(
375
379
  self,
@@ -393,8 +397,8 @@ class RabbitMQServiceException(ServiceException):
393
397
 
394
398
  if code is not None:
395
399
  self._code = code
396
- elif self._GENERAL_CODE is not None:
397
- self._code = self._GENERAL_CODE
400
+ elif self.GENERAL_CODE is not None:
401
+ self._code = self.GENERAL_CODE
398
402
  else:
399
403
  self._code = 0
400
404
 
@@ -429,3 +433,109 @@ class RabbitMQRpcRequestPendingError(Exception):
429
433
 
430
434
  class RabbitMQConnectionUnhealthyError(Exception):
431
435
  pass
436
+
437
+
438
+ class KafkaDisconnectedError(Exception):
439
+ pass
440
+
441
+
442
+ class GenericServiceExceptionFactory:
443
+ def __init__(
444
+ self,
445
+ message: str,
446
+ severity: Severity | None = None,
447
+ tags: list[str] | None = None,
448
+ extra: dict[str, str] | None = None,
449
+ remote_logging: bool = True,
450
+ extract_exc_info: bool = True,
451
+ ):
452
+ self._message = message
453
+ self._severity = severity
454
+ self._tags = tags
455
+ self._extra = extra
456
+ self._remote_logging = remote_logging
457
+ self._extract_exc_info = extract_exc_info
458
+
459
+ self._http_service_error: type[HTTPServiceError] = InternalServerError
460
+ self._rabbitmq_service_exception: type[RabbitMQServiceException] = (
461
+ RabbitMQServiceException
462
+ )
463
+
464
+ self._body: Any | None = None
465
+ self._status_code: int | None = None
466
+ self._headers: dict[str, str] | None = None
467
+ self._response_code: int | None = None
468
+ self._corrective_action: str | None = None
469
+ self._code: int | None = None
470
+ self._data: Any | None = None
471
+
472
+ def for_http_service_error(
473
+ self, http_service_error: type[HTTPServiceError]
474
+ ) -> Self:
475
+ self._http_service_error = http_service_error
476
+
477
+ return self
478
+
479
+ def for_rabbitmq_service_exception(
480
+ self, rabbitmq_service_exception: type[RabbitMQServiceException]
481
+ ) -> Self:
482
+ self._rabbitmq_service_exception = rabbitmq_service_exception
483
+
484
+ return self
485
+
486
+ def with_http_service_error(
487
+ self,
488
+ body: Any | None = None,
489
+ status_code: int | None = None,
490
+ headers: dict[str, str] | None = None,
491
+ response_code: int | None = None,
492
+ corrective_action: str | None = None,
493
+ ) -> Self:
494
+ self._body = body
495
+ self._status_code = status_code
496
+ self._headers = headers
497
+ self._response_code = response_code
498
+ self._corrective_action = corrective_action
499
+
500
+ return self
501
+
502
+ def with_rabbitmq_service_exception(
503
+ self,
504
+ code: int | None = None,
505
+ data: Any | None = None,
506
+ ) -> Self:
507
+ self._code = code
508
+ self._data = data
509
+
510
+ return self
511
+
512
+ def create(self, service_type: ServiceType) -> ServiceException:
513
+ assert self._http_service_error is not None
514
+ assert self._rabbitmq_service_exception is not None
515
+
516
+ match service_type:
517
+ case ServiceType.HTTP:
518
+ return self._http_service_error(
519
+ message=self._message,
520
+ body=self._body,
521
+ status_code=self._status_code,
522
+ headers=self._headers,
523
+ response_code=self._response_code,
524
+ corrective_action=self._corrective_action,
525
+ severity=self._severity,
526
+ tags=self._tags,
527
+ extra=self._extra,
528
+ remote_logging=self._remote_logging,
529
+ extract_exc_info=self._extract_exc_info,
530
+ )
531
+ case ServiceType.RABBIT_MQ:
532
+ return self._rabbitmq_service_exception(
533
+ message=self._message,
534
+ code=self._code,
535
+ data=self._data,
536
+ severity=self._severity,
537
+ tags=self._tags,
538
+ extra=self._extra,
539
+ remote_logging=self._remote_logging,
540
+ extract_exc_info=self._extract_exc_info,
541
+ )
@@ -0,0 +1,110 @@
1
+ from ._base import (
2
+ ROUTE_HANDLER_ATTRIBUTE,
3
+ APIRouter,
4
+ BackgroundTasks,
5
+ Body,
6
+ ControllerBase,
7
+ Cookie,
8
+ Depends,
9
+ File,
10
+ FileResponse,
11
+ Form,
12
+ Header,
13
+ HTMLResponse,
14
+ HTTPException,
15
+ JSONResponse,
16
+ Path,
17
+ PlainTextResponse,
18
+ Query,
19
+ RedirectResponse,
20
+ Request,
21
+ Response,
22
+ RouteHandlerMetadata,
23
+ Security,
24
+ StreamingResponse,
25
+ UploadFile,
26
+ WebSocket,
27
+ WebSocketDisconnect,
28
+ WebSocketException,
29
+ api_controller,
30
+ delete,
31
+ get,
32
+ head,
33
+ options,
34
+ patch,
35
+ post,
36
+ put,
37
+ status,
38
+ trace,
39
+ )
40
+ from ._exception_handlers import (
41
+ AbstractHttpExceptionHandler,
42
+ HttpGeneralExceptionHandler,
43
+ HTTPServiceExceptionHandler,
44
+ RequestValidationErrorHandler,
45
+ )
46
+ from ._request import (
47
+ CamelCaseRequest,
48
+ InboundRequest,
49
+ OutboundRequest,
50
+ SnakeCaseRequest,
51
+ )
52
+ from ._response import (
53
+ CamelCaseResponse,
54
+ InboundResponse,
55
+ OutboundResponse,
56
+ SnakeCaseRespose,
57
+ )
58
+
59
+ __all__ = [
60
+ "AbstractHttpExceptionHandler",
61
+ "api_controller",
62
+ "APIRouter",
63
+ "BackgroundTasks",
64
+ "Body",
65
+ "CamelCaseRequest",
66
+ "CamelCaseResponse",
67
+ "ControllerBase",
68
+ "Cookie",
69
+ "delete",
70
+ "Depends",
71
+ "File",
72
+ "FileResponse",
73
+ "Form",
74
+ "get",
75
+ "head",
76
+ "Header",
77
+ "HTMLResponse",
78
+ "HTTPException",
79
+ "HttpGeneralExceptionHandler",
80
+ "HTTPServiceExceptionHandler",
81
+ "InboundRequest",
82
+ "InboundResponse",
83
+ "JSONResponse",
84
+ "options",
85
+ "OutboundRequest",
86
+ "OutboundResponse",
87
+ "patch",
88
+ "Path",
89
+ "PlainTextResponse",
90
+ "post",
91
+ "put",
92
+ "Query",
93
+ "RedirectResponse",
94
+ "Request",
95
+ "RequestValidationErrorHandler",
96
+ "Response",
97
+ "Response",
98
+ "ROUTE_HANDLER_ATTRIBUTE",
99
+ "RouteHandlerMetadata",
100
+ "Security",
101
+ "SnakeCaseRequest",
102
+ "SnakeCaseRespose",
103
+ "status",
104
+ "StreamingResponse",
105
+ "trace",
106
+ "UploadFile",
107
+ "WebSocket",
108
+ "WebSocketDisconnect",
109
+ "WebSocketException",
110
+ ]
@@ -75,7 +75,7 @@ __all__ = [
75
75
 
76
76
  AC = TypeVar("AC")
77
77
  API_CONTROLLER_ATTRIBUTE = "__api_controller_router__"
78
- ROUTE_HANDLER_ATTRIBUTE = "__route_handler_meta__"
78
+ ROUTE_HANDLER_ATTRIBUTE = "__route_handler_metadata__"
79
79
 
80
80
 
81
81
  class HTTPMethods(Enum):
@@ -90,7 +90,7 @@ class HTTPMethods(Enum):
90
90
 
91
91
 
92
92
  @dataclass
93
- class RouteHandlerMeta:
93
+ class RouteHandlerMetadata:
94
94
  method: HTTPMethods
95
95
  path: str | None = None
96
96
  response_model: Any | None = None
@@ -173,7 +173,7 @@ def get(
173
173
  setattr(
174
174
  route_handler,
175
175
  ROUTE_HANDLER_ATTRIBUTE,
176
- RouteHandlerMeta(
176
+ RouteHandlerMetadata(
177
177
  method=HTTPMethods.GET,
178
178
  path=path,
179
179
  response_model=response_model,
@@ -230,7 +230,7 @@ def put(
230
230
  setattr(
231
231
  route_handler,
232
232
  ROUTE_HANDLER_ATTRIBUTE,
233
- RouteHandlerMeta(
233
+ RouteHandlerMetadata(
234
234
  method=HTTPMethods.PUT,
235
235
  path=path,
236
236
  response_model=response_model,
@@ -287,7 +287,7 @@ def post(
287
287
  setattr(
288
288
  route_handler,
289
289
  ROUTE_HANDLER_ATTRIBUTE,
290
- RouteHandlerMeta(
290
+ RouteHandlerMetadata(
291
291
  method=HTTPMethods.POST,
292
292
  path=path,
293
293
  response_model=response_model,
@@ -344,7 +344,7 @@ def delete(
344
344
  setattr(
345
345
  route_handler,
346
346
  ROUTE_HANDLER_ATTRIBUTE,
347
- RouteHandlerMeta(
347
+ RouteHandlerMetadata(
348
348
  method=HTTPMethods.DELETE,
349
349
  path=path,
350
350
  response_model=response_model,
@@ -401,7 +401,7 @@ def options(
401
401
  setattr(
402
402
  route_handler,
403
403
  ROUTE_HANDLER_ATTRIBUTE,
404
- RouteHandlerMeta(
404
+ RouteHandlerMetadata(
405
405
  method=HTTPMethods.OPTIONS,
406
406
  path=path,
407
407
  response_model=response_model,
@@ -458,7 +458,7 @@ def head(
458
458
  setattr(
459
459
  route_handler,
460
460
  ROUTE_HANDLER_ATTRIBUTE,
461
- RouteHandlerMeta(
461
+ RouteHandlerMetadata(
462
462
  method=HTTPMethods.HEAD,
463
463
  path=path,
464
464
  response_model=response_model,
@@ -515,7 +515,7 @@ def patch(
515
515
  setattr(
516
516
  route_handler,
517
517
  ROUTE_HANDLER_ATTRIBUTE,
518
- RouteHandlerMeta(
518
+ RouteHandlerMetadata(
519
519
  method=HTTPMethods.PATCH,
520
520
  path=path,
521
521
  response_model=response_model,
@@ -572,7 +572,7 @@ def trace(
572
572
  setattr(
573
573
  route_handler,
574
574
  ROUTE_HANDLER_ATTRIBUTE,
575
- RouteHandlerMeta(
575
+ RouteHandlerMetadata(
576
576
  method=HTTPMethods.TRACE,
577
577
  path=path,
578
578
  response_model=response_model,
@@ -622,21 +622,21 @@ class ControllerBase:
622
622
  if attribute is None:
623
623
  continue
624
624
 
625
- route_handler_meta = getattr(
625
+ route_handler_metadata = getattr(
626
626
  attribute, ROUTE_HANDLER_ATTRIBUTE, None
627
627
  )
628
628
 
629
- if route_handler_meta is None:
629
+ if route_handler_metadata is None:
630
630
  continue
631
631
 
632
- if not isinstance(route_handler_meta, RouteHandlerMeta):
632
+ if not isinstance(route_handler_metadata, RouteHandlerMetadata):
633
633
  raise TypeError(
634
- f"expected `{ROUTE_HANDLER_ATTRIBUTE}` to be of type `RouteHandlerMeta`, got {type(route_handler_meta)}"
634
+ f"expected `{ROUTE_HANDLER_ATTRIBUTE}` to be of type `RouteHandlerMetadata`, got {type(route_handler_metadata)}"
635
635
  )
636
636
 
637
637
  api_router_method = None
638
638
 
639
- match route_handler_meta.method:
639
+ match route_handler_metadata.method:
640
640
  case HTTPMethods.GET:
641
641
  api_router_method = api_router.get
642
642
  case HTTPMethods.PUT:
@@ -656,30 +656,30 @@ class ControllerBase:
656
656
 
657
657
  if api_router_method is None:
658
658
  raise ValueError(
659
- f"api router method {route_handler_meta.method} not supported"
659
+ f"api router method {route_handler_metadata.method} not supported"
660
660
  )
661
661
 
662
662
  api_router_method(
663
- path=route_handler_meta.path or "",
664
- response_model=route_handler_meta.response_model,
665
- status_code=route_handler_meta.status_code,
666
- tags=route_handler_meta.tags,
667
- dependencies=route_handler_meta.dependencies,
668
- summary=route_handler_meta.summary,
669
- description=route_handler_meta.description,
670
- response_description=route_handler_meta.response_description,
671
- responses=route_handler_meta.responses,
672
- deprecated=route_handler_meta.deprecated,
673
- response_model_include=route_handler_meta.response_model_include,
674
- response_model_exclude=route_handler_meta.response_model_exclude,
675
- response_model_by_alias=route_handler_meta.response_model_by_alias,
676
- response_model_exclude_unset=route_handler_meta.response_model_exclude_unset,
677
- response_model_exclude_defaults=route_handler_meta.response_model_exclude_defaults,
678
- response_model_exclude_none=route_handler_meta.response_model_exclude_none,
679
- include_in_schema=route_handler_meta.include_in_schema,
680
- response_class=route_handler_meta.response_class,
681
- name=route_handler_meta.name,
682
- openapi_extra=route_handler_meta.openapi_extra,
663
+ path=route_handler_metadata.path or "",
664
+ response_model=route_handler_metadata.response_model,
665
+ status_code=route_handler_metadata.status_code,
666
+ tags=route_handler_metadata.tags,
667
+ dependencies=route_handler_metadata.dependencies,
668
+ summary=route_handler_metadata.summary,
669
+ description=route_handler_metadata.description,
670
+ response_description=route_handler_metadata.response_description,
671
+ responses=route_handler_metadata.responses,
672
+ deprecated=route_handler_metadata.deprecated,
673
+ response_model_include=route_handler_metadata.response_model_include,
674
+ response_model_exclude=route_handler_metadata.response_model_exclude,
675
+ response_model_by_alias=route_handler_metadata.response_model_by_alias,
676
+ response_model_exclude_unset=route_handler_metadata.response_model_exclude_unset,
677
+ response_model_exclude_defaults=route_handler_metadata.response_model_exclude_defaults,
678
+ response_model_exclude_none=route_handler_metadata.response_model_exclude_none,
679
+ include_in_schema=route_handler_metadata.include_in_schema,
680
+ response_class=route_handler_metadata.response_class,
681
+ name=route_handler_metadata.name,
682
+ openapi_extra=route_handler_metadata.openapi_extra,
683
683
  )(attribute)
684
684
 
685
685
  return api_router