starmallow 0.7.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/__init__.py +1 -1
- starmallow/applications.py +196 -232
- starmallow/background.py +1 -1
- starmallow/concurrency.py +8 -7
- starmallow/dataclasses.py +11 -10
- starmallow/datastructures.py +1 -1
- starmallow/decorators.py +31 -30
- starmallow/delimited_field.py +37 -15
- starmallow/docs.py +5 -5
- starmallow/endpoint.py +105 -79
- starmallow/endpoints.py +3 -2
- starmallow/exceptions.py +3 -3
- starmallow/ext/marshmallow/openapi.py +13 -16
- starmallow/fields.py +3 -3
- starmallow/generics.py +34 -0
- starmallow/middleware/asyncexitstack.py +1 -2
- starmallow/params.py +20 -21
- starmallow/py.typed +0 -0
- starmallow/request_resolver.py +62 -58
- starmallow/responses.py +5 -4
- starmallow/routing.py +231 -239
- starmallow/schema_generator.py +98 -52
- starmallow/security/api_key.py +11 -11
- starmallow/security/base.py +12 -4
- starmallow/security/http.py +31 -26
- starmallow/security/oauth2.py +48 -48
- starmallow/security/open_id_connect_url.py +7 -7
- starmallow/security/utils.py +2 -5
- starmallow/serializers.py +59 -63
- starmallow/types.py +12 -8
- starmallow/utils.py +114 -70
- starmallow/websockets.py +3 -6
- {starmallow-0.7.0.dist-info → starmallow-0.9.0.dist-info}/METADATA +17 -16
- starmallow-0.9.0.dist-info/RECORD +43 -0
- {starmallow-0.7.0.dist-info → starmallow-0.9.0.dist-info}/WHEEL +1 -1
- starmallow/union_field.py +0 -86
- starmallow-0.7.0.dist-info/RECORD +0 -42
- {starmallow-0.7.0.dist-info → starmallow-0.9.0.dist-info}/licenses/LICENSE.md +0 -0
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:
|
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],
|
82
|
-
request_class:
|
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],
|
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
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
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:
|
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[[
|
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:
|
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) ->
|
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:
|
221
|
-
methods:
|
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:
|
225
|
-
deprecated:
|
226
|
-
request_class:
|
227
|
-
|
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:
|
235
|
-
description:
|
221
|
+
summary: str | None = None,
|
222
|
+
description: str | None = None,
|
236
223
|
response_description: str = "Successful Response",
|
237
|
-
responses:
|
238
|
-
callbacks:
|
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:
|
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:
|
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:
|
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:
|
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
|
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
|
-
[
|
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:
|
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:
|
369
|
-
default_request_class:
|
370
|
-
default_response_class:
|
371
|
-
deprecated:
|
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:
|
374
|
-
callbacks:
|
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:
|
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:
|
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:
|
401
|
-
name:
|
386
|
+
methods: list[str] | None = None,
|
387
|
+
name: str | None = None,
|
402
388
|
include_in_schema: bool = True,
|
403
|
-
) -> Callable[[
|
404
|
-
def decorator(func:
|
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:
|
405
|
+
endpoint: Callable[..., Any] | type(APIHTTPEndpoint),
|
420
406
|
*,
|
421
|
-
methods:
|
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:
|
410
|
+
status_code: int | None = None,
|
425
411
|
middleware: Sequence[Middleware] | None = None,
|
426
|
-
deprecated:
|
427
|
-
request_class:
|
428
|
-
response_model:
|
429
|
-
response_class:
|
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:
|
432
|
-
description:
|
417
|
+
summary: str | None = None,
|
418
|
+
description: str | None = None,
|
433
419
|
response_description: str = "Successful Response",
|
434
|
-
responses:
|
435
|
-
callbacks:
|
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:
|
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:
|
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:
|
444
|
-
route_class:
|
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
|
-
|
456
|
-
|
457
|
-
|
458
|
-
|
459
|
-
|
460
|
-
|
461
|
-
|
462
|
-
endpoint_options
|
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:
|
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:
|
519
|
+
status_code: int | None = None,
|
528
520
|
middleware: Sequence[Middleware] | None = None,
|
529
|
-
deprecated:
|
530
|
-
request_class:
|
531
|
-
response_model:
|
532
|
-
response_class:
|
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:
|
535
|
-
description:
|
526
|
+
summary: str | None = None,
|
527
|
+
description: str | None = None,
|
536
528
|
response_description: str = "Successful Response",
|
537
|
-
responses:
|
538
|
-
callbacks:
|
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:
|
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:
|
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:
|
547
|
-
route_class:
|
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:
|
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:
|
588
|
-
) -> Callable[[
|
589
|
-
def decorator(func:
|
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:
|
597
|
-
) -> Callable[[
|
598
|
-
def decorator(func:
|
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:
|
610
|
-
default_request_class:
|
611
|
-
default_response_class:
|
612
|
-
responses:
|
613
|
-
callbacks:
|
614
|
-
deprecated:
|
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:
|
720
|
+
status_code: int | None = None,
|
729
721
|
middleware: Sequence[Middleware] | None = None,
|
730
|
-
deprecated:
|
731
|
-
request_class:
|
732
|
-
response_model:
|
733
|
-
response_class:
|
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:
|
736
|
-
description:
|
727
|
+
summary: str | None = None,
|
728
|
+
description: str | None = None,
|
737
729
|
response_description: str = "Successful Response",
|
738
|
-
responses:
|
739
|
-
callbacks:
|
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:
|
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:
|
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:
|
748
|
-
route_class:
|
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:
|
771
|
+
status_code: int | None = None,
|
780
772
|
middleware: Sequence[Middleware] | None = None,
|
781
|
-
deprecated:
|
782
|
-
request_class:
|
783
|
-
response_model:
|
784
|
-
response_class:
|
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:
|
787
|
-
description:
|
778
|
+
summary: str | None = None,
|
779
|
+
description: str | None = None,
|
788
780
|
response_description: str = "Successful Response",
|
789
|
-
responses:
|
790
|
-
callbacks:
|
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:
|
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:
|
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:
|
799
|
-
route_class:
|
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:
|
822
|
+
status_code: int | None = None,
|
831
823
|
middleware: Sequence[Middleware] | None = None,
|
832
|
-
deprecated:
|
833
|
-
request_class:
|
834
|
-
response_model:
|
835
|
-
response_class:
|
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:
|
838
|
-
description:
|
829
|
+
summary: str | None = None,
|
830
|
+
description: str | None = None,
|
839
831
|
response_description: str = "Successful Response",
|
840
|
-
responses:
|
841
|
-
callbacks:
|
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:
|
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:
|
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:
|
850
|
-
route_class:
|
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:
|
873
|
+
status_code: int | None = None,
|
882
874
|
middleware: Sequence[Middleware] | None = None,
|
883
|
-
deprecated:
|
884
|
-
request_class:
|
885
|
-
response_model:
|
886
|
-
response_class:
|
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:
|
889
|
-
description:
|
880
|
+
summary: str | None = None,
|
881
|
+
description: str | None = None,
|
890
882
|
response_description: str = "Successful Response",
|
891
|
-
responses:
|
892
|
-
callbacks:
|
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:
|
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:
|
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:
|
901
|
-
route_class:
|
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:
|
924
|
+
status_code: int | None = None,
|
933
925
|
middleware: Sequence[Middleware] | None = None,
|
934
|
-
deprecated:
|
935
|
-
request_class:
|
936
|
-
response_model:
|
937
|
-
response_class:
|
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:
|
940
|
-
description:
|
931
|
+
summary: str | None = None,
|
932
|
+
description: str | None = None,
|
941
933
|
response_description: str = "Successful Response",
|
942
|
-
responses:
|
943
|
-
callbacks:
|
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:
|
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:
|
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:
|
952
|
-
route_class:
|
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:
|
975
|
+
status_code: int | None = None,
|
984
976
|
middleware: Sequence[Middleware] | None = None,
|
985
|
-
deprecated:
|
986
|
-
request_class:
|
987
|
-
response_model:
|
988
|
-
response_class:
|
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:
|
991
|
-
description:
|
982
|
+
summary: str | None = None,
|
983
|
+
description: str | None = None,
|
992
984
|
response_description: str = "Successful Response",
|
993
|
-
responses:
|
994
|
-
callbacks:
|
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:
|
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:
|
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:
|
1003
|
-
route_class:
|
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:
|
1026
|
+
status_code: int | None = None,
|
1035
1027
|
middleware: Sequence[Middleware] | None = None,
|
1036
|
-
deprecated:
|
1037
|
-
request_class:
|
1038
|
-
response_model:
|
1039
|
-
response_class:
|
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:
|
1042
|
-
description:
|
1033
|
+
summary: str | None = None,
|
1034
|
+
description: str | None = None,
|
1043
1035
|
response_description: str = "Successful Response",
|
1044
|
-
responses:
|
1045
|
-
callbacks:
|
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:
|
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:
|
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:
|
1054
|
-
route_class:
|
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:
|
1077
|
+
status_code: int | None = None,
|
1086
1078
|
middleware: Sequence[Middleware] | None = None,
|
1087
|
-
deprecated:
|
1088
|
-
request_class:
|
1089
|
-
response_model:
|
1090
|
-
response_class:
|
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:
|
1093
|
-
description:
|
1084
|
+
summary: str | None = None,
|
1085
|
+
description: str | None = None,
|
1094
1086
|
response_description: str = "Successful Response",
|
1095
|
-
responses:
|
1096
|
-
callbacks:
|
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:
|
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:
|
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:
|
1105
|
-
route_class:
|
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,
|