starmallow 0.8.0__py3-none-any.whl → 0.9.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.
starmallow/routing.py CHANGED
@@ -2,23 +2,14 @@ import asyncio
2
2
  import functools
3
3
  import inspect
4
4
  import logging
5
+ from collections.abc import Awaitable, Callable, Sequence
5
6
  from enum import Enum, IntEnum
6
7
  from typing import (
7
8
  Any,
8
- Awaitable,
9
- Callable,
10
- Coroutine,
11
- Dict,
12
- List,
13
- Optional,
14
- Sequence,
15
- Set,
16
- Tuple,
17
- Type,
18
- Union,
19
9
  )
20
10
 
21
11
  import marshmallow as ma
12
+ import marshmallow.fields as mf
22
13
  from starlette import routing
23
14
  from starlette.concurrency import run_in_threadpool
24
15
  from starlette.middleware import Middleware
@@ -28,8 +19,8 @@ from starlette.routing import (
28
19
  BaseRoute,
29
20
  Match,
30
21
  compile_path,
31
- is_async_callable,
32
- wrap_app_handling_exceptions,
22
+ is_async_callable, # type: ignore
23
+ wrap_app_handling_exceptions, # type: ignore
33
24
  )
34
25
  from starlette.status import WS_1008_POLICY_VIOLATION
35
26
  from starlette.types import ASGIApp, Receive, Scope, Send
@@ -43,16 +34,15 @@ from starmallow.endpoints import APIHTTPEndpoint
43
34
  from starmallow.exceptions import RequestValidationError, WebSocketRequestValidationError
44
35
  from starmallow.request_resolver import resolve_params
45
36
  from starmallow.responses import JSONResponse
46
- from starmallow.types import DecoratedCallable
37
+ from starmallow.types import DecoratedCallable, WebSocketEndpointCallable
47
38
  from starmallow.utils import (
39
+ MaDataclassProtocol,
48
40
  create_response_model,
49
41
  generate_unique_id,
50
42
  get_name,
51
43
  get_typed_signature,
52
44
  get_value_or_default,
53
45
  is_body_allowed_for_status_code,
54
- is_marshmallow_field,
55
- is_marshmallow_schema,
56
46
  )
57
47
  from starmallow.websockets import APIWebSocket
58
48
 
@@ -61,7 +51,7 @@ logger = logging.getLogger(__name__)
61
51
 
62
52
  async def run_endpoint_function(
63
53
  endpoint_model: EndpointModel,
64
- values: Dict[str, Any],
54
+ values: dict[str, Any],
65
55
  ) -> Any:
66
56
  assert endpoint_model.call is not None, "endpoint_model.call must be a function"
67
57
 
@@ -78,8 +68,8 @@ async def run_endpoint_function(
78
68
 
79
69
 
80
70
  def request_response(
81
- func: Callable[[Request], Union[Awaitable[Response], Response]],
82
- request_class: Type[Request],
71
+ func: Callable[[Request], Awaitable[Response] | Response],
72
+ request_class: type[Request],
83
73
  ) -> ASGIApp:
84
74
  """
85
75
  Takes a function or coroutine `func(request) -> response`,
@@ -94,7 +84,7 @@ def request_response(
94
84
  response = await func(request)
95
85
  else:
96
86
  response = await run_in_threadpool(func, request)
97
- await response(scope, receive, send)
87
+ await response(scope, receive, send) # type: ignore - TODO: Not sure what the type should be
98
88
 
99
89
  try:
100
90
  await wrap_app_handling_exceptions(app, request)(scope, receive, send)
@@ -120,7 +110,7 @@ def websocket_session(func: Callable) -> ASGIApp:
120
110
 
121
111
  def get_request_handler(
122
112
  endpoint_model: EndpointModel,
123
- ) -> Callable[[Request], Coroutine[Any, Any, Response]]:
113
+ ) -> Callable[[Request], Awaitable[Response] | Response]:
124
114
  assert endpoint_model.call is not None, "dependant.call must be a function"
125
115
 
126
116
  async def app(request: Request) -> Response:
@@ -131,7 +121,7 @@ def get_request_handler(
131
121
 
132
122
  raw_response = await run_endpoint_function(
133
123
  endpoint_model,
134
- values,
124
+ values or {},
135
125
  )
136
126
  if isinstance(raw_response, Response):
137
127
  if raw_response.background is None:
@@ -139,12 +129,13 @@ def get_request_handler(
139
129
  return raw_response
140
130
 
141
131
  response_data = raw_response
142
- if is_marshmallow_schema(endpoint_model.response_model):
143
- response_data = endpoint_model.response_model.dump(raw_response)
144
- elif is_marshmallow_field(endpoint_model.response_model):
145
- response_data = endpoint_model.response_model._serialize(raw_response, attr='response', obj=raw_response)
132
+ model = endpoint_model.response_model
133
+ if isinstance(model, ma.Schema):
134
+ response_data = model.dump(raw_response)
135
+ elif isinstance(model, mf.Field):
136
+ response_data = model._serialize(raw_response, attr='response', obj=raw_response)
146
137
 
147
- response_args: Dict[str, Any] = {"background": background_tasks}
138
+ response_args: dict[str, Any] = {"background": background_tasks}
148
139
  if endpoint_model.status_code is not None:
149
140
  response_args["status_code"] = endpoint_model.status_code
150
141
  if sub_response.status_code:
@@ -162,7 +153,7 @@ def get_request_handler(
162
153
 
163
154
  def get_websocker_hander(
164
155
  endpoint_model: EndpointModel,
165
- ) -> Callable[[Request], Coroutine[Any, Any, Response]]:
156
+ ) -> Callable[[WebSocket], Awaitable[None]]:
166
157
  assert endpoint_model.call is not None, "dependant.call must be a function"
167
158
 
168
159
  async def app(websocket: WebSocket) -> None:
@@ -174,7 +165,7 @@ def get_websocker_hander(
174
165
 
175
166
  await run_endpoint_function(
176
167
  endpoint_model,
177
- values,
168
+ values or {},
178
169
  )
179
170
 
180
171
  return app
@@ -186,7 +177,7 @@ class APIWebSocketRoute(routing.WebSocketRoute, EndpointMixin):
186
177
  path: str,
187
178
  endpoint: Callable[..., Any],
188
179
  *,
189
- name: Optional[str] = None,
180
+ name: str | None = None,
190
181
  ) -> None:
191
182
  self.path = path
192
183
  self.endpoint = endpoint
@@ -203,7 +194,7 @@ class APIWebSocketRoute(routing.WebSocketRoute, EndpointMixin):
203
194
  ),
204
195
  )
205
196
 
206
- def matches(self, scope: Scope) -> Tuple[Match, Scope]:
197
+ def matches(self, scope: Scope) -> tuple[Match, Scope]:
207
198
  match, child_scope = super().matches(scope)
208
199
  if match != Match.NONE:
209
200
  child_scope["route"] = self
@@ -217,35 +208,29 @@ class APIRoute(routing.Route, EndpointMixin):
217
208
  path: str,
218
209
  endpoint: Callable[..., Any],
219
210
  *,
220
- name: Optional[str] = None,
221
- methods: Optional[Union[Set[str], List[str]]] = None,
211
+ name: str | None = None,
212
+ methods: Sequence[str] | None = None,
222
213
  include_in_schema: bool = True,
223
214
  middleware: Sequence[Middleware] | None = None,
224
- status_code: Optional[int] = None,
225
- deprecated: Optional[bool] = None,
226
- request_class: Union[Type[Request], DefaultPlaceholder] = Default(
227
- Request,
228
- ),
229
- response_model: Optional[ma.Schema] = None,
230
- response_class: Union[Type[Response], DefaultPlaceholder] = Default(
231
- JSONResponse,
232
- ),
215
+ status_code: int | None = None,
216
+ deprecated: bool | None = None,
217
+ request_class: type[Request] | DefaultPlaceholder = Default(Request),
218
+ response_model: ma.Schema | type[ma.Schema | MaDataclassProtocol] | None = None,
219
+ response_class: type[Response] | DefaultPlaceholder = Default(JSONResponse),
233
220
  # OpenAPI summary
234
- summary: Optional[str] = None,
235
- description: Optional[str] = None,
221
+ summary: str | None = None,
222
+ description: str | None = None,
236
223
  response_description: str = "Successful Response",
237
- responses: Optional[Dict[Union[int, str], Dict[str, Any]]] = None,
238
- callbacks: Optional[List[BaseRoute]] = None,
224
+ responses: dict[int | str, dict[str, Any]] | None = None,
225
+ callbacks: list[BaseRoute] | None = None,
239
226
  # Sets the OpenAPI operationId to be used in your path operation
240
- operation_id: Optional[str] = None,
227
+ operation_id: str | None = None,
241
228
  # If operation_id is None, this function will be used to create one.
242
- generate_unique_id_function: Union[
243
- Callable[["APIRoute"], str], DefaultPlaceholder,
244
- ] = Default(generate_unique_id),
229
+ generate_unique_id_function: Callable[["APIRoute"], str] | DefaultPlaceholder = Default(generate_unique_id),
245
230
  # OpenAPI tags
246
- tags: Optional[List[Union[str, Enum]]] = None,
231
+ tags: list[str | Enum] | None = None,
247
232
  # Will be deeply merged with the automatically generated OpenAPI schema for the path operation.
248
- openapi_extra: Optional[Dict[str, Any]] = None,
233
+ openapi_extra: dict[str, Any] | None = None,
249
234
  ) -> None:
250
235
  # Copied from starlette, without the path assertion
251
236
  self.path = path
@@ -256,9 +241,15 @@ class APIRoute(routing.Route, EndpointMixin):
256
241
  endpoint_handler = endpoint
257
242
  while isinstance(endpoint_handler, functools.partial):
258
243
  endpoint_handler = endpoint_handler.func
244
+
245
+ if isinstance(request_class, DefaultPlaceholder):
246
+ self.request_class = request_class.value
247
+ else:
248
+ self.request_class = request_class
249
+
259
250
  if inspect.isfunction(endpoint_handler) or inspect.ismethod(endpoint_handler):
260
251
  # Endpoint is function or method. Treat it as `func(request) -> response`.
261
- self.app = request_response(endpoint, request_class)
252
+ self.app = request_response(endpoint, self.request_class)
262
253
  if methods is None:
263
254
  methods = ["GET"]
264
255
  else:
@@ -286,20 +277,15 @@ class APIRoute(routing.Route, EndpointMixin):
286
277
  self.responses = responses or {}
287
278
  self.openapi_extra = openapi_extra
288
279
 
289
- if isinstance(request_class, DefaultPlaceholder):
290
- self.request_class: Request = request_class.value
291
- else:
292
- self.request_class = request_class
293
-
294
280
  if isinstance(response_class, DefaultPlaceholder):
295
- self.response_class: Response = response_class.value
281
+ self.response_class = response_class.value
296
282
  else:
297
283
  self.response_class = response_class
298
284
 
299
285
  self.generate_unique_id_function = generate_unique_id_function
300
286
  if isinstance(generate_unique_id_function, DefaultPlaceholder):
301
287
  current_generate_unique_id: Callable[
302
- ["APIRoute"], str,
288
+ [APIRoute], str,
303
289
  ] = generate_unique_id_function.value
304
290
  else:
305
291
  current_generate_unique_id = generate_unique_id_function
@@ -335,7 +321,7 @@ class APIRoute(routing.Route, EndpointMixin):
335
321
  response_field = create_response_model(type_=model)
336
322
  response_fields[additional_status_code] = response_field
337
323
  if response_fields:
338
- self.response_fields: Dict[Union[int, str], ma.Schema] = response_fields
324
+ self.response_fields: dict[int | str, ma.Schema] = response_fields
339
325
  else:
340
326
  self.response_fields = {}
341
327
 
@@ -343,7 +329,7 @@ class APIRoute(routing.Route, EndpointMixin):
343
329
  self.path_format,
344
330
  self.endpoint,
345
331
  name=self.name,
346
- methods=self.methods,
332
+ methods=list(self.methods) if self.methods else None,
347
333
  status_code=self.status_code,
348
334
  response_model=self.response_model,
349
335
  response_class=self.response_class,
@@ -365,24 +351,24 @@ class APIRouter(routing.Router):
365
351
  def __init__(
366
352
  self,
367
353
  *args,
368
- tags: Optional[List[Union[str, Enum]]] = None,
369
- default_request_class: Type[Request] = Default(Request),
370
- default_response_class: Type[Response] = Default(JSONResponse),
371
- deprecated: Optional[bool] = None,
354
+ tags: list[str | Enum] | None = None,
355
+ default_request_class: type[Request] = Default(Request),
356
+ default_response_class: type[Response] = Default(JSONResponse),
357
+ deprecated: bool | None = None,
372
358
  include_in_schema: bool = True,
373
- responses: Optional[Dict[Union[int, str], Dict[str, Any]]] = None,
374
- callbacks: Optional[List[BaseRoute]] = None,
359
+ responses: dict[int | str, dict[str, Any]] | None = None,
360
+ callbacks: list[BaseRoute] | None = None,
375
361
  generate_unique_id_function: Callable[[APIRoute], str] = Default(
376
362
  generate_unique_id,
377
363
  ),
378
364
  prefix: str = "",
379
- route_class: Optional[Type[APIRoute]] = APIRoute,
365
+ route_class: type[APIRoute] = APIRoute,
380
366
  middleware: Sequence[Middleware] | None = None,
381
367
  **kwargs,
382
368
  ) -> None:
383
369
  super().__init__(*args, middleware=middleware, **kwargs)
384
370
 
385
- self.tags: List[Union[str, Enum]] = tags or []
371
+ self.tags: list[str | Enum] = tags or []
386
372
  self.default_request_class = default_request_class
387
373
  self.default_response_class = default_response_class
388
374
  self.deprecated = deprecated
@@ -397,11 +383,11 @@ class APIRouter(routing.Router):
397
383
  def route(
398
384
  self,
399
385
  path: str,
400
- methods: Optional[List[str]] = None,
401
- name: Optional[str] = None,
386
+ methods: list[str] | None = None,
387
+ name: str | None = None,
402
388
  include_in_schema: bool = True,
403
- ) -> Callable[[DecoratedCallable], DecoratedCallable]:
404
- def decorator(func: DecoratedCallable) -> DecoratedCallable:
389
+ ) -> Callable[[Callable[[Request], Awaitable[Response] | Response]], Callable[[Request], Awaitable[Response] | Response]]:
390
+ def decorator(func: Callable[[Request], Awaitable[Response] | Response]) -> Callable[[Request], Awaitable[Response] | Response]:
405
391
  self.add_route(
406
392
  path,
407
393
  func,
@@ -416,32 +402,32 @@ class APIRouter(routing.Router):
416
402
  def add_api_route(
417
403
  self,
418
404
  path: str,
419
- endpoint: Union[Callable[..., Any], APIHTTPEndpoint],
405
+ endpoint: Callable[..., Any] | type(APIHTTPEndpoint),
420
406
  *,
421
- methods: Optional[Union[Set[str], List[str]]] = None,
422
- name: str = None,
407
+ methods: set[str] | list[str] | None = None,
408
+ name: str | None = None,
423
409
  include_in_schema: bool = True,
424
- status_code: Optional[int] = None,
410
+ status_code: int | None = None,
425
411
  middleware: Sequence[Middleware] | None = None,
426
- deprecated: Optional[bool] = None,
427
- request_class: Type[Request] = Default(Request),
428
- response_model: Optional[Type[Any]] = None,
429
- response_class: Type[Response] = JSONResponse,
412
+ deprecated: bool | None = None,
413
+ request_class: type[Request] = Default(Request),
414
+ response_model: ma.Schema | type[ma.Schema | MaDataclassProtocol] | None = None,
415
+ response_class: type[Response] = JSONResponse,
430
416
  # OpenAPI summary
431
- summary: Optional[str] = None,
432
- description: Optional[str] = None,
417
+ summary: str | None = None,
418
+ description: str | None = None,
433
419
  response_description: str = "Successful Response",
434
- responses: Optional[Dict[Union[int, str], Dict[str, Any]]] = None,
435
- callbacks: Optional[List[BaseRoute]] = None,
420
+ responses: dict[int | str, dict[str, Any]] | None = None,
421
+ callbacks: list[BaseRoute] | None = None,
436
422
  # Sets the OpenAPI operationId to be used in your path operation
437
- operation_id: Optional[str] = None,
423
+ operation_id: str | None = None,
438
424
  # If operation_id is None, this function will be used to create one.
439
425
  generate_unique_id_function: Callable[["APIRoute"], str] = Default(generate_unique_id),
440
426
  # OpenAPI tags
441
- tags: Optional[List[Union[str, Enum]]] = None,
427
+ tags: list[str | Enum] | None = None,
442
428
  # Will be deeply merged with the automatically generated OpenAPI schema for the path operation.
443
- openapi_extra: Optional[Dict[str, Any]] = None,
444
- route_class: Optional[Type[APIRoute]] = None,
429
+ openapi_extra: dict[str, Any] | None = None,
430
+ route_class: type[APIRoute] | None = None,
445
431
  ) -> None:
446
432
  route_class = route_class or self.route_class
447
433
 
@@ -452,20 +438,26 @@ class APIRouter(routing.Router):
452
438
  if isinstance(endpoint, type(APIHTTPEndpoint)):
453
439
  # Ensure the functions are bound to a class instance
454
440
  # Currently all routes will share the same instance
455
- endpoint = endpoint()
456
-
457
- for method in endpoint.methods:
458
- endpoint_function = getattr(endpoint, method.lower())
459
- if hasattr(endpoint_function, 'endpoint_options'):
460
- endpoint_options = endpoint_function.endpoint_options
461
- else:
462
- endpoint_options = EndpointOptions()
441
+ endpoint_instance = endpoint()
442
+ if endpoint_instance.methods is None:
443
+ raise ValueError("APIHTTPEndpoint must have methods set")
444
+
445
+ for method in endpoint_instance.methods:
446
+ endpoint_function = getattr(endpoint_instance, method.lower())
447
+ endpoint_options = (
448
+ endpoint_function.endpoint_options
449
+ if hasattr(endpoint_function, 'endpoint_options')
450
+ else EndpointOptions()
451
+ )
463
452
 
464
453
  method_tags = current_tags.copy()
465
454
  if endpoint_options.tags:
466
455
  method_tags.extend(endpoint_options.tags)
467
456
 
468
457
  endpoint_route_class = endpoint_options.route_class or route_class
458
+ if endpoint_route_class is None:
459
+ raise ValueError("route_class must be set on the endpoint")
460
+
469
461
  route = endpoint_route_class(
470
462
  self.prefix + path,
471
463
  endpoint_function,
@@ -495,7 +487,7 @@ class APIRouter(routing.Router):
495
487
  route = route_class(
496
488
  self.prefix + path,
497
489
  endpoint,
498
- methods=methods,
490
+ methods=list(methods) if methods else None,
499
491
  name=name,
500
492
  include_in_schema=include_in_schema and self.include_in_schema,
501
493
  status_code=status_code,
@@ -521,30 +513,30 @@ class APIRouter(routing.Router):
521
513
  self,
522
514
  path: str,
523
515
  *,
524
- methods: Optional[Union[Set[str], List[str]]] = None,
525
- name: str = None,
516
+ methods: set[str] | list[str] | None = None,
517
+ name: str | None = None,
526
518
  include_in_schema: bool = True,
527
- status_code: Optional[int] = None,
519
+ status_code: int | None = None,
528
520
  middleware: Sequence[Middleware] | None = None,
529
- deprecated: Optional[bool] = None,
530
- request_class: Type[Request] = Default(Request),
531
- response_model: Optional[Type[Any]] = None,
532
- response_class: Type[Response] = JSONResponse,
521
+ deprecated: bool | None = None,
522
+ request_class: type[Request] = Default(Request),
523
+ response_model: type[Any] | None = None,
524
+ response_class: type[Response] = JSONResponse,
533
525
  # OpenAPI summary
534
- summary: Optional[str] = None,
535
- description: Optional[str] = None,
526
+ summary: str | None = None,
527
+ description: str | None = None,
536
528
  response_description: str = "Successful Response",
537
- responses: Optional[Dict[Union[int, str], Dict[str, Any]]] = None,
538
- callbacks: Optional[List[BaseRoute]] = None,
529
+ responses: dict[int | str, dict[str, Any]] | None = None,
530
+ callbacks: list[BaseRoute] | None = None,
539
531
  # Sets the OpenAPI operationId to be used in your path operation
540
- operation_id: Optional[str] = None,
532
+ operation_id: str | None = None,
541
533
  # If operation_id is None, this function will be used to create one.
542
534
  generate_unique_id_function: Callable[["APIRoute"], str] = Default(generate_unique_id),
543
535
  # OpenAPI tags
544
- tags: Optional[List[Union[str, Enum]]] = None,
536
+ tags: list[str | Enum] | None = None,
545
537
  # Will be deeply merged with the automatically generated OpenAPI schema for the path operation.
546
- openapi_extra: Optional[Dict[str, Any]] = None,
547
- route_class: Optional[Type[APIRoute]] = None,
538
+ openapi_extra: dict[str, Any] | None = None,
539
+ route_class: type[APIRoute] | None = None,
548
540
  ) -> Callable[[DecoratedCallable], DecoratedCallable]:
549
541
  def decorator(func: DecoratedCallable) -> DecoratedCallable:
550
542
  self.add_api_route(
@@ -574,7 +566,7 @@ class APIRouter(routing.Router):
574
566
  return decorator
575
567
 
576
568
  def add_api_websocket_route(
577
- self, path: str, endpoint: Callable[..., Any], name: Optional[str] = None,
569
+ self, path: str, endpoint: WebSocketEndpointCallable, name: str | None = None,
578
570
  ) -> None:
579
571
  route = APIWebSocketRoute(
580
572
  self.prefix + path,
@@ -584,18 +576,18 @@ class APIRouter(routing.Router):
584
576
  self.routes.append(route)
585
577
 
586
578
  def websocket(
587
- self, path: str, name: Optional[str] = None,
588
- ) -> Callable[[DecoratedCallable], DecoratedCallable]:
589
- def decorator(func: DecoratedCallable) -> DecoratedCallable:
579
+ self, path: str, name: str | None = None,
580
+ ) -> Callable[[WebSocketEndpointCallable], WebSocketEndpointCallable]:
581
+ def decorator(func: WebSocketEndpointCallable) -> WebSocketEndpointCallable:
590
582
  self.add_api_websocket_route(path, func, name=name)
591
583
  return func
592
584
 
593
585
  return decorator
594
586
 
595
587
  def websocket_route(
596
- self, path: str, name: Union[str, None] = None,
597
- ) -> Callable[[DecoratedCallable], DecoratedCallable]:
598
- def decorator(func: DecoratedCallable) -> DecoratedCallable:
588
+ self, path: str, name: str | None = None,
589
+ ) -> Callable[[WebSocketEndpointCallable], WebSocketEndpointCallable]:
590
+ def decorator(func: WebSocketEndpointCallable) -> WebSocketEndpointCallable:
599
591
  self.add_websocket_route(path, func, name=name)
600
592
  return func
601
593
 
@@ -606,12 +598,12 @@ class APIRouter(routing.Router):
606
598
  router: "APIRouter",
607
599
  *,
608
600
  prefix: str = "",
609
- tags: Optional[List[Union[str, Enum]]] = None,
610
- default_request_class: Type[Request] = Default(Request),
611
- default_response_class: Type[Response] = Default(JSONResponse),
612
- responses: Optional[Dict[Union[int, str], Dict[str, Any]]] = None,
613
- callbacks: Optional[List[BaseRoute]] = None,
614
- deprecated: Optional[bool] = None,
601
+ tags: list[str | Enum] | None = None,
602
+ default_request_class: type[Request] = Default(Request),
603
+ default_response_class: type[Response] = Default(JSONResponse),
604
+ responses: dict[int | str, dict[str, Any]] | None = None,
605
+ callbacks: list[BaseRoute] | None = None,
606
+ deprecated: bool | None = None,
615
607
  include_in_schema: bool = True,
616
608
  generate_unique_id_function: Callable[[APIRoute], str] = Default(generate_unique_id),
617
609
  ) -> None:
@@ -723,29 +715,29 @@ class APIRouter(routing.Router):
723
715
  self,
724
716
  path: str,
725
717
  *,
726
- name: str = None,
718
+ name: str | None = None,
727
719
  include_in_schema: bool = True,
728
- status_code: Optional[int] = None,
720
+ status_code: int | None = None,
729
721
  middleware: Sequence[Middleware] | None = None,
730
- deprecated: Optional[bool] = None,
731
- request_class: Type[Request] = Default(Request),
732
- response_model: Optional[Type[Any]] = None,
733
- response_class: Type[Response] = JSONResponse,
722
+ deprecated: bool | None = None,
723
+ request_class: type[Request] = Default(Request),
724
+ response_model: type[Any] | None = None,
725
+ response_class: type[Response] = JSONResponse,
734
726
  # OpenAPI summary
735
- summary: Optional[str] = None,
736
- description: Optional[str] = None,
727
+ summary: str | None = None,
728
+ description: str | None = None,
737
729
  response_description: str = "Successful Response",
738
- responses: Optional[Dict[Union[int, str], Dict[str, Any]]] = None,
739
- callbacks: Optional[List[BaseRoute]] = None,
730
+ responses: dict[int | str, dict[str, Any]] | None = None,
731
+ callbacks: list[BaseRoute] | None = None,
740
732
  # Sets the OpenAPI operationId to be used in your path operation
741
- operation_id: Optional[str] = None,
733
+ operation_id: str | None = None,
742
734
  # If operation_id is None, this function will be used to create one.
743
735
  generate_unique_id_function: Callable[["APIRoute"], str] = Default(generate_unique_id),
744
736
  # OpenAPI tags
745
- tags: Optional[List[Union[str, Enum]]] = None,
737
+ tags: list[str | Enum] | None = None,
746
738
  # Will be deeply merged with the automatically generated OpenAPI schema for the path operation.
747
- openapi_extra: Optional[Dict[str, Any]] = None,
748
- route_class: Optional[Type[APIRoute]] = None,
739
+ openapi_extra: dict[str, Any] | None = None,
740
+ route_class: type[APIRoute] | None = None,
749
741
  ):
750
742
  return self.api_route(
751
743
  path,
@@ -774,29 +766,29 @@ class APIRouter(routing.Router):
774
766
  self,
775
767
  path: str,
776
768
  *,
777
- name: str = None,
769
+ name: str | None = None,
778
770
  include_in_schema: bool = True,
779
- status_code: Optional[int] = None,
771
+ status_code: int | None = None,
780
772
  middleware: Sequence[Middleware] | None = None,
781
- deprecated: Optional[bool] = None,
782
- request_class: Type[Request] = Default(Request),
783
- response_model: Optional[Type[Any]] = None,
784
- response_class: Type[Response] = JSONResponse,
773
+ deprecated: bool | None = None,
774
+ request_class: type[Request] = Default(Request),
775
+ response_model: type[Any] | None = None,
776
+ response_class: type[Response] = JSONResponse,
785
777
  # OpenAPI summary
786
- summary: Optional[str] = None,
787
- description: Optional[str] = None,
778
+ summary: str | None = None,
779
+ description: str | None = None,
788
780
  response_description: str = "Successful Response",
789
- responses: Optional[Dict[Union[int, str], Dict[str, Any]]] = None,
790
- callbacks: Optional[List[BaseRoute]] = None,
781
+ responses: dict[int | str, dict[str, Any]] | None = None,
782
+ callbacks: list[BaseRoute] | None = None,
791
783
  # Sets the OpenAPI operationId to be used in your path operation
792
- operation_id: Optional[str] = None,
784
+ operation_id: str | None = None,
793
785
  # If operation_id is None, this function will be used to create one.
794
786
  generate_unique_id_function: Callable[["APIRoute"], str] = Default(generate_unique_id),
795
787
  # OpenAPI tags
796
- tags: Optional[List[Union[str, Enum]]] = None,
788
+ tags: list[str | Enum] | None = None,
797
789
  # Will be deeply merged with the automatically generated OpenAPI schema for the path operation.
798
- openapi_extra: Optional[Dict[str, Any]] = None,
799
- route_class: Optional[Type[APIRoute]] = None,
790
+ openapi_extra: dict[str, Any] | None = None,
791
+ route_class: type[APIRoute] | None = None,
800
792
  ):
801
793
  return self.api_route(
802
794
  path,
@@ -825,29 +817,29 @@ class APIRouter(routing.Router):
825
817
  self,
826
818
  path: str,
827
819
  *,
828
- name: str = None,
820
+ name: str | None = None,
829
821
  include_in_schema: bool = True,
830
- status_code: Optional[int] = None,
822
+ status_code: int | None = None,
831
823
  middleware: Sequence[Middleware] | None = None,
832
- deprecated: Optional[bool] = None,
833
- request_class: Type[Request] = Default(Request),
834
- response_model: Optional[Type[Any]] = None,
835
- response_class: Type[Response] = JSONResponse,
824
+ deprecated: bool | None = None,
825
+ request_class: type[Request] = Default(Request),
826
+ response_model: type[Any] | None = None,
827
+ response_class: type[Response] = JSONResponse,
836
828
  # OpenAPI summary
837
- summary: Optional[str] = None,
838
- description: Optional[str] = None,
829
+ summary: str | None = None,
830
+ description: str | None = None,
839
831
  response_description: str = "Successful Response",
840
- responses: Optional[Dict[Union[int, str], Dict[str, Any]]] = None,
841
- callbacks: Optional[List[BaseRoute]] = None,
832
+ responses: dict[int | str, dict[str, Any]] | None = None,
833
+ callbacks: list[BaseRoute] | None = None,
842
834
  # Sets the OpenAPI operationId to be used in your path operation
843
- operation_id: Optional[str] = None,
835
+ operation_id: str | None = None,
844
836
  # If operation_id is None, this function will be used to create one.
845
837
  generate_unique_id_function: Callable[["APIRoute"], str] = Default(generate_unique_id),
846
838
  # OpenAPI tags
847
- tags: Optional[List[Union[str, Enum]]] = None,
839
+ tags: list[str | Enum] | None = None,
848
840
  # Will be deeply merged with the automatically generated OpenAPI schema for the path operation.
849
- openapi_extra: Optional[Dict[str, Any]] = None,
850
- route_class: Optional[Type[APIRoute]] = None,
841
+ openapi_extra: dict[str, Any] | None = None,
842
+ route_class: type[APIRoute] | None = None,
851
843
  ):
852
844
  return self.api_route(
853
845
  path,
@@ -876,29 +868,29 @@ class APIRouter(routing.Router):
876
868
  self,
877
869
  path: str,
878
870
  *,
879
- name: str = None,
871
+ name: str | None = None,
880
872
  include_in_schema: bool = True,
881
- status_code: Optional[int] = None,
873
+ status_code: int | None = None,
882
874
  middleware: Sequence[Middleware] | None = None,
883
- deprecated: Optional[bool] = None,
884
- request_class: Type[Request] = Default(Request),
885
- response_model: Optional[Type[Any]] = None,
886
- response_class: Type[Response] = JSONResponse,
875
+ deprecated: bool | None = None,
876
+ request_class: type[Request] = Default(Request),
877
+ response_model: type[Any] | None = None,
878
+ response_class: type[Response] = JSONResponse,
887
879
  # OpenAPI summary
888
- summary: Optional[str] = None,
889
- description: Optional[str] = None,
880
+ summary: str | None = None,
881
+ description: str | None = None,
890
882
  response_description: str = "Successful Response",
891
- responses: Optional[Dict[Union[int, str], Dict[str, Any]]] = None,
892
- callbacks: Optional[List[BaseRoute]] = None,
883
+ responses: dict[int | str, dict[str, Any]] | None = None,
884
+ callbacks: list[BaseRoute] | None = None,
893
885
  # Sets the OpenAPI operationId to be used in your path operation
894
- operation_id: Optional[str] = None,
886
+ operation_id: str | None = None,
895
887
  # If operation_id is None, this function will be used to create one.
896
888
  generate_unique_id_function: Callable[["APIRoute"], str] = Default(generate_unique_id),
897
889
  # OpenAPI tags
898
- tags: Optional[List[Union[str, Enum]]] = None,
890
+ tags: list[str | Enum] | None = None,
899
891
  # Will be deeply merged with the automatically generated OpenAPI schema for the path operation.
900
- openapi_extra: Optional[Dict[str, Any]] = None,
901
- route_class: Optional[Type[APIRoute]] = None,
892
+ openapi_extra: dict[str, Any] | None = None,
893
+ route_class: type[APIRoute] | None = None,
902
894
  ):
903
895
  return self.api_route(
904
896
  path,
@@ -927,29 +919,29 @@ class APIRouter(routing.Router):
927
919
  self,
928
920
  path: str,
929
921
  *,
930
- name: str = None,
922
+ name: str | None = None,
931
923
  include_in_schema: bool = True,
932
- status_code: Optional[int] = None,
924
+ status_code: int | None = None,
933
925
  middleware: Sequence[Middleware] | None = None,
934
- deprecated: Optional[bool] = None,
935
- request_class: Type[Request] = Default(Request),
936
- response_model: Optional[Type[Any]] = None,
937
- response_class: Type[Response] = JSONResponse,
926
+ deprecated: bool | None = None,
927
+ request_class: type[Request] = Default(Request),
928
+ response_model: type[Any] | None = None,
929
+ response_class: type[Response] = JSONResponse,
938
930
  # OpenAPI summary
939
- summary: Optional[str] = None,
940
- description: Optional[str] = None,
931
+ summary: str | None = None,
932
+ description: str | None = None,
941
933
  response_description: str = "Successful Response",
942
- responses: Optional[Dict[Union[int, str], Dict[str, Any]]] = None,
943
- callbacks: Optional[List[BaseRoute]] = None,
934
+ responses: dict[int | str, dict[str, Any]] | None = None,
935
+ callbacks: list[BaseRoute] | None = None,
944
936
  # Sets the OpenAPI operationId to be used in your path operation
945
- operation_id: Optional[str] = None,
937
+ operation_id: str | None = None,
946
938
  # If operation_id is None, this function will be used to create one.
947
939
  generate_unique_id_function: Callable[["APIRoute"], str] = Default(generate_unique_id),
948
940
  # OpenAPI tags
949
- tags: Optional[List[Union[str, Enum]]] = None,
941
+ tags: list[str | Enum] | None = None,
950
942
  # Will be deeply merged with the automatically generated OpenAPI schema for the path operation.
951
- openapi_extra: Optional[Dict[str, Any]] = None,
952
- route_class: Optional[Type[APIRoute]] = None,
943
+ openapi_extra: dict[str, Any] | None = None,
944
+ route_class: type[APIRoute] | None = None,
953
945
  ):
954
946
  return self.api_route(
955
947
  path,
@@ -978,29 +970,29 @@ class APIRouter(routing.Router):
978
970
  self,
979
971
  path: str,
980
972
  *,
981
- name: str = None,
973
+ name: str | None = None,
982
974
  include_in_schema: bool = True,
983
- status_code: Optional[int] = None,
975
+ status_code: int | None = None,
984
976
  middleware: Sequence[Middleware] | None = None,
985
- deprecated: Optional[bool] = None,
986
- request_class: Type[Request] = Default(Request),
987
- response_model: Optional[Type[Any]] = None,
988
- response_class: Type[Response] = JSONResponse,
977
+ deprecated: bool | None = None,
978
+ request_class: type[Request] = Default(Request),
979
+ response_model: type[Any] | None = None,
980
+ response_class: type[Response] = JSONResponse,
989
981
  # OpenAPI summary
990
- summary: Optional[str] = None,
991
- description: Optional[str] = None,
982
+ summary: str | None = None,
983
+ description: str | None = None,
992
984
  response_description: str = "Successful Response",
993
- responses: Optional[Dict[Union[int, str], Dict[str, Any]]] = None,
994
- callbacks: Optional[List[BaseRoute]] = None,
985
+ responses: dict[int | str, dict[str, Any]] | None = None,
986
+ callbacks: list[BaseRoute] | None = None,
995
987
  # Sets the OpenAPI operationId to be used in your path operation
996
- operation_id: Optional[str] = None,
988
+ operation_id: str | None = None,
997
989
  # If operation_id is None, this function will be used to create one.
998
990
  generate_unique_id_function: Callable[["APIRoute"], str] = Default(generate_unique_id),
999
991
  # OpenAPI tags
1000
- tags: Optional[List[Union[str, Enum]]] = None,
992
+ tags: list[str | Enum] | None = None,
1001
993
  # Will be deeply merged with the automatically generated OpenAPI schema for the path operation.
1002
- openapi_extra: Optional[Dict[str, Any]] = None,
1003
- route_class: Optional[Type[APIRoute]] = None,
994
+ openapi_extra: dict[str, Any] | None = None,
995
+ route_class: type[APIRoute] | None = None,
1004
996
  ):
1005
997
  return self.api_route(
1006
998
  path,
@@ -1029,29 +1021,29 @@ class APIRouter(routing.Router):
1029
1021
  self,
1030
1022
  path: str,
1031
1023
  *,
1032
- name: str = None,
1024
+ name: str | None = None,
1033
1025
  include_in_schema: bool = True,
1034
- status_code: Optional[int] = None,
1026
+ status_code: int | None = None,
1035
1027
  middleware: Sequence[Middleware] | None = None,
1036
- deprecated: Optional[bool] = None,
1037
- request_class: Type[Request] = Default(Request),
1038
- response_model: Optional[Type[Any]] = None,
1039
- response_class: Type[Response] = JSONResponse,
1028
+ deprecated: bool | None = None,
1029
+ request_class: type[Request] = Default(Request),
1030
+ response_model: type[Any] | None = None,
1031
+ response_class: type[Response] = JSONResponse,
1040
1032
  # OpenAPI summary
1041
- summary: Optional[str] = None,
1042
- description: Optional[str] = None,
1033
+ summary: str | None = None,
1034
+ description: str | None = None,
1043
1035
  response_description: str = "Successful Response",
1044
- responses: Optional[Dict[Union[int, str], Dict[str, Any]]] = None,
1045
- callbacks: Optional[List[BaseRoute]] = None,
1036
+ responses: dict[int | str, dict[str, Any]] | None = None,
1037
+ callbacks: list[BaseRoute] | None = None,
1046
1038
  # Sets the OpenAPI operationId to be used in your path operation
1047
- operation_id: Optional[str] = None,
1039
+ operation_id: str | None = None,
1048
1040
  # If operation_id is None, this function will be used to create one.
1049
1041
  generate_unique_id_function: Callable[["APIRoute"], str] = Default(generate_unique_id),
1050
1042
  # OpenAPI tags
1051
- tags: Optional[List[Union[str, Enum]]] = None,
1043
+ tags: list[str | Enum] | None = None,
1052
1044
  # Will be deeply merged with the automatically generated OpenAPI schema for the path operation.
1053
- openapi_extra: Optional[Dict[str, Any]] = None,
1054
- route_class: Optional[Type[APIRoute]] = None,
1045
+ openapi_extra: dict[str, Any] | None = None,
1046
+ route_class: type[APIRoute] | None = None,
1055
1047
  ):
1056
1048
  return self.api_route(
1057
1049
  path,
@@ -1080,29 +1072,29 @@ class APIRouter(routing.Router):
1080
1072
  self,
1081
1073
  path: str,
1082
1074
  *,
1083
- name: str = None,
1075
+ name: str | None = None,
1084
1076
  include_in_schema: bool = True,
1085
- status_code: Optional[int] = None,
1077
+ status_code: int | None = None,
1086
1078
  middleware: Sequence[Middleware] | None = None,
1087
- deprecated: Optional[bool] = None,
1088
- request_class: Type[Request] = Default(Request),
1089
- response_model: Optional[Type[Any]] = None,
1090
- response_class: Type[Response] = JSONResponse,
1079
+ deprecated: bool | None = None,
1080
+ request_class: type[Request] = Default(Request),
1081
+ response_model: type[Any] | None = None,
1082
+ response_class: type[Response] = JSONResponse,
1091
1083
  # OpenAPI summary
1092
- summary: Optional[str] = None,
1093
- description: Optional[str] = None,
1084
+ summary: str | None = None,
1085
+ description: str | None = None,
1094
1086
  response_description: str = "Successful Response",
1095
- responses: Optional[Dict[Union[int, str], Dict[str, Any]]] = None,
1096
- callbacks: Optional[List[BaseRoute]] = None,
1087
+ responses: dict[int | str, dict[str, Any]] | None = None,
1088
+ callbacks: list[BaseRoute] | None = None,
1097
1089
  # Sets the OpenAPI operationId to be used in your path operation
1098
- operation_id: Optional[str] = None,
1090
+ operation_id: str | None = None,
1099
1091
  # If operation_id is None, this function will be used to create one.
1100
1092
  generate_unique_id_function: Callable[["APIRoute"], str] = Default(generate_unique_id),
1101
1093
  # OpenAPI tags
1102
- tags: Optional[List[Union[str, Enum]]] = None,
1094
+ tags: list[str | Enum] | None = None,
1103
1095
  # Will be deeply merged with the automatically generated OpenAPI schema for the path operation.
1104
- openapi_extra: Optional[Dict[str, Any]] = None,
1105
- route_class: Optional[Type[APIRoute]] = None,
1096
+ openapi_extra: dict[str, Any] | None = None,
1097
+ route_class: type[APIRoute] | None = None,
1106
1098
  ):
1107
1099
  return self.api_route(
1108
1100
  path,