prefect-client 2.19.3__py3-none-any.whl → 3.0.0rc1__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 (239) hide show
  1. prefect/__init__.py +8 -56
  2. prefect/_internal/compatibility/deprecated.py +6 -115
  3. prefect/_internal/compatibility/experimental.py +4 -79
  4. prefect/_internal/concurrency/api.py +0 -34
  5. prefect/_internal/concurrency/calls.py +0 -6
  6. prefect/_internal/concurrency/cancellation.py +0 -3
  7. prefect/_internal/concurrency/event_loop.py +0 -20
  8. prefect/_internal/concurrency/inspection.py +3 -3
  9. prefect/_internal/concurrency/threads.py +35 -0
  10. prefect/_internal/concurrency/waiters.py +0 -28
  11. prefect/_internal/pydantic/__init__.py +0 -45
  12. prefect/_internal/pydantic/v1_schema.py +21 -22
  13. prefect/_internal/pydantic/v2_schema.py +0 -2
  14. prefect/_internal/pydantic/v2_validated_func.py +18 -23
  15. prefect/_internal/schemas/bases.py +44 -177
  16. prefect/_internal/schemas/fields.py +1 -43
  17. prefect/_internal/schemas/validators.py +60 -158
  18. prefect/artifacts.py +161 -14
  19. prefect/automations.py +39 -4
  20. prefect/blocks/abstract.py +1 -1
  21. prefect/blocks/core.py +268 -148
  22. prefect/blocks/fields.py +2 -57
  23. prefect/blocks/kubernetes.py +8 -12
  24. prefect/blocks/notifications.py +40 -20
  25. prefect/blocks/system.py +22 -11
  26. prefect/blocks/webhook.py +2 -9
  27. prefect/client/base.py +4 -4
  28. prefect/client/cloud.py +8 -13
  29. prefect/client/orchestration.py +347 -341
  30. prefect/client/schemas/actions.py +92 -86
  31. prefect/client/schemas/filters.py +20 -40
  32. prefect/client/schemas/objects.py +147 -145
  33. prefect/client/schemas/responses.py +16 -24
  34. prefect/client/schemas/schedules.py +47 -35
  35. prefect/client/subscriptions.py +2 -2
  36. prefect/client/utilities.py +5 -2
  37. prefect/concurrency/asyncio.py +3 -1
  38. prefect/concurrency/events.py +1 -1
  39. prefect/concurrency/services.py +6 -3
  40. prefect/context.py +195 -27
  41. prefect/deployments/__init__.py +5 -6
  42. prefect/deployments/base.py +7 -5
  43. prefect/deployments/flow_runs.py +185 -0
  44. prefect/deployments/runner.py +50 -45
  45. prefect/deployments/schedules.py +28 -23
  46. prefect/deployments/steps/__init__.py +0 -1
  47. prefect/deployments/steps/core.py +1 -0
  48. prefect/deployments/steps/pull.py +7 -21
  49. prefect/engine.py +12 -2422
  50. prefect/events/actions.py +17 -23
  51. prefect/events/cli/automations.py +19 -6
  52. prefect/events/clients.py +14 -37
  53. prefect/events/filters.py +14 -18
  54. prefect/events/related.py +2 -2
  55. prefect/events/schemas/__init__.py +0 -5
  56. prefect/events/schemas/automations.py +55 -46
  57. prefect/events/schemas/deployment_triggers.py +7 -197
  58. prefect/events/schemas/events.py +34 -65
  59. prefect/events/schemas/labelling.py +10 -14
  60. prefect/events/utilities.py +2 -3
  61. prefect/events/worker.py +2 -3
  62. prefect/filesystems.py +6 -517
  63. prefect/{new_flow_engine.py → flow_engine.py} +313 -72
  64. prefect/flow_runs.py +377 -5
  65. prefect/flows.py +248 -165
  66. prefect/futures.py +186 -345
  67. prefect/infrastructure/__init__.py +0 -27
  68. prefect/infrastructure/provisioners/__init__.py +5 -3
  69. prefect/infrastructure/provisioners/cloud_run.py +11 -6
  70. prefect/infrastructure/provisioners/container_instance.py +11 -7
  71. prefect/infrastructure/provisioners/ecs.py +6 -4
  72. prefect/infrastructure/provisioners/modal.py +8 -5
  73. prefect/input/actions.py +2 -4
  74. prefect/input/run_input.py +5 -7
  75. prefect/logging/formatters.py +0 -2
  76. prefect/logging/handlers.py +3 -11
  77. prefect/logging/loggers.py +2 -2
  78. prefect/manifests.py +2 -1
  79. prefect/records/__init__.py +1 -0
  80. prefect/records/result_store.py +42 -0
  81. prefect/records/store.py +9 -0
  82. prefect/results.py +43 -39
  83. prefect/runner/runner.py +9 -9
  84. prefect/runner/server.py +6 -10
  85. prefect/runner/storage.py +3 -8
  86. prefect/runner/submit.py +2 -2
  87. prefect/runner/utils.py +2 -2
  88. prefect/serializers.py +24 -35
  89. prefect/server/api/collections_data/views/aggregate-worker-metadata.json +5 -14
  90. prefect/settings.py +70 -133
  91. prefect/states.py +17 -47
  92. prefect/task_engine.py +697 -58
  93. prefect/task_runners.py +269 -301
  94. prefect/task_server.py +53 -34
  95. prefect/tasks.py +327 -337
  96. prefect/transactions.py +220 -0
  97. prefect/types/__init__.py +61 -82
  98. prefect/utilities/asyncutils.py +195 -136
  99. prefect/utilities/callables.py +121 -41
  100. prefect/utilities/collections.py +23 -38
  101. prefect/utilities/dispatch.py +11 -3
  102. prefect/utilities/dockerutils.py +4 -0
  103. prefect/utilities/engine.py +140 -20
  104. prefect/utilities/importtools.py +26 -27
  105. prefect/utilities/pydantic.py +128 -38
  106. prefect/utilities/schema_tools/hydration.py +5 -1
  107. prefect/utilities/templating.py +12 -2
  108. prefect/variables.py +78 -61
  109. prefect/workers/__init__.py +0 -1
  110. prefect/workers/base.py +15 -17
  111. prefect/workers/process.py +3 -8
  112. prefect/workers/server.py +2 -2
  113. {prefect_client-2.19.3.dist-info → prefect_client-3.0.0rc1.dist-info}/METADATA +22 -21
  114. prefect_client-3.0.0rc1.dist-info/RECORD +176 -0
  115. prefect/_internal/pydantic/_base_model.py +0 -51
  116. prefect/_internal/pydantic/_compat.py +0 -82
  117. prefect/_internal/pydantic/_flags.py +0 -20
  118. prefect/_internal/pydantic/_types.py +0 -8
  119. prefect/_internal/pydantic/utilities/__init__.py +0 -0
  120. prefect/_internal/pydantic/utilities/config_dict.py +0 -72
  121. prefect/_internal/pydantic/utilities/field_validator.py +0 -150
  122. prefect/_internal/pydantic/utilities/model_construct.py +0 -56
  123. prefect/_internal/pydantic/utilities/model_copy.py +0 -55
  124. prefect/_internal/pydantic/utilities/model_dump.py +0 -136
  125. prefect/_internal/pydantic/utilities/model_dump_json.py +0 -112
  126. prefect/_internal/pydantic/utilities/model_fields.py +0 -50
  127. prefect/_internal/pydantic/utilities/model_fields_set.py +0 -29
  128. prefect/_internal/pydantic/utilities/model_json_schema.py +0 -82
  129. prefect/_internal/pydantic/utilities/model_rebuild.py +0 -80
  130. prefect/_internal/pydantic/utilities/model_validate.py +0 -75
  131. prefect/_internal/pydantic/utilities/model_validate_json.py +0 -68
  132. prefect/_internal/pydantic/utilities/model_validator.py +0 -87
  133. prefect/_internal/pydantic/utilities/type_adapter.py +0 -71
  134. prefect/_vendor/__init__.py +0 -0
  135. prefect/_vendor/fastapi/__init__.py +0 -25
  136. prefect/_vendor/fastapi/applications.py +0 -946
  137. prefect/_vendor/fastapi/background.py +0 -3
  138. prefect/_vendor/fastapi/concurrency.py +0 -44
  139. prefect/_vendor/fastapi/datastructures.py +0 -58
  140. prefect/_vendor/fastapi/dependencies/__init__.py +0 -0
  141. prefect/_vendor/fastapi/dependencies/models.py +0 -64
  142. prefect/_vendor/fastapi/dependencies/utils.py +0 -877
  143. prefect/_vendor/fastapi/encoders.py +0 -177
  144. prefect/_vendor/fastapi/exception_handlers.py +0 -40
  145. prefect/_vendor/fastapi/exceptions.py +0 -46
  146. prefect/_vendor/fastapi/logger.py +0 -3
  147. prefect/_vendor/fastapi/middleware/__init__.py +0 -1
  148. prefect/_vendor/fastapi/middleware/asyncexitstack.py +0 -25
  149. prefect/_vendor/fastapi/middleware/cors.py +0 -3
  150. prefect/_vendor/fastapi/middleware/gzip.py +0 -3
  151. prefect/_vendor/fastapi/middleware/httpsredirect.py +0 -3
  152. prefect/_vendor/fastapi/middleware/trustedhost.py +0 -3
  153. prefect/_vendor/fastapi/middleware/wsgi.py +0 -3
  154. prefect/_vendor/fastapi/openapi/__init__.py +0 -0
  155. prefect/_vendor/fastapi/openapi/constants.py +0 -2
  156. prefect/_vendor/fastapi/openapi/docs.py +0 -203
  157. prefect/_vendor/fastapi/openapi/models.py +0 -480
  158. prefect/_vendor/fastapi/openapi/utils.py +0 -485
  159. prefect/_vendor/fastapi/param_functions.py +0 -340
  160. prefect/_vendor/fastapi/params.py +0 -453
  161. prefect/_vendor/fastapi/requests.py +0 -4
  162. prefect/_vendor/fastapi/responses.py +0 -40
  163. prefect/_vendor/fastapi/routing.py +0 -1331
  164. prefect/_vendor/fastapi/security/__init__.py +0 -15
  165. prefect/_vendor/fastapi/security/api_key.py +0 -98
  166. prefect/_vendor/fastapi/security/base.py +0 -6
  167. prefect/_vendor/fastapi/security/http.py +0 -172
  168. prefect/_vendor/fastapi/security/oauth2.py +0 -227
  169. prefect/_vendor/fastapi/security/open_id_connect_url.py +0 -34
  170. prefect/_vendor/fastapi/security/utils.py +0 -10
  171. prefect/_vendor/fastapi/staticfiles.py +0 -1
  172. prefect/_vendor/fastapi/templating.py +0 -3
  173. prefect/_vendor/fastapi/testclient.py +0 -1
  174. prefect/_vendor/fastapi/types.py +0 -3
  175. prefect/_vendor/fastapi/utils.py +0 -235
  176. prefect/_vendor/fastapi/websockets.py +0 -7
  177. prefect/_vendor/starlette/__init__.py +0 -1
  178. prefect/_vendor/starlette/_compat.py +0 -28
  179. prefect/_vendor/starlette/_exception_handler.py +0 -80
  180. prefect/_vendor/starlette/_utils.py +0 -88
  181. prefect/_vendor/starlette/applications.py +0 -261
  182. prefect/_vendor/starlette/authentication.py +0 -159
  183. prefect/_vendor/starlette/background.py +0 -43
  184. prefect/_vendor/starlette/concurrency.py +0 -59
  185. prefect/_vendor/starlette/config.py +0 -151
  186. prefect/_vendor/starlette/convertors.py +0 -87
  187. prefect/_vendor/starlette/datastructures.py +0 -707
  188. prefect/_vendor/starlette/endpoints.py +0 -130
  189. prefect/_vendor/starlette/exceptions.py +0 -60
  190. prefect/_vendor/starlette/formparsers.py +0 -276
  191. prefect/_vendor/starlette/middleware/__init__.py +0 -17
  192. prefect/_vendor/starlette/middleware/authentication.py +0 -52
  193. prefect/_vendor/starlette/middleware/base.py +0 -220
  194. prefect/_vendor/starlette/middleware/cors.py +0 -176
  195. prefect/_vendor/starlette/middleware/errors.py +0 -265
  196. prefect/_vendor/starlette/middleware/exceptions.py +0 -74
  197. prefect/_vendor/starlette/middleware/gzip.py +0 -113
  198. prefect/_vendor/starlette/middleware/httpsredirect.py +0 -19
  199. prefect/_vendor/starlette/middleware/sessions.py +0 -82
  200. prefect/_vendor/starlette/middleware/trustedhost.py +0 -64
  201. prefect/_vendor/starlette/middleware/wsgi.py +0 -147
  202. prefect/_vendor/starlette/requests.py +0 -328
  203. prefect/_vendor/starlette/responses.py +0 -347
  204. prefect/_vendor/starlette/routing.py +0 -933
  205. prefect/_vendor/starlette/schemas.py +0 -154
  206. prefect/_vendor/starlette/staticfiles.py +0 -248
  207. prefect/_vendor/starlette/status.py +0 -199
  208. prefect/_vendor/starlette/templating.py +0 -231
  209. prefect/_vendor/starlette/testclient.py +0 -804
  210. prefect/_vendor/starlette/types.py +0 -30
  211. prefect/_vendor/starlette/websockets.py +0 -193
  212. prefect/agent.py +0 -698
  213. prefect/deployments/deployments.py +0 -1042
  214. prefect/deprecated/__init__.py +0 -0
  215. prefect/deprecated/data_documents.py +0 -350
  216. prefect/deprecated/packaging/__init__.py +0 -12
  217. prefect/deprecated/packaging/base.py +0 -96
  218. prefect/deprecated/packaging/docker.py +0 -146
  219. prefect/deprecated/packaging/file.py +0 -92
  220. prefect/deprecated/packaging/orion.py +0 -80
  221. prefect/deprecated/packaging/serializers.py +0 -171
  222. prefect/events/instrument.py +0 -135
  223. prefect/infrastructure/base.py +0 -323
  224. prefect/infrastructure/container.py +0 -818
  225. prefect/infrastructure/kubernetes.py +0 -920
  226. prefect/infrastructure/process.py +0 -289
  227. prefect/new_task_engine.py +0 -423
  228. prefect/pydantic/__init__.py +0 -76
  229. prefect/pydantic/main.py +0 -39
  230. prefect/software/__init__.py +0 -2
  231. prefect/software/base.py +0 -50
  232. prefect/software/conda.py +0 -199
  233. prefect/software/pip.py +0 -122
  234. prefect/software/python.py +0 -52
  235. prefect/workers/block.py +0 -218
  236. prefect_client-2.19.3.dist-info/RECORD +0 -292
  237. {prefect_client-2.19.3.dist-info → prefect_client-3.0.0rc1.dist-info}/LICENSE +0 -0
  238. {prefect_client-2.19.3.dist-info → prefect_client-3.0.0rc1.dist-info}/WHEEL +0 -0
  239. {prefect_client-2.19.3.dist-info → prefect_client-3.0.0rc1.dist-info}/top_level.txt +0 -0
@@ -1,1331 +0,0 @@
1
- import asyncio
2
- import dataclasses
3
- import email.message
4
- import inspect
5
- import json
6
- from contextlib import AsyncExitStack
7
- from enum import Enum, IntEnum
8
- from typing import (
9
- Any,
10
- Callable,
11
- Coroutine,
12
- Dict,
13
- List,
14
- Optional,
15
- Sequence,
16
- Set,
17
- Tuple,
18
- Type,
19
- Union,
20
- )
21
-
22
- from prefect._vendor.fastapi import params
23
- from prefect._vendor.fastapi.datastructures import Default, DefaultPlaceholder
24
- from prefect._vendor.fastapi.dependencies.models import Dependant
25
- from prefect._vendor.fastapi.dependencies.utils import (
26
- get_body_field,
27
- get_dependant,
28
- get_parameterless_sub_dependant,
29
- get_typed_return_annotation,
30
- solve_dependencies,
31
- )
32
- from prefect._vendor.fastapi.encoders import DictIntStrAny, SetIntStr, jsonable_encoder
33
- from prefect._vendor.fastapi.exceptions import (
34
- FastAPIError,
35
- RequestValidationError,
36
- WebSocketRequestValidationError,
37
- )
38
- from prefect._vendor.fastapi.types import DecoratedCallable
39
- from prefect._vendor.fastapi.utils import (
40
- create_cloned_field,
41
- create_response_field,
42
- generate_unique_id,
43
- get_value_or_default,
44
- is_body_allowed_for_status_code,
45
- )
46
-
47
- from prefect._internal.pydantic import HAS_PYDANTIC_V2
48
-
49
- if HAS_PYDANTIC_V2:
50
- from pydantic.v1 import BaseModel
51
- from pydantic.v1.error_wrappers import ErrorWrapper, ValidationError
52
- from pydantic.v1.fields import ModelField, Undefined
53
- from pydantic.v1.utils import lenient_issubclass
54
- else:
55
- from pydantic import BaseModel
56
- from pydantic.error_wrappers import ErrorWrapper, ValidationError
57
- from pydantic.fields import ModelField, Undefined
58
- from pydantic.utils import lenient_issubclass
59
-
60
- from prefect._vendor.starlette import routing
61
- from prefect._vendor.starlette.concurrency import run_in_threadpool
62
- from prefect._vendor.starlette.exceptions import HTTPException
63
- from prefect._vendor.starlette.requests import Request
64
- from prefect._vendor.starlette.responses import JSONResponse, Response
65
- from prefect._vendor.starlette.routing import (
66
- BaseRoute,
67
- Match,
68
- compile_path,
69
- get_name,
70
- request_response,
71
- websocket_session,
72
- )
73
- from prefect._vendor.starlette.routing import Mount as Mount # noqa
74
- from prefect._vendor.starlette.types import ASGIApp, Lifespan, Scope
75
- from prefect._vendor.starlette.websockets import WebSocket
76
-
77
-
78
- def _prepare_response_content(
79
- res: Any,
80
- *,
81
- exclude_unset: bool,
82
- exclude_defaults: bool = False,
83
- exclude_none: bool = False,
84
- ) -> Any:
85
- if isinstance(res, BaseModel):
86
- read_with_orm_mode = getattr(res.__config__, "read_with_orm_mode", None)
87
- if read_with_orm_mode:
88
- # Let from_orm extract the data from this model instead of converting
89
- # it now to a dict.
90
- # Otherwise there's no way to extract lazy data that requires attribute
91
- # access instead of dict iteration, e.g. lazy relationships.
92
- return res
93
- return res.dict(
94
- by_alias=True,
95
- exclude_unset=exclude_unset,
96
- exclude_defaults=exclude_defaults,
97
- exclude_none=exclude_none,
98
- )
99
- elif isinstance(res, list):
100
- return [
101
- _prepare_response_content(
102
- item,
103
- exclude_unset=exclude_unset,
104
- exclude_defaults=exclude_defaults,
105
- exclude_none=exclude_none,
106
- )
107
- for item in res
108
- ]
109
- elif isinstance(res, dict):
110
- return {
111
- k: _prepare_response_content(
112
- v,
113
- exclude_unset=exclude_unset,
114
- exclude_defaults=exclude_defaults,
115
- exclude_none=exclude_none,
116
- )
117
- for k, v in res.items()
118
- }
119
- elif dataclasses.is_dataclass(res):
120
- return dataclasses.asdict(res)
121
- return res
122
-
123
-
124
- async def serialize_response(
125
- *,
126
- field: Optional[ModelField] = None,
127
- response_content: Any,
128
- include: Optional[Union[SetIntStr, DictIntStrAny]] = None,
129
- exclude: Optional[Union[SetIntStr, DictIntStrAny]] = None,
130
- by_alias: bool = True,
131
- exclude_unset: bool = False,
132
- exclude_defaults: bool = False,
133
- exclude_none: bool = False,
134
- is_coroutine: bool = True,
135
- ) -> Any:
136
- if field:
137
- errors = []
138
- response_content = _prepare_response_content(
139
- response_content,
140
- exclude_unset=exclude_unset,
141
- exclude_defaults=exclude_defaults,
142
- exclude_none=exclude_none,
143
- )
144
- if is_coroutine:
145
- value, errors_ = field.validate(response_content, {}, loc=("response",))
146
- else:
147
- value, errors_ = await run_in_threadpool(
148
- field.validate, response_content, {}, loc=("response",)
149
- )
150
- if isinstance(errors_, ErrorWrapper):
151
- errors.append(errors_)
152
- elif isinstance(errors_, list):
153
- errors.extend(errors_)
154
- if errors:
155
- raise ValidationError(errors, field.type_)
156
- return jsonable_encoder(
157
- value,
158
- include=include,
159
- exclude=exclude,
160
- by_alias=by_alias,
161
- exclude_unset=exclude_unset,
162
- exclude_defaults=exclude_defaults,
163
- exclude_none=exclude_none,
164
- )
165
- else:
166
- return jsonable_encoder(response_content)
167
-
168
-
169
- async def run_endpoint_function(
170
- *, dependant: Dependant, values: Dict[str, Any], is_coroutine: bool
171
- ) -> Any:
172
- # Only called by get_request_handler. Has been split into its own function to
173
- # facilitate profiling endpoints, since inner functions are harder to profile.
174
- assert dependant.call is not None, "dependant.call must be a function"
175
-
176
- if is_coroutine:
177
- return await dependant.call(**values)
178
- else:
179
- return await run_in_threadpool(dependant.call, **values)
180
-
181
-
182
- def get_request_handler(
183
- dependant: Dependant,
184
- body_field: Optional[ModelField] = None,
185
- status_code: Optional[int] = None,
186
- response_class: Union[Type[Response], DefaultPlaceholder] = Default(JSONResponse),
187
- response_field: Optional[ModelField] = None,
188
- response_model_include: Optional[Union[SetIntStr, DictIntStrAny]] = None,
189
- response_model_exclude: Optional[Union[SetIntStr, DictIntStrAny]] = None,
190
- response_model_by_alias: bool = True,
191
- response_model_exclude_unset: bool = False,
192
- response_model_exclude_defaults: bool = False,
193
- response_model_exclude_none: bool = False,
194
- dependency_overrides_provider: Optional[Any] = None,
195
- ) -> Callable[[Request], Coroutine[Any, Any, Response]]:
196
- assert dependant.call is not None, "dependant.call must be a function"
197
- is_coroutine = asyncio.iscoroutinefunction(dependant.call)
198
- is_body_form = body_field and isinstance(body_field.field_info, params.Form)
199
- if isinstance(response_class, DefaultPlaceholder):
200
- actual_response_class: Type[Response] = response_class.value
201
- else:
202
- actual_response_class = response_class
203
-
204
- async def app(request: Request) -> Response:
205
- try:
206
- body: Any = None
207
- if body_field:
208
- if is_body_form:
209
- body = await request.form()
210
- stack = request.scope.get("fastapi_astack")
211
- assert isinstance(stack, AsyncExitStack)
212
- stack.push_async_callback(body.close)
213
- else:
214
- body_bytes = await request.body()
215
- if body_bytes:
216
- json_body: Any = Undefined
217
- content_type_value = request.headers.get("content-type")
218
- if not content_type_value:
219
- json_body = await request.json()
220
- else:
221
- message = email.message.Message()
222
- message["content-type"] = content_type_value
223
- if message.get_content_maintype() == "application":
224
- subtype = message.get_content_subtype()
225
- if subtype == "json" or subtype.endswith("+json"):
226
- json_body = await request.json()
227
- if json_body != Undefined:
228
- body = json_body
229
- else:
230
- body = body_bytes
231
- except json.JSONDecodeError as e:
232
- raise RequestValidationError(
233
- [ErrorWrapper(e, ("body", e.pos))], body=e.doc
234
- ) from e
235
- except HTTPException:
236
- raise
237
- except Exception as e:
238
- raise HTTPException(
239
- status_code=400, detail="There was an error parsing the body"
240
- ) from e
241
- solved_result = await solve_dependencies(
242
- request=request,
243
- dependant=dependant,
244
- body=body,
245
- dependency_overrides_provider=dependency_overrides_provider,
246
- )
247
- values, errors, background_tasks, sub_response, _ = solved_result
248
- if errors:
249
- raise RequestValidationError(errors, body=body)
250
- else:
251
- raw_response = await run_endpoint_function(
252
- dependant=dependant, values=values, is_coroutine=is_coroutine
253
- )
254
-
255
- if isinstance(raw_response, Response):
256
- if raw_response.background is None:
257
- raw_response.background = background_tasks
258
- return raw_response
259
- response_args: Dict[str, Any] = {"background": background_tasks}
260
- # If status_code was set, use it, otherwise use the default from the
261
- # response class, in the case of redirect it's 307
262
- current_status_code = (
263
- status_code if status_code else sub_response.status_code
264
- )
265
- if current_status_code is not None:
266
- response_args["status_code"] = current_status_code
267
- if sub_response.status_code:
268
- response_args["status_code"] = sub_response.status_code
269
- content = await serialize_response(
270
- field=response_field,
271
- response_content=raw_response,
272
- include=response_model_include,
273
- exclude=response_model_exclude,
274
- by_alias=response_model_by_alias,
275
- exclude_unset=response_model_exclude_unset,
276
- exclude_defaults=response_model_exclude_defaults,
277
- exclude_none=response_model_exclude_none,
278
- is_coroutine=is_coroutine,
279
- )
280
- response = actual_response_class(content, **response_args)
281
- if not is_body_allowed_for_status_code(response.status_code):
282
- response.body = b""
283
- response.headers.raw.extend(sub_response.headers.raw)
284
- return response
285
-
286
- return app
287
-
288
-
289
- def get_websocket_app(
290
- dependant: Dependant, dependency_overrides_provider: Optional[Any] = None
291
- ) -> Callable[[WebSocket], Coroutine[Any, Any, Any]]:
292
- async def app(websocket: WebSocket) -> None:
293
- solved_result = await solve_dependencies(
294
- request=websocket,
295
- dependant=dependant,
296
- dependency_overrides_provider=dependency_overrides_provider,
297
- )
298
- values, errors, _, _2, _3 = solved_result
299
- if errors:
300
- raise WebSocketRequestValidationError(errors)
301
- assert dependant.call is not None, "dependant.call must be a function"
302
- await dependant.call(**values)
303
-
304
- return app
305
-
306
-
307
- class APIWebSocketRoute(routing.WebSocketRoute):
308
- def __init__(
309
- self,
310
- path: str,
311
- endpoint: Callable[..., Any],
312
- *,
313
- name: Optional[str] = None,
314
- dependencies: Optional[Sequence[params.Depends]] = None,
315
- dependency_overrides_provider: Optional[Any] = None,
316
- ) -> None:
317
- self.path = path
318
- self.endpoint = endpoint
319
- self.name = get_name(endpoint) if name is None else name
320
- self.dependencies = list(dependencies or [])
321
- self.path_regex, self.path_format, self.param_convertors = compile_path(path)
322
- self.dependant = get_dependant(path=self.path_format, call=self.endpoint)
323
- for depends in self.dependencies[::-1]:
324
- self.dependant.dependencies.insert(
325
- 0,
326
- get_parameterless_sub_dependant(depends=depends, path=self.path_format),
327
- )
328
-
329
- self.app = websocket_session(
330
- get_websocket_app(
331
- dependant=self.dependant,
332
- dependency_overrides_provider=dependency_overrides_provider,
333
- )
334
- )
335
-
336
- def matches(self, scope: Scope) -> Tuple[Match, Scope]:
337
- match, child_scope = super().matches(scope)
338
- if match != Match.NONE:
339
- child_scope["route"] = self
340
- return match, child_scope
341
-
342
-
343
- class APIRoute(routing.Route):
344
- def __init__(
345
- self,
346
- path: str,
347
- endpoint: Callable[..., Any],
348
- *,
349
- response_model: Any = Default(None),
350
- status_code: Optional[int] = None,
351
- tags: Optional[List[Union[str, Enum]]] = None,
352
- dependencies: Optional[Sequence[params.Depends]] = None,
353
- summary: Optional[str] = None,
354
- description: Optional[str] = None,
355
- response_description: str = "Successful Response",
356
- responses: Optional[Dict[Union[int, str], Dict[str, Any]]] = None,
357
- deprecated: Optional[bool] = None,
358
- name: Optional[str] = None,
359
- methods: Optional[Union[Set[str], List[str]]] = None,
360
- operation_id: Optional[str] = None,
361
- response_model_include: Optional[Union[SetIntStr, DictIntStrAny]] = None,
362
- response_model_exclude: Optional[Union[SetIntStr, DictIntStrAny]] = None,
363
- response_model_by_alias: bool = True,
364
- response_model_exclude_unset: bool = False,
365
- response_model_exclude_defaults: bool = False,
366
- response_model_exclude_none: bool = False,
367
- include_in_schema: bool = True,
368
- response_class: Union[Type[Response], DefaultPlaceholder] = Default(
369
- JSONResponse
370
- ),
371
- dependency_overrides_provider: Optional[Any] = None,
372
- callbacks: Optional[List[BaseRoute]] = None,
373
- openapi_extra: Optional[Dict[str, Any]] = None,
374
- generate_unique_id_function: Union[
375
- Callable[["APIRoute"], str], DefaultPlaceholder
376
- ] = Default(generate_unique_id),
377
- ) -> None:
378
- self.path = path
379
- self.endpoint = endpoint
380
- if isinstance(response_model, DefaultPlaceholder):
381
- return_annotation = get_typed_return_annotation(endpoint)
382
- if lenient_issubclass(return_annotation, Response):
383
- response_model = None
384
- else:
385
- response_model = return_annotation
386
- self.response_model = response_model
387
- self.summary = summary
388
- self.response_description = response_description
389
- self.deprecated = deprecated
390
- self.operation_id = operation_id
391
- self.response_model_include = response_model_include
392
- self.response_model_exclude = response_model_exclude
393
- self.response_model_by_alias = response_model_by_alias
394
- self.response_model_exclude_unset = response_model_exclude_unset
395
- self.response_model_exclude_defaults = response_model_exclude_defaults
396
- self.response_model_exclude_none = response_model_exclude_none
397
- self.include_in_schema = include_in_schema
398
- self.response_class = response_class
399
- self.dependency_overrides_provider = dependency_overrides_provider
400
- self.callbacks = callbacks
401
- self.openapi_extra = openapi_extra
402
- self.generate_unique_id_function = generate_unique_id_function
403
- self.tags = tags or []
404
- self.responses = responses or {}
405
- self.name = get_name(endpoint) if name is None else name
406
- self.path_regex, self.path_format, self.param_convertors = compile_path(path)
407
- if methods is None:
408
- methods = ["GET"]
409
- self.methods: Set[str] = {method.upper() for method in methods}
410
- if isinstance(generate_unique_id_function, DefaultPlaceholder):
411
- current_generate_unique_id: Callable[
412
- ["APIRoute"], str
413
- ] = generate_unique_id_function.value
414
- else:
415
- current_generate_unique_id = generate_unique_id_function
416
- self.unique_id = self.operation_id or current_generate_unique_id(self)
417
- # normalize enums e.g. http.HTTPStatus
418
- if isinstance(status_code, IntEnum):
419
- status_code = int(status_code)
420
- self.status_code = status_code
421
- if self.response_model:
422
- assert is_body_allowed_for_status_code(
423
- status_code
424
- ), f"Status code {status_code} must not have a response body"
425
- response_name = "Response_" + self.unique_id
426
- self.response_field = create_response_field(
427
- name=response_name, type_=self.response_model
428
- )
429
- # Create a clone of the field, so that a Pydantic submodel is not returned
430
- # as is just because it's an instance of a subclass of a more limited class
431
- # e.g. UserInDB (containing hashed_password) could be a subclass of User
432
- # that doesn't have the hashed_password. But because it's a subclass, it
433
- # would pass the validation and be returned as is.
434
- # By being a new field, no inheritance will be passed as is. A new model
435
- # will be always created.
436
- self.secure_cloned_response_field: Optional[
437
- ModelField
438
- ] = create_cloned_field(self.response_field)
439
- else:
440
- self.response_field = None # type: ignore
441
- self.secure_cloned_response_field = None
442
- self.dependencies = list(dependencies or [])
443
- self.description = description or inspect.cleandoc(self.endpoint.__doc__ or "")
444
- # if a "form feed" character (page break) is found in the description text,
445
- # truncate description text to the content preceding the first "form feed"
446
- self.description = self.description.split("\f")[0].strip()
447
- response_fields = {}
448
- for additional_status_code, response in self.responses.items():
449
- assert isinstance(response, dict), "An additional response must be a dict"
450
- model = response.get("model")
451
- if model:
452
- assert is_body_allowed_for_status_code(
453
- additional_status_code
454
- ), f"Status code {additional_status_code} must not have a response body"
455
- response_name = f"Response_{additional_status_code}_{self.unique_id}"
456
- response_field = create_response_field(name=response_name, type_=model)
457
- response_fields[additional_status_code] = response_field
458
- if response_fields:
459
- self.response_fields: Dict[Union[int, str], ModelField] = response_fields
460
- else:
461
- self.response_fields = {}
462
-
463
- assert callable(endpoint), "An endpoint must be a callable"
464
- self.dependant = get_dependant(path=self.path_format, call=self.endpoint)
465
- for depends in self.dependencies[::-1]:
466
- self.dependant.dependencies.insert(
467
- 0,
468
- get_parameterless_sub_dependant(depends=depends, path=self.path_format),
469
- )
470
- self.body_field = get_body_field(dependant=self.dependant, name=self.unique_id)
471
- self.app = request_response(self.get_route_handler())
472
-
473
- def get_route_handler(self) -> Callable[[Request], Coroutine[Any, Any, Response]]:
474
- return get_request_handler(
475
- dependant=self.dependant,
476
- body_field=self.body_field,
477
- status_code=self.status_code,
478
- response_class=self.response_class,
479
- response_field=self.secure_cloned_response_field,
480
- response_model_include=self.response_model_include,
481
- response_model_exclude=self.response_model_exclude,
482
- response_model_by_alias=self.response_model_by_alias,
483
- response_model_exclude_unset=self.response_model_exclude_unset,
484
- response_model_exclude_defaults=self.response_model_exclude_defaults,
485
- response_model_exclude_none=self.response_model_exclude_none,
486
- dependency_overrides_provider=self.dependency_overrides_provider,
487
- )
488
-
489
- def matches(self, scope: Scope) -> Tuple[Match, Scope]:
490
- match, child_scope = super().matches(scope)
491
- if match != Match.NONE:
492
- child_scope["route"] = self
493
- return match, child_scope
494
-
495
-
496
- class APIRouter(routing.Router):
497
- def __init__(
498
- self,
499
- *,
500
- prefix: str = "",
501
- tags: Optional[List[Union[str, Enum]]] = None,
502
- dependencies: Optional[Sequence[params.Depends]] = None,
503
- default_response_class: Type[Response] = Default(JSONResponse),
504
- responses: Optional[Dict[Union[int, str], Dict[str, Any]]] = None,
505
- callbacks: Optional[List[BaseRoute]] = None,
506
- routes: Optional[List[routing.BaseRoute]] = None,
507
- redirect_slashes: bool = True,
508
- default: Optional[ASGIApp] = None,
509
- dependency_overrides_provider: Optional[Any] = None,
510
- route_class: Type[APIRoute] = APIRoute,
511
- on_startup: Optional[Sequence[Callable[[], Any]]] = None,
512
- on_shutdown: Optional[Sequence[Callable[[], Any]]] = None,
513
- # the generic to Lifespan[AppType] is the type of the top level application
514
- # which the router cannot know statically, so we use typing.Any
515
- lifespan: Optional[Lifespan[Any]] = None,
516
- deprecated: Optional[bool] = None,
517
- include_in_schema: bool = True,
518
- generate_unique_id_function: Callable[[APIRoute], str] = Default(
519
- generate_unique_id
520
- ),
521
- ) -> None:
522
- super().__init__(
523
- routes=routes,
524
- redirect_slashes=redirect_slashes,
525
- default=default,
526
- on_startup=on_startup,
527
- on_shutdown=on_shutdown,
528
- lifespan=lifespan,
529
- )
530
- if prefix:
531
- assert prefix.startswith("/"), "A path prefix must start with '/'"
532
- assert not prefix.endswith(
533
- "/"
534
- ), "A path prefix must not end with '/', as the routes will start with '/'"
535
- self.prefix = prefix
536
- self.tags: List[Union[str, Enum]] = tags or []
537
- self.dependencies = list(dependencies or [])
538
- self.deprecated = deprecated
539
- self.include_in_schema = include_in_schema
540
- self.responses = responses or {}
541
- self.callbacks = callbacks or []
542
- self.dependency_overrides_provider = dependency_overrides_provider
543
- self.route_class = route_class
544
- self.default_response_class = default_response_class
545
- self.generate_unique_id_function = generate_unique_id_function
546
-
547
- def route(
548
- self,
549
- path: str,
550
- methods: Optional[List[str]] = None,
551
- name: Optional[str] = None,
552
- include_in_schema: bool = True,
553
- ) -> Callable[[DecoratedCallable], DecoratedCallable]:
554
- def decorator(func: DecoratedCallable) -> DecoratedCallable:
555
- self.add_route(
556
- path,
557
- func,
558
- methods=methods,
559
- name=name,
560
- include_in_schema=include_in_schema,
561
- )
562
- return func
563
-
564
- return decorator
565
-
566
- def add_api_route(
567
- self,
568
- path: str,
569
- endpoint: Callable[..., Any],
570
- *,
571
- response_model: Any = Default(None),
572
- status_code: Optional[int] = None,
573
- tags: Optional[List[Union[str, Enum]]] = None,
574
- dependencies: Optional[Sequence[params.Depends]] = None,
575
- summary: Optional[str] = None,
576
- description: Optional[str] = None,
577
- response_description: str = "Successful Response",
578
- responses: Optional[Dict[Union[int, str], Dict[str, Any]]] = None,
579
- deprecated: Optional[bool] = None,
580
- methods: Optional[Union[Set[str], List[str]]] = None,
581
- operation_id: Optional[str] = None,
582
- response_model_include: Optional[Union[SetIntStr, DictIntStrAny]] = None,
583
- response_model_exclude: Optional[Union[SetIntStr, DictIntStrAny]] = None,
584
- response_model_by_alias: bool = True,
585
- response_model_exclude_unset: bool = False,
586
- response_model_exclude_defaults: bool = False,
587
- response_model_exclude_none: bool = False,
588
- include_in_schema: bool = True,
589
- response_class: Union[Type[Response], DefaultPlaceholder] = Default(
590
- JSONResponse
591
- ),
592
- name: Optional[str] = None,
593
- route_class_override: Optional[Type[APIRoute]] = None,
594
- callbacks: Optional[List[BaseRoute]] = None,
595
- openapi_extra: Optional[Dict[str, Any]] = None,
596
- generate_unique_id_function: Union[
597
- Callable[[APIRoute], str], DefaultPlaceholder
598
- ] = Default(generate_unique_id),
599
- ) -> None:
600
- route_class = route_class_override or self.route_class
601
- responses = responses or {}
602
- combined_responses = {**self.responses, **responses}
603
- current_response_class = get_value_or_default(
604
- response_class, self.default_response_class
605
- )
606
- current_tags = self.tags.copy()
607
- if tags:
608
- current_tags.extend(tags)
609
- current_dependencies = self.dependencies.copy()
610
- if dependencies:
611
- current_dependencies.extend(dependencies)
612
- current_callbacks = self.callbacks.copy()
613
- if callbacks:
614
- current_callbacks.extend(callbacks)
615
- current_generate_unique_id = get_value_or_default(
616
- generate_unique_id_function, self.generate_unique_id_function
617
- )
618
- route = route_class(
619
- self.prefix + path,
620
- endpoint=endpoint,
621
- response_model=response_model,
622
- status_code=status_code,
623
- tags=current_tags,
624
- dependencies=current_dependencies,
625
- summary=summary,
626
- description=description,
627
- response_description=response_description,
628
- responses=combined_responses,
629
- deprecated=deprecated or self.deprecated,
630
- methods=methods,
631
- operation_id=operation_id,
632
- response_model_include=response_model_include,
633
- response_model_exclude=response_model_exclude,
634
- response_model_by_alias=response_model_by_alias,
635
- response_model_exclude_unset=response_model_exclude_unset,
636
- response_model_exclude_defaults=response_model_exclude_defaults,
637
- response_model_exclude_none=response_model_exclude_none,
638
- include_in_schema=include_in_schema and self.include_in_schema,
639
- response_class=current_response_class,
640
- name=name,
641
- dependency_overrides_provider=self.dependency_overrides_provider,
642
- callbacks=current_callbacks,
643
- openapi_extra=openapi_extra,
644
- generate_unique_id_function=current_generate_unique_id,
645
- )
646
- self.routes.append(route)
647
-
648
- def api_route(
649
- self,
650
- path: str,
651
- *,
652
- response_model: Any = Default(None),
653
- status_code: Optional[int] = None,
654
- tags: Optional[List[Union[str, Enum]]] = None,
655
- dependencies: Optional[Sequence[params.Depends]] = None,
656
- summary: Optional[str] = None,
657
- description: Optional[str] = None,
658
- response_description: str = "Successful Response",
659
- responses: Optional[Dict[Union[int, str], Dict[str, Any]]] = None,
660
- deprecated: Optional[bool] = None,
661
- methods: Optional[List[str]] = None,
662
- operation_id: Optional[str] = None,
663
- response_model_include: Optional[Union[SetIntStr, DictIntStrAny]] = None,
664
- response_model_exclude: Optional[Union[SetIntStr, DictIntStrAny]] = None,
665
- response_model_by_alias: bool = True,
666
- response_model_exclude_unset: bool = False,
667
- response_model_exclude_defaults: bool = False,
668
- response_model_exclude_none: bool = False,
669
- include_in_schema: bool = True,
670
- response_class: Type[Response] = Default(JSONResponse),
671
- name: Optional[str] = None,
672
- callbacks: Optional[List[BaseRoute]] = None,
673
- openapi_extra: Optional[Dict[str, Any]] = None,
674
- generate_unique_id_function: Callable[[APIRoute], str] = Default(
675
- generate_unique_id
676
- ),
677
- ) -> Callable[[DecoratedCallable], DecoratedCallable]:
678
- def decorator(func: DecoratedCallable) -> DecoratedCallable:
679
- self.add_api_route(
680
- path,
681
- func,
682
- response_model=response_model,
683
- status_code=status_code,
684
- tags=tags,
685
- dependencies=dependencies,
686
- summary=summary,
687
- description=description,
688
- response_description=response_description,
689
- responses=responses,
690
- deprecated=deprecated,
691
- methods=methods,
692
- operation_id=operation_id,
693
- response_model_include=response_model_include,
694
- response_model_exclude=response_model_exclude,
695
- response_model_by_alias=response_model_by_alias,
696
- response_model_exclude_unset=response_model_exclude_unset,
697
- response_model_exclude_defaults=response_model_exclude_defaults,
698
- response_model_exclude_none=response_model_exclude_none,
699
- include_in_schema=include_in_schema,
700
- response_class=response_class,
701
- name=name,
702
- callbacks=callbacks,
703
- openapi_extra=openapi_extra,
704
- generate_unique_id_function=generate_unique_id_function,
705
- )
706
- return func
707
-
708
- return decorator
709
-
710
- def add_api_websocket_route(
711
- self,
712
- path: str,
713
- endpoint: Callable[..., Any],
714
- name: Optional[str] = None,
715
- *,
716
- dependencies: Optional[Sequence[params.Depends]] = None,
717
- ) -> None:
718
- current_dependencies = self.dependencies.copy()
719
- if dependencies:
720
- current_dependencies.extend(dependencies)
721
-
722
- route = APIWebSocketRoute(
723
- self.prefix + path,
724
- endpoint=endpoint,
725
- name=name,
726
- dependencies=current_dependencies,
727
- dependency_overrides_provider=self.dependency_overrides_provider,
728
- )
729
- self.routes.append(route)
730
-
731
- def websocket(
732
- self,
733
- path: str,
734
- name: Optional[str] = None,
735
- *,
736
- dependencies: Optional[Sequence[params.Depends]] = None,
737
- ) -> Callable[[DecoratedCallable], DecoratedCallable]:
738
- def decorator(func: DecoratedCallable) -> DecoratedCallable:
739
- self.add_api_websocket_route(
740
- path, func, name=name, dependencies=dependencies
741
- )
742
- return func
743
-
744
- return decorator
745
-
746
- def websocket_route(
747
- self, path: str, name: Union[str, None] = None
748
- ) -> Callable[[DecoratedCallable], DecoratedCallable]:
749
- def decorator(func: DecoratedCallable) -> DecoratedCallable:
750
- self.add_websocket_route(path, func, name=name)
751
- return func
752
-
753
- return decorator
754
-
755
- def include_router(
756
- self,
757
- router: "APIRouter",
758
- *,
759
- prefix: str = "",
760
- tags: Optional[List[Union[str, Enum]]] = None,
761
- dependencies: Optional[Sequence[params.Depends]] = None,
762
- default_response_class: Type[Response] = Default(JSONResponse),
763
- responses: Optional[Dict[Union[int, str], Dict[str, Any]]] = None,
764
- callbacks: Optional[List[BaseRoute]] = None,
765
- deprecated: Optional[bool] = None,
766
- include_in_schema: bool = True,
767
- generate_unique_id_function: Callable[[APIRoute], str] = Default(
768
- generate_unique_id
769
- ),
770
- ) -> None:
771
- if prefix:
772
- assert prefix.startswith("/"), "A path prefix must start with '/'"
773
- assert not prefix.endswith(
774
- "/"
775
- ), "A path prefix must not end with '/', as the routes will start with '/'"
776
- else:
777
- for r in router.routes:
778
- path = getattr(r, "path") # noqa: B009
779
- name = getattr(r, "name", "unknown")
780
- if path is not None and not path:
781
- raise FastAPIError(
782
- f"Prefix and path cannot be both empty (path operation: {name})"
783
- )
784
- if responses is None:
785
- responses = {}
786
- for route in router.routes:
787
- if isinstance(route, APIRoute):
788
- combined_responses = {**responses, **route.responses}
789
- use_response_class = get_value_or_default(
790
- route.response_class,
791
- router.default_response_class,
792
- default_response_class,
793
- self.default_response_class,
794
- )
795
- current_tags = []
796
- if tags:
797
- current_tags.extend(tags)
798
- if route.tags:
799
- current_tags.extend(route.tags)
800
- current_dependencies: List[params.Depends] = []
801
- if dependencies:
802
- current_dependencies.extend(dependencies)
803
- if route.dependencies:
804
- current_dependencies.extend(route.dependencies)
805
- current_callbacks = []
806
- if callbacks:
807
- current_callbacks.extend(callbacks)
808
- if route.callbacks:
809
- current_callbacks.extend(route.callbacks)
810
- current_generate_unique_id = get_value_or_default(
811
- route.generate_unique_id_function,
812
- router.generate_unique_id_function,
813
- generate_unique_id_function,
814
- self.generate_unique_id_function,
815
- )
816
- self.add_api_route(
817
- prefix + route.path,
818
- route.endpoint,
819
- response_model=route.response_model,
820
- status_code=route.status_code,
821
- tags=current_tags,
822
- dependencies=current_dependencies,
823
- summary=route.summary,
824
- description=route.description,
825
- response_description=route.response_description,
826
- responses=combined_responses,
827
- deprecated=route.deprecated or deprecated or self.deprecated,
828
- methods=route.methods,
829
- operation_id=route.operation_id,
830
- response_model_include=route.response_model_include,
831
- response_model_exclude=route.response_model_exclude,
832
- response_model_by_alias=route.response_model_by_alias,
833
- response_model_exclude_unset=route.response_model_exclude_unset,
834
- response_model_exclude_defaults=route.response_model_exclude_defaults,
835
- response_model_exclude_none=route.response_model_exclude_none,
836
- include_in_schema=route.include_in_schema
837
- and self.include_in_schema
838
- and include_in_schema,
839
- response_class=use_response_class,
840
- name=route.name,
841
- route_class_override=type(route),
842
- callbacks=current_callbacks,
843
- openapi_extra=route.openapi_extra,
844
- generate_unique_id_function=current_generate_unique_id,
845
- )
846
- elif isinstance(route, routing.Route):
847
- methods = list(route.methods or [])
848
- self.add_route(
849
- prefix + route.path,
850
- route.endpoint,
851
- methods=methods,
852
- include_in_schema=route.include_in_schema,
853
- name=route.name,
854
- )
855
- elif isinstance(route, APIWebSocketRoute):
856
- current_dependencies = []
857
- if dependencies:
858
- current_dependencies.extend(dependencies)
859
- if route.dependencies:
860
- current_dependencies.extend(route.dependencies)
861
- self.add_api_websocket_route(
862
- prefix + route.path,
863
- route.endpoint,
864
- dependencies=current_dependencies,
865
- name=route.name,
866
- )
867
- elif isinstance(route, routing.WebSocketRoute):
868
- self.add_websocket_route(
869
- prefix + route.path, route.endpoint, name=route.name
870
- )
871
- for handler in router.on_startup:
872
- self.add_event_handler("startup", handler)
873
- for handler in router.on_shutdown:
874
- self.add_event_handler("shutdown", handler)
875
-
876
- def get(
877
- self,
878
- path: str,
879
- *,
880
- response_model: Any = Default(None),
881
- status_code: Optional[int] = None,
882
- tags: Optional[List[Union[str, Enum]]] = None,
883
- dependencies: Optional[Sequence[params.Depends]] = None,
884
- summary: Optional[str] = None,
885
- description: Optional[str] = None,
886
- response_description: str = "Successful Response",
887
- responses: Optional[Dict[Union[int, str], Dict[str, Any]]] = None,
888
- deprecated: Optional[bool] = None,
889
- operation_id: Optional[str] = None,
890
- response_model_include: Optional[Union[SetIntStr, DictIntStrAny]] = None,
891
- response_model_exclude: Optional[Union[SetIntStr, DictIntStrAny]] = None,
892
- response_model_by_alias: bool = True,
893
- response_model_exclude_unset: bool = False,
894
- response_model_exclude_defaults: bool = False,
895
- response_model_exclude_none: bool = False,
896
- include_in_schema: bool = True,
897
- response_class: Type[Response] = Default(JSONResponse),
898
- name: Optional[str] = None,
899
- callbacks: Optional[List[BaseRoute]] = None,
900
- openapi_extra: Optional[Dict[str, Any]] = None,
901
- generate_unique_id_function: Callable[[APIRoute], str] = Default(
902
- generate_unique_id
903
- ),
904
- ) -> Callable[[DecoratedCallable], DecoratedCallable]:
905
- return self.api_route(
906
- path=path,
907
- response_model=response_model,
908
- status_code=status_code,
909
- tags=tags,
910
- dependencies=dependencies,
911
- summary=summary,
912
- description=description,
913
- response_description=response_description,
914
- responses=responses,
915
- deprecated=deprecated,
916
- methods=["GET"],
917
- operation_id=operation_id,
918
- response_model_include=response_model_include,
919
- response_model_exclude=response_model_exclude,
920
- response_model_by_alias=response_model_by_alias,
921
- response_model_exclude_unset=response_model_exclude_unset,
922
- response_model_exclude_defaults=response_model_exclude_defaults,
923
- response_model_exclude_none=response_model_exclude_none,
924
- include_in_schema=include_in_schema,
925
- response_class=response_class,
926
- name=name,
927
- callbacks=callbacks,
928
- openapi_extra=openapi_extra,
929
- generate_unique_id_function=generate_unique_id_function,
930
- )
931
-
932
- def put(
933
- self,
934
- path: str,
935
- *,
936
- response_model: Any = Default(None),
937
- status_code: Optional[int] = None,
938
- tags: Optional[List[Union[str, Enum]]] = None,
939
- dependencies: Optional[Sequence[params.Depends]] = None,
940
- summary: Optional[str] = None,
941
- description: Optional[str] = None,
942
- response_description: str = "Successful Response",
943
- responses: Optional[Dict[Union[int, str], Dict[str, Any]]] = None,
944
- deprecated: Optional[bool] = None,
945
- operation_id: Optional[str] = None,
946
- response_model_include: Optional[Union[SetIntStr, DictIntStrAny]] = None,
947
- response_model_exclude: Optional[Union[SetIntStr, DictIntStrAny]] = None,
948
- response_model_by_alias: bool = True,
949
- response_model_exclude_unset: bool = False,
950
- response_model_exclude_defaults: bool = False,
951
- response_model_exclude_none: bool = False,
952
- include_in_schema: bool = True,
953
- response_class: Type[Response] = Default(JSONResponse),
954
- name: Optional[str] = None,
955
- callbacks: Optional[List[BaseRoute]] = None,
956
- openapi_extra: Optional[Dict[str, Any]] = None,
957
- generate_unique_id_function: Callable[[APIRoute], str] = Default(
958
- generate_unique_id
959
- ),
960
- ) -> Callable[[DecoratedCallable], DecoratedCallable]:
961
- return self.api_route(
962
- path=path,
963
- response_model=response_model,
964
- status_code=status_code,
965
- tags=tags,
966
- dependencies=dependencies,
967
- summary=summary,
968
- description=description,
969
- response_description=response_description,
970
- responses=responses,
971
- deprecated=deprecated,
972
- methods=["PUT"],
973
- operation_id=operation_id,
974
- response_model_include=response_model_include,
975
- response_model_exclude=response_model_exclude,
976
- response_model_by_alias=response_model_by_alias,
977
- response_model_exclude_unset=response_model_exclude_unset,
978
- response_model_exclude_defaults=response_model_exclude_defaults,
979
- response_model_exclude_none=response_model_exclude_none,
980
- include_in_schema=include_in_schema,
981
- response_class=response_class,
982
- name=name,
983
- callbacks=callbacks,
984
- openapi_extra=openapi_extra,
985
- generate_unique_id_function=generate_unique_id_function,
986
- )
987
-
988
- def post(
989
- self,
990
- path: str,
991
- *,
992
- response_model: Any = Default(None),
993
- status_code: Optional[int] = None,
994
- tags: Optional[List[Union[str, Enum]]] = None,
995
- dependencies: Optional[Sequence[params.Depends]] = None,
996
- summary: Optional[str] = None,
997
- description: Optional[str] = None,
998
- response_description: str = "Successful Response",
999
- responses: Optional[Dict[Union[int, str], Dict[str, Any]]] = None,
1000
- deprecated: Optional[bool] = None,
1001
- operation_id: Optional[str] = None,
1002
- response_model_include: Optional[Union[SetIntStr, DictIntStrAny]] = None,
1003
- response_model_exclude: Optional[Union[SetIntStr, DictIntStrAny]] = None,
1004
- response_model_by_alias: bool = True,
1005
- response_model_exclude_unset: bool = False,
1006
- response_model_exclude_defaults: bool = False,
1007
- response_model_exclude_none: bool = False,
1008
- include_in_schema: bool = True,
1009
- response_class: Type[Response] = Default(JSONResponse),
1010
- name: Optional[str] = None,
1011
- callbacks: Optional[List[BaseRoute]] = None,
1012
- openapi_extra: Optional[Dict[str, Any]] = None,
1013
- generate_unique_id_function: Callable[[APIRoute], str] = Default(
1014
- generate_unique_id
1015
- ),
1016
- ) -> Callable[[DecoratedCallable], DecoratedCallable]:
1017
- return self.api_route(
1018
- path=path,
1019
- response_model=response_model,
1020
- status_code=status_code,
1021
- tags=tags,
1022
- dependencies=dependencies,
1023
- summary=summary,
1024
- description=description,
1025
- response_description=response_description,
1026
- responses=responses,
1027
- deprecated=deprecated,
1028
- methods=["POST"],
1029
- operation_id=operation_id,
1030
- response_model_include=response_model_include,
1031
- response_model_exclude=response_model_exclude,
1032
- response_model_by_alias=response_model_by_alias,
1033
- response_model_exclude_unset=response_model_exclude_unset,
1034
- response_model_exclude_defaults=response_model_exclude_defaults,
1035
- response_model_exclude_none=response_model_exclude_none,
1036
- include_in_schema=include_in_schema,
1037
- response_class=response_class,
1038
- name=name,
1039
- callbacks=callbacks,
1040
- openapi_extra=openapi_extra,
1041
- generate_unique_id_function=generate_unique_id_function,
1042
- )
1043
-
1044
- def delete(
1045
- self,
1046
- path: str,
1047
- *,
1048
- response_model: Any = Default(None),
1049
- status_code: Optional[int] = None,
1050
- tags: Optional[List[Union[str, Enum]]] = None,
1051
- dependencies: Optional[Sequence[params.Depends]] = None,
1052
- summary: Optional[str] = None,
1053
- description: Optional[str] = None,
1054
- response_description: str = "Successful Response",
1055
- responses: Optional[Dict[Union[int, str], Dict[str, Any]]] = None,
1056
- deprecated: Optional[bool] = None,
1057
- operation_id: Optional[str] = None,
1058
- response_model_include: Optional[Union[SetIntStr, DictIntStrAny]] = None,
1059
- response_model_exclude: Optional[Union[SetIntStr, DictIntStrAny]] = None,
1060
- response_model_by_alias: bool = True,
1061
- response_model_exclude_unset: bool = False,
1062
- response_model_exclude_defaults: bool = False,
1063
- response_model_exclude_none: bool = False,
1064
- include_in_schema: bool = True,
1065
- response_class: Type[Response] = Default(JSONResponse),
1066
- name: Optional[str] = None,
1067
- callbacks: Optional[List[BaseRoute]] = None,
1068
- openapi_extra: Optional[Dict[str, Any]] = None,
1069
- generate_unique_id_function: Callable[[APIRoute], str] = Default(
1070
- generate_unique_id
1071
- ),
1072
- ) -> Callable[[DecoratedCallable], DecoratedCallable]:
1073
- return self.api_route(
1074
- path=path,
1075
- response_model=response_model,
1076
- status_code=status_code,
1077
- tags=tags,
1078
- dependencies=dependencies,
1079
- summary=summary,
1080
- description=description,
1081
- response_description=response_description,
1082
- responses=responses,
1083
- deprecated=deprecated,
1084
- methods=["DELETE"],
1085
- operation_id=operation_id,
1086
- response_model_include=response_model_include,
1087
- response_model_exclude=response_model_exclude,
1088
- response_model_by_alias=response_model_by_alias,
1089
- response_model_exclude_unset=response_model_exclude_unset,
1090
- response_model_exclude_defaults=response_model_exclude_defaults,
1091
- response_model_exclude_none=response_model_exclude_none,
1092
- include_in_schema=include_in_schema,
1093
- response_class=response_class,
1094
- name=name,
1095
- callbacks=callbacks,
1096
- openapi_extra=openapi_extra,
1097
- generate_unique_id_function=generate_unique_id_function,
1098
- )
1099
-
1100
- def options(
1101
- self,
1102
- path: str,
1103
- *,
1104
- response_model: Any = Default(None),
1105
- status_code: Optional[int] = None,
1106
- tags: Optional[List[Union[str, Enum]]] = None,
1107
- dependencies: Optional[Sequence[params.Depends]] = None,
1108
- summary: Optional[str] = None,
1109
- description: Optional[str] = None,
1110
- response_description: str = "Successful Response",
1111
- responses: Optional[Dict[Union[int, str], Dict[str, Any]]] = None,
1112
- deprecated: Optional[bool] = None,
1113
- operation_id: Optional[str] = None,
1114
- response_model_include: Optional[Union[SetIntStr, DictIntStrAny]] = None,
1115
- response_model_exclude: Optional[Union[SetIntStr, DictIntStrAny]] = None,
1116
- response_model_by_alias: bool = True,
1117
- response_model_exclude_unset: bool = False,
1118
- response_model_exclude_defaults: bool = False,
1119
- response_model_exclude_none: bool = False,
1120
- include_in_schema: bool = True,
1121
- response_class: Type[Response] = Default(JSONResponse),
1122
- name: Optional[str] = None,
1123
- callbacks: Optional[List[BaseRoute]] = None,
1124
- openapi_extra: Optional[Dict[str, Any]] = None,
1125
- generate_unique_id_function: Callable[[APIRoute], str] = Default(
1126
- generate_unique_id
1127
- ),
1128
- ) -> Callable[[DecoratedCallable], DecoratedCallable]:
1129
- return self.api_route(
1130
- path=path,
1131
- response_model=response_model,
1132
- status_code=status_code,
1133
- tags=tags,
1134
- dependencies=dependencies,
1135
- summary=summary,
1136
- description=description,
1137
- response_description=response_description,
1138
- responses=responses,
1139
- deprecated=deprecated,
1140
- methods=["OPTIONS"],
1141
- operation_id=operation_id,
1142
- response_model_include=response_model_include,
1143
- response_model_exclude=response_model_exclude,
1144
- response_model_by_alias=response_model_by_alias,
1145
- response_model_exclude_unset=response_model_exclude_unset,
1146
- response_model_exclude_defaults=response_model_exclude_defaults,
1147
- response_model_exclude_none=response_model_exclude_none,
1148
- include_in_schema=include_in_schema,
1149
- response_class=response_class,
1150
- name=name,
1151
- callbacks=callbacks,
1152
- openapi_extra=openapi_extra,
1153
- generate_unique_id_function=generate_unique_id_function,
1154
- )
1155
-
1156
- def head(
1157
- self,
1158
- path: str,
1159
- *,
1160
- response_model: Any = Default(None),
1161
- status_code: Optional[int] = None,
1162
- tags: Optional[List[Union[str, Enum]]] = None,
1163
- dependencies: Optional[Sequence[params.Depends]] = None,
1164
- summary: Optional[str] = None,
1165
- description: Optional[str] = None,
1166
- response_description: str = "Successful Response",
1167
- responses: Optional[Dict[Union[int, str], Dict[str, Any]]] = None,
1168
- deprecated: Optional[bool] = None,
1169
- operation_id: Optional[str] = None,
1170
- response_model_include: Optional[Union[SetIntStr, DictIntStrAny]] = None,
1171
- response_model_exclude: Optional[Union[SetIntStr, DictIntStrAny]] = None,
1172
- response_model_by_alias: bool = True,
1173
- response_model_exclude_unset: bool = False,
1174
- response_model_exclude_defaults: bool = False,
1175
- response_model_exclude_none: bool = False,
1176
- include_in_schema: bool = True,
1177
- response_class: Type[Response] = Default(JSONResponse),
1178
- name: Optional[str] = None,
1179
- callbacks: Optional[List[BaseRoute]] = None,
1180
- openapi_extra: Optional[Dict[str, Any]] = None,
1181
- generate_unique_id_function: Callable[[APIRoute], str] = Default(
1182
- generate_unique_id
1183
- ),
1184
- ) -> Callable[[DecoratedCallable], DecoratedCallable]:
1185
- return self.api_route(
1186
- path=path,
1187
- response_model=response_model,
1188
- status_code=status_code,
1189
- tags=tags,
1190
- dependencies=dependencies,
1191
- summary=summary,
1192
- description=description,
1193
- response_description=response_description,
1194
- responses=responses,
1195
- deprecated=deprecated,
1196
- methods=["HEAD"],
1197
- operation_id=operation_id,
1198
- response_model_include=response_model_include,
1199
- response_model_exclude=response_model_exclude,
1200
- response_model_by_alias=response_model_by_alias,
1201
- response_model_exclude_unset=response_model_exclude_unset,
1202
- response_model_exclude_defaults=response_model_exclude_defaults,
1203
- response_model_exclude_none=response_model_exclude_none,
1204
- include_in_schema=include_in_schema,
1205
- response_class=response_class,
1206
- name=name,
1207
- callbacks=callbacks,
1208
- openapi_extra=openapi_extra,
1209
- generate_unique_id_function=generate_unique_id_function,
1210
- )
1211
-
1212
- def patch(
1213
- self,
1214
- path: str,
1215
- *,
1216
- response_model: Any = Default(None),
1217
- status_code: Optional[int] = None,
1218
- tags: Optional[List[Union[str, Enum]]] = None,
1219
- dependencies: Optional[Sequence[params.Depends]] = None,
1220
- summary: Optional[str] = None,
1221
- description: Optional[str] = None,
1222
- response_description: str = "Successful Response",
1223
- responses: Optional[Dict[Union[int, str], Dict[str, Any]]] = None,
1224
- deprecated: Optional[bool] = None,
1225
- operation_id: Optional[str] = None,
1226
- response_model_include: Optional[Union[SetIntStr, DictIntStrAny]] = None,
1227
- response_model_exclude: Optional[Union[SetIntStr, DictIntStrAny]] = None,
1228
- response_model_by_alias: bool = True,
1229
- response_model_exclude_unset: bool = False,
1230
- response_model_exclude_defaults: bool = False,
1231
- response_model_exclude_none: bool = False,
1232
- include_in_schema: bool = True,
1233
- response_class: Type[Response] = Default(JSONResponse),
1234
- name: Optional[str] = None,
1235
- callbacks: Optional[List[BaseRoute]] = None,
1236
- openapi_extra: Optional[Dict[str, Any]] = None,
1237
- generate_unique_id_function: Callable[[APIRoute], str] = Default(
1238
- generate_unique_id
1239
- ),
1240
- ) -> Callable[[DecoratedCallable], DecoratedCallable]:
1241
- return self.api_route(
1242
- path=path,
1243
- response_model=response_model,
1244
- status_code=status_code,
1245
- tags=tags,
1246
- dependencies=dependencies,
1247
- summary=summary,
1248
- description=description,
1249
- response_description=response_description,
1250
- responses=responses,
1251
- deprecated=deprecated,
1252
- methods=["PATCH"],
1253
- operation_id=operation_id,
1254
- response_model_include=response_model_include,
1255
- response_model_exclude=response_model_exclude,
1256
- response_model_by_alias=response_model_by_alias,
1257
- response_model_exclude_unset=response_model_exclude_unset,
1258
- response_model_exclude_defaults=response_model_exclude_defaults,
1259
- response_model_exclude_none=response_model_exclude_none,
1260
- include_in_schema=include_in_schema,
1261
- response_class=response_class,
1262
- name=name,
1263
- callbacks=callbacks,
1264
- openapi_extra=openapi_extra,
1265
- generate_unique_id_function=generate_unique_id_function,
1266
- )
1267
-
1268
- def trace(
1269
- self,
1270
- path: str,
1271
- *,
1272
- response_model: Any = Default(None),
1273
- status_code: Optional[int] = None,
1274
- tags: Optional[List[Union[str, Enum]]] = None,
1275
- dependencies: Optional[Sequence[params.Depends]] = None,
1276
- summary: Optional[str] = None,
1277
- description: Optional[str] = None,
1278
- response_description: str = "Successful Response",
1279
- responses: Optional[Dict[Union[int, str], Dict[str, Any]]] = None,
1280
- deprecated: Optional[bool] = None,
1281
- operation_id: Optional[str] = None,
1282
- response_model_include: Optional[Union[SetIntStr, DictIntStrAny]] = None,
1283
- response_model_exclude: Optional[Union[SetIntStr, DictIntStrAny]] = None,
1284
- response_model_by_alias: bool = True,
1285
- response_model_exclude_unset: bool = False,
1286
- response_model_exclude_defaults: bool = False,
1287
- response_model_exclude_none: bool = False,
1288
- include_in_schema: bool = True,
1289
- response_class: Type[Response] = Default(JSONResponse),
1290
- name: Optional[str] = None,
1291
- callbacks: Optional[List[BaseRoute]] = None,
1292
- openapi_extra: Optional[Dict[str, Any]] = None,
1293
- generate_unique_id_function: Callable[[APIRoute], str] = Default(
1294
- generate_unique_id
1295
- ),
1296
- ) -> Callable[[DecoratedCallable], DecoratedCallable]:
1297
- return self.api_route(
1298
- path=path,
1299
- response_model=response_model,
1300
- status_code=status_code,
1301
- tags=tags,
1302
- dependencies=dependencies,
1303
- summary=summary,
1304
- description=description,
1305
- response_description=response_description,
1306
- responses=responses,
1307
- deprecated=deprecated,
1308
- methods=["TRACE"],
1309
- operation_id=operation_id,
1310
- response_model_include=response_model_include,
1311
- response_model_exclude=response_model_exclude,
1312
- response_model_by_alias=response_model_by_alias,
1313
- response_model_exclude_unset=response_model_exclude_unset,
1314
- response_model_exclude_defaults=response_model_exclude_defaults,
1315
- response_model_exclude_none=response_model_exclude_none,
1316
- include_in_schema=include_in_schema,
1317
- response_class=response_class,
1318
- name=name,
1319
- callbacks=callbacks,
1320
- openapi_extra=openapi_extra,
1321
- generate_unique_id_function=generate_unique_id_function,
1322
- )
1323
-
1324
- def on_event(
1325
- self, event_type: str
1326
- ) -> Callable[[DecoratedCallable], DecoratedCallable]:
1327
- def decorator(func: DecoratedCallable) -> DecoratedCallable:
1328
- self.add_event_handler(event_type, func)
1329
- return func
1330
-
1331
- return decorator