prefect-client 2.20.4__py3-none-any.whl → 3.0.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.
Files changed (288) hide show
  1. prefect/__init__.py +74 -110
  2. prefect/_internal/compatibility/deprecated.py +6 -115
  3. prefect/_internal/compatibility/experimental.py +4 -79
  4. prefect/_internal/compatibility/migration.py +166 -0
  5. prefect/_internal/concurrency/__init__.py +2 -2
  6. prefect/_internal/concurrency/api.py +1 -35
  7. prefect/_internal/concurrency/calls.py +0 -6
  8. prefect/_internal/concurrency/cancellation.py +0 -3
  9. prefect/_internal/concurrency/event_loop.py +0 -20
  10. prefect/_internal/concurrency/inspection.py +3 -3
  11. prefect/_internal/concurrency/primitives.py +1 -0
  12. prefect/_internal/concurrency/services.py +23 -0
  13. prefect/_internal/concurrency/threads.py +35 -0
  14. prefect/_internal/concurrency/waiters.py +0 -28
  15. prefect/_internal/integrations.py +7 -0
  16. prefect/_internal/pydantic/__init__.py +0 -45
  17. prefect/_internal/pydantic/annotations/pendulum.py +2 -2
  18. prefect/_internal/pydantic/v1_schema.py +21 -22
  19. prefect/_internal/pydantic/v2_schema.py +0 -2
  20. prefect/_internal/pydantic/v2_validated_func.py +18 -23
  21. prefect/_internal/pytz.py +1 -1
  22. prefect/_internal/retries.py +61 -0
  23. prefect/_internal/schemas/bases.py +45 -177
  24. prefect/_internal/schemas/fields.py +1 -43
  25. prefect/_internal/schemas/validators.py +47 -233
  26. prefect/agent.py +3 -695
  27. prefect/artifacts.py +173 -14
  28. prefect/automations.py +39 -4
  29. prefect/blocks/abstract.py +1 -1
  30. prefect/blocks/core.py +405 -153
  31. prefect/blocks/fields.py +2 -57
  32. prefect/blocks/notifications.py +43 -28
  33. prefect/blocks/redis.py +168 -0
  34. prefect/blocks/system.py +67 -20
  35. prefect/blocks/webhook.py +2 -9
  36. prefect/cache_policies.py +239 -0
  37. prefect/client/__init__.py +4 -0
  38. prefect/client/base.py +33 -27
  39. prefect/client/cloud.py +65 -20
  40. prefect/client/collections.py +1 -1
  41. prefect/client/orchestration.py +650 -442
  42. prefect/client/schemas/actions.py +115 -100
  43. prefect/client/schemas/filters.py +46 -52
  44. prefect/client/schemas/objects.py +228 -178
  45. prefect/client/schemas/responses.py +18 -36
  46. prefect/client/schemas/schedules.py +55 -36
  47. prefect/client/schemas/sorting.py +2 -0
  48. prefect/client/subscriptions.py +8 -7
  49. prefect/client/types/flexible_schedule_list.py +11 -0
  50. prefect/client/utilities.py +9 -6
  51. prefect/concurrency/asyncio.py +60 -11
  52. prefect/concurrency/context.py +24 -0
  53. prefect/concurrency/events.py +2 -2
  54. prefect/concurrency/services.py +46 -16
  55. prefect/concurrency/sync.py +51 -7
  56. prefect/concurrency/v1/asyncio.py +143 -0
  57. prefect/concurrency/v1/context.py +27 -0
  58. prefect/concurrency/v1/events.py +61 -0
  59. prefect/concurrency/v1/services.py +116 -0
  60. prefect/concurrency/v1/sync.py +92 -0
  61. prefect/context.py +246 -149
  62. prefect/deployments/__init__.py +33 -18
  63. prefect/deployments/base.py +10 -15
  64. prefect/deployments/deployments.py +2 -1048
  65. prefect/deployments/flow_runs.py +178 -0
  66. prefect/deployments/runner.py +72 -173
  67. prefect/deployments/schedules.py +31 -25
  68. prefect/deployments/steps/__init__.py +0 -1
  69. prefect/deployments/steps/core.py +7 -0
  70. prefect/deployments/steps/pull.py +15 -21
  71. prefect/deployments/steps/utility.py +2 -1
  72. prefect/docker/__init__.py +20 -0
  73. prefect/docker/docker_image.py +82 -0
  74. prefect/engine.py +15 -2475
  75. prefect/events/actions.py +17 -23
  76. prefect/events/cli/automations.py +20 -7
  77. prefect/events/clients.py +142 -80
  78. prefect/events/filters.py +14 -18
  79. prefect/events/related.py +74 -75
  80. prefect/events/schemas/__init__.py +0 -5
  81. prefect/events/schemas/automations.py +55 -46
  82. prefect/events/schemas/deployment_triggers.py +7 -197
  83. prefect/events/schemas/events.py +46 -65
  84. prefect/events/schemas/labelling.py +10 -14
  85. prefect/events/utilities.py +4 -5
  86. prefect/events/worker.py +23 -8
  87. prefect/exceptions.py +15 -0
  88. prefect/filesystems.py +30 -529
  89. prefect/flow_engine.py +827 -0
  90. prefect/flow_runs.py +379 -7
  91. prefect/flows.py +470 -360
  92. prefect/futures.py +382 -331
  93. prefect/infrastructure/__init__.py +5 -26
  94. prefect/infrastructure/base.py +3 -320
  95. prefect/infrastructure/provisioners/__init__.py +5 -3
  96. prefect/infrastructure/provisioners/cloud_run.py +13 -8
  97. prefect/infrastructure/provisioners/container_instance.py +14 -9
  98. prefect/infrastructure/provisioners/ecs.py +10 -8
  99. prefect/infrastructure/provisioners/modal.py +8 -5
  100. prefect/input/__init__.py +4 -0
  101. prefect/input/actions.py +2 -4
  102. prefect/input/run_input.py +9 -9
  103. prefect/logging/formatters.py +2 -4
  104. prefect/logging/handlers.py +9 -14
  105. prefect/logging/loggers.py +5 -5
  106. prefect/main.py +72 -0
  107. prefect/plugins.py +2 -64
  108. prefect/profiles.toml +16 -2
  109. prefect/records/__init__.py +1 -0
  110. prefect/records/base.py +223 -0
  111. prefect/records/filesystem.py +207 -0
  112. prefect/records/memory.py +178 -0
  113. prefect/records/result_store.py +64 -0
  114. prefect/results.py +577 -504
  115. prefect/runner/runner.py +117 -47
  116. prefect/runner/server.py +32 -34
  117. prefect/runner/storage.py +3 -12
  118. prefect/runner/submit.py +2 -10
  119. prefect/runner/utils.py +2 -2
  120. prefect/runtime/__init__.py +1 -0
  121. prefect/runtime/deployment.py +1 -0
  122. prefect/runtime/flow_run.py +40 -5
  123. prefect/runtime/task_run.py +1 -0
  124. prefect/serializers.py +28 -39
  125. prefect/server/api/collections_data/views/aggregate-worker-metadata.json +5 -14
  126. prefect/settings.py +209 -332
  127. prefect/states.py +160 -63
  128. prefect/task_engine.py +1478 -57
  129. prefect/task_runners.py +383 -287
  130. prefect/task_runs.py +240 -0
  131. prefect/task_worker.py +463 -0
  132. prefect/tasks.py +684 -374
  133. prefect/transactions.py +410 -0
  134. prefect/types/__init__.py +72 -86
  135. prefect/types/entrypoint.py +13 -0
  136. prefect/utilities/annotations.py +4 -3
  137. prefect/utilities/asyncutils.py +227 -148
  138. prefect/utilities/callables.py +137 -45
  139. prefect/utilities/collections.py +134 -86
  140. prefect/utilities/dispatch.py +27 -14
  141. prefect/utilities/dockerutils.py +11 -4
  142. prefect/utilities/engine.py +186 -32
  143. prefect/utilities/filesystem.py +4 -5
  144. prefect/utilities/importtools.py +26 -27
  145. prefect/utilities/pydantic.py +128 -38
  146. prefect/utilities/schema_tools/hydration.py +18 -1
  147. prefect/utilities/schema_tools/validation.py +30 -0
  148. prefect/utilities/services.py +35 -9
  149. prefect/utilities/templating.py +12 -2
  150. prefect/utilities/timeout.py +20 -5
  151. prefect/utilities/urls.py +195 -0
  152. prefect/utilities/visualization.py +1 -0
  153. prefect/variables.py +78 -59
  154. prefect/workers/__init__.py +0 -1
  155. prefect/workers/base.py +237 -244
  156. prefect/workers/block.py +5 -226
  157. prefect/workers/cloud.py +6 -0
  158. prefect/workers/process.py +265 -12
  159. prefect/workers/server.py +29 -11
  160. {prefect_client-2.20.4.dist-info → prefect_client-3.0.0.dist-info}/METADATA +28 -24
  161. prefect_client-3.0.0.dist-info/RECORD +201 -0
  162. {prefect_client-2.20.4.dist-info → prefect_client-3.0.0.dist-info}/WHEEL +1 -1
  163. prefect/_internal/pydantic/_base_model.py +0 -51
  164. prefect/_internal/pydantic/_compat.py +0 -82
  165. prefect/_internal/pydantic/_flags.py +0 -20
  166. prefect/_internal/pydantic/_types.py +0 -8
  167. prefect/_internal/pydantic/utilities/config_dict.py +0 -72
  168. prefect/_internal/pydantic/utilities/field_validator.py +0 -150
  169. prefect/_internal/pydantic/utilities/model_construct.py +0 -56
  170. prefect/_internal/pydantic/utilities/model_copy.py +0 -55
  171. prefect/_internal/pydantic/utilities/model_dump.py +0 -136
  172. prefect/_internal/pydantic/utilities/model_dump_json.py +0 -112
  173. prefect/_internal/pydantic/utilities/model_fields.py +0 -50
  174. prefect/_internal/pydantic/utilities/model_fields_set.py +0 -29
  175. prefect/_internal/pydantic/utilities/model_json_schema.py +0 -82
  176. prefect/_internal/pydantic/utilities/model_rebuild.py +0 -80
  177. prefect/_internal/pydantic/utilities/model_validate.py +0 -75
  178. prefect/_internal/pydantic/utilities/model_validate_json.py +0 -68
  179. prefect/_internal/pydantic/utilities/model_validator.py +0 -87
  180. prefect/_internal/pydantic/utilities/type_adapter.py +0 -71
  181. prefect/_vendor/fastapi/__init__.py +0 -25
  182. prefect/_vendor/fastapi/applications.py +0 -946
  183. prefect/_vendor/fastapi/background.py +0 -3
  184. prefect/_vendor/fastapi/concurrency.py +0 -44
  185. prefect/_vendor/fastapi/datastructures.py +0 -58
  186. prefect/_vendor/fastapi/dependencies/__init__.py +0 -0
  187. prefect/_vendor/fastapi/dependencies/models.py +0 -64
  188. prefect/_vendor/fastapi/dependencies/utils.py +0 -877
  189. prefect/_vendor/fastapi/encoders.py +0 -177
  190. prefect/_vendor/fastapi/exception_handlers.py +0 -40
  191. prefect/_vendor/fastapi/exceptions.py +0 -46
  192. prefect/_vendor/fastapi/logger.py +0 -3
  193. prefect/_vendor/fastapi/middleware/__init__.py +0 -1
  194. prefect/_vendor/fastapi/middleware/asyncexitstack.py +0 -25
  195. prefect/_vendor/fastapi/middleware/cors.py +0 -3
  196. prefect/_vendor/fastapi/middleware/gzip.py +0 -3
  197. prefect/_vendor/fastapi/middleware/httpsredirect.py +0 -3
  198. prefect/_vendor/fastapi/middleware/trustedhost.py +0 -3
  199. prefect/_vendor/fastapi/middleware/wsgi.py +0 -3
  200. prefect/_vendor/fastapi/openapi/__init__.py +0 -0
  201. prefect/_vendor/fastapi/openapi/constants.py +0 -2
  202. prefect/_vendor/fastapi/openapi/docs.py +0 -203
  203. prefect/_vendor/fastapi/openapi/models.py +0 -480
  204. prefect/_vendor/fastapi/openapi/utils.py +0 -485
  205. prefect/_vendor/fastapi/param_functions.py +0 -340
  206. prefect/_vendor/fastapi/params.py +0 -453
  207. prefect/_vendor/fastapi/py.typed +0 -0
  208. prefect/_vendor/fastapi/requests.py +0 -4
  209. prefect/_vendor/fastapi/responses.py +0 -40
  210. prefect/_vendor/fastapi/routing.py +0 -1331
  211. prefect/_vendor/fastapi/security/__init__.py +0 -15
  212. prefect/_vendor/fastapi/security/api_key.py +0 -98
  213. prefect/_vendor/fastapi/security/base.py +0 -6
  214. prefect/_vendor/fastapi/security/http.py +0 -172
  215. prefect/_vendor/fastapi/security/oauth2.py +0 -227
  216. prefect/_vendor/fastapi/security/open_id_connect_url.py +0 -34
  217. prefect/_vendor/fastapi/security/utils.py +0 -10
  218. prefect/_vendor/fastapi/staticfiles.py +0 -1
  219. prefect/_vendor/fastapi/templating.py +0 -3
  220. prefect/_vendor/fastapi/testclient.py +0 -1
  221. prefect/_vendor/fastapi/types.py +0 -3
  222. prefect/_vendor/fastapi/utils.py +0 -235
  223. prefect/_vendor/fastapi/websockets.py +0 -7
  224. prefect/_vendor/starlette/__init__.py +0 -1
  225. prefect/_vendor/starlette/_compat.py +0 -28
  226. prefect/_vendor/starlette/_exception_handler.py +0 -80
  227. prefect/_vendor/starlette/_utils.py +0 -88
  228. prefect/_vendor/starlette/applications.py +0 -261
  229. prefect/_vendor/starlette/authentication.py +0 -159
  230. prefect/_vendor/starlette/background.py +0 -43
  231. prefect/_vendor/starlette/concurrency.py +0 -59
  232. prefect/_vendor/starlette/config.py +0 -151
  233. prefect/_vendor/starlette/convertors.py +0 -87
  234. prefect/_vendor/starlette/datastructures.py +0 -707
  235. prefect/_vendor/starlette/endpoints.py +0 -130
  236. prefect/_vendor/starlette/exceptions.py +0 -60
  237. prefect/_vendor/starlette/formparsers.py +0 -276
  238. prefect/_vendor/starlette/middleware/__init__.py +0 -17
  239. prefect/_vendor/starlette/middleware/authentication.py +0 -52
  240. prefect/_vendor/starlette/middleware/base.py +0 -220
  241. prefect/_vendor/starlette/middleware/cors.py +0 -176
  242. prefect/_vendor/starlette/middleware/errors.py +0 -265
  243. prefect/_vendor/starlette/middleware/exceptions.py +0 -74
  244. prefect/_vendor/starlette/middleware/gzip.py +0 -113
  245. prefect/_vendor/starlette/middleware/httpsredirect.py +0 -19
  246. prefect/_vendor/starlette/middleware/sessions.py +0 -82
  247. prefect/_vendor/starlette/middleware/trustedhost.py +0 -64
  248. prefect/_vendor/starlette/middleware/wsgi.py +0 -147
  249. prefect/_vendor/starlette/py.typed +0 -0
  250. prefect/_vendor/starlette/requests.py +0 -328
  251. prefect/_vendor/starlette/responses.py +0 -347
  252. prefect/_vendor/starlette/routing.py +0 -933
  253. prefect/_vendor/starlette/schemas.py +0 -154
  254. prefect/_vendor/starlette/staticfiles.py +0 -248
  255. prefect/_vendor/starlette/status.py +0 -199
  256. prefect/_vendor/starlette/templating.py +0 -231
  257. prefect/_vendor/starlette/testclient.py +0 -804
  258. prefect/_vendor/starlette/types.py +0 -30
  259. prefect/_vendor/starlette/websockets.py +0 -193
  260. prefect/blocks/kubernetes.py +0 -119
  261. prefect/deprecated/__init__.py +0 -0
  262. prefect/deprecated/data_documents.py +0 -350
  263. prefect/deprecated/packaging/__init__.py +0 -12
  264. prefect/deprecated/packaging/base.py +0 -96
  265. prefect/deprecated/packaging/docker.py +0 -146
  266. prefect/deprecated/packaging/file.py +0 -92
  267. prefect/deprecated/packaging/orion.py +0 -80
  268. prefect/deprecated/packaging/serializers.py +0 -171
  269. prefect/events/instrument.py +0 -135
  270. prefect/infrastructure/container.py +0 -824
  271. prefect/infrastructure/kubernetes.py +0 -920
  272. prefect/infrastructure/process.py +0 -289
  273. prefect/manifests.py +0 -20
  274. prefect/new_flow_engine.py +0 -449
  275. prefect/new_task_engine.py +0 -423
  276. prefect/pydantic/__init__.py +0 -76
  277. prefect/pydantic/main.py +0 -39
  278. prefect/software/__init__.py +0 -2
  279. prefect/software/base.py +0 -50
  280. prefect/software/conda.py +0 -199
  281. prefect/software/pip.py +0 -122
  282. prefect/software/python.py +0 -52
  283. prefect/task_server.py +0 -322
  284. prefect_client-2.20.4.dist-info/RECORD +0 -294
  285. /prefect/{_internal/pydantic/utilities → client/types}/__init__.py +0 -0
  286. /prefect/{_vendor → concurrency/v1}/__init__.py +0 -0
  287. {prefect_client-2.20.4.dist-info → prefect_client-3.0.0.dist-info}/LICENSE +0 -0
  288. {prefect_client-2.20.4.dist-info → prefect_client-3.0.0.dist-info}/top_level.txt +0 -0
@@ -1,177 +0,0 @@
1
- import dataclasses
2
- from collections import defaultdict, deque
3
- from enum import Enum
4
- from pathlib import PurePath
5
- from types import GeneratorType
6
- from typing import Any, Callable, Dict, List, Optional, Set, Tuple, Union
7
-
8
- from prefect._internal.pydantic import HAS_PYDANTIC_V2
9
-
10
- if HAS_PYDANTIC_V2:
11
- from pydantic.v1 import BaseModel
12
- from pydantic.v1.json import ENCODERS_BY_TYPE
13
- else:
14
- from pydantic import BaseModel
15
- from pydantic.json import ENCODERS_BY_TYPE
16
-
17
- SetIntStr = Set[Union[int, str]]
18
- DictIntStrAny = Dict[Union[int, str], Any]
19
-
20
-
21
- def generate_encoders_by_class_tuples(
22
- type_encoder_map: Dict[Any, Callable[[Any], Any]],
23
- ) -> Dict[Callable[[Any], Any], Tuple[Any, ...]]:
24
- encoders_by_class_tuples: Dict[Callable[[Any], Any], Tuple[Any, ...]] = defaultdict(
25
- tuple
26
- )
27
- for type_, encoder in type_encoder_map.items():
28
- encoders_by_class_tuples[encoder] += (type_,)
29
- return encoders_by_class_tuples
30
-
31
-
32
- encoders_by_class_tuples = generate_encoders_by_class_tuples(ENCODERS_BY_TYPE)
33
-
34
-
35
- def jsonable_encoder(
36
- obj: Any,
37
- include: Optional[Union[SetIntStr, DictIntStrAny]] = None,
38
- exclude: Optional[Union[SetIntStr, DictIntStrAny]] = None,
39
- by_alias: bool = True,
40
- exclude_unset: bool = False,
41
- exclude_defaults: bool = False,
42
- exclude_none: bool = False,
43
- custom_encoder: Optional[Dict[Any, Callable[[Any], Any]]] = None,
44
- sqlalchemy_safe: bool = True,
45
- ) -> Any:
46
- custom_encoder = custom_encoder or {}
47
- if custom_encoder:
48
- if type(obj) in custom_encoder:
49
- return custom_encoder[type(obj)](obj)
50
- else:
51
- for encoder_type, encoder_instance in custom_encoder.items():
52
- if isinstance(obj, encoder_type):
53
- return encoder_instance(obj)
54
- if include is not None and not isinstance(include, (set, dict)):
55
- include = set(include)
56
- if exclude is not None and not isinstance(exclude, (set, dict)):
57
- exclude = set(exclude)
58
- if isinstance(obj, BaseModel):
59
- encoder = getattr(obj.__config__, "json_encoders", {})
60
- if custom_encoder:
61
- encoder.update(custom_encoder)
62
- obj_dict = obj.dict(
63
- include=include,
64
- exclude=exclude,
65
- by_alias=by_alias,
66
- exclude_unset=exclude_unset,
67
- exclude_none=exclude_none,
68
- exclude_defaults=exclude_defaults,
69
- )
70
- if "__root__" in obj_dict:
71
- obj_dict = obj_dict["__root__"]
72
- return jsonable_encoder(
73
- obj_dict,
74
- exclude_none=exclude_none,
75
- exclude_defaults=exclude_defaults,
76
- custom_encoder=encoder,
77
- sqlalchemy_safe=sqlalchemy_safe,
78
- )
79
- if dataclasses.is_dataclass(obj):
80
- obj_dict = dataclasses.asdict(obj)
81
- return jsonable_encoder(
82
- obj_dict,
83
- include=include,
84
- exclude=exclude,
85
- by_alias=by_alias,
86
- exclude_unset=exclude_unset,
87
- exclude_defaults=exclude_defaults,
88
- exclude_none=exclude_none,
89
- custom_encoder=custom_encoder,
90
- sqlalchemy_safe=sqlalchemy_safe,
91
- )
92
- if isinstance(obj, Enum):
93
- return obj.value
94
- if isinstance(obj, PurePath):
95
- return str(obj)
96
- if isinstance(obj, (str, int, float, type(None))):
97
- return obj
98
- if isinstance(obj, dict):
99
- encoded_dict = {}
100
- allowed_keys = set(obj.keys())
101
- if include is not None:
102
- allowed_keys &= set(include)
103
- if exclude is not None:
104
- allowed_keys -= set(exclude)
105
- for key, value in obj.items():
106
- if (
107
- (
108
- not sqlalchemy_safe
109
- or (not isinstance(key, str))
110
- or (not key.startswith("_sa"))
111
- )
112
- and (value is not None or not exclude_none)
113
- and key in allowed_keys
114
- ):
115
- encoded_key = jsonable_encoder(
116
- key,
117
- by_alias=by_alias,
118
- exclude_unset=exclude_unset,
119
- exclude_none=exclude_none,
120
- custom_encoder=custom_encoder,
121
- sqlalchemy_safe=sqlalchemy_safe,
122
- )
123
- encoded_value = jsonable_encoder(
124
- value,
125
- by_alias=by_alias,
126
- exclude_unset=exclude_unset,
127
- exclude_none=exclude_none,
128
- custom_encoder=custom_encoder,
129
- sqlalchemy_safe=sqlalchemy_safe,
130
- )
131
- encoded_dict[encoded_key] = encoded_value
132
- return encoded_dict
133
- if isinstance(obj, (list, set, frozenset, GeneratorType, tuple, deque)):
134
- encoded_list = []
135
- for item in obj:
136
- encoded_list.append(
137
- jsonable_encoder(
138
- item,
139
- include=include,
140
- exclude=exclude,
141
- by_alias=by_alias,
142
- exclude_unset=exclude_unset,
143
- exclude_defaults=exclude_defaults,
144
- exclude_none=exclude_none,
145
- custom_encoder=custom_encoder,
146
- sqlalchemy_safe=sqlalchemy_safe,
147
- )
148
- )
149
- return encoded_list
150
-
151
- if type(obj) in ENCODERS_BY_TYPE:
152
- return ENCODERS_BY_TYPE[type(obj)](obj)
153
- for encoder, classes_tuple in encoders_by_class_tuples.items():
154
- if isinstance(obj, classes_tuple):
155
- return encoder(obj)
156
-
157
- try:
158
- data = dict(obj)
159
- except Exception as e:
160
- errors: List[Exception] = []
161
- errors.append(e)
162
- try:
163
- data = vars(obj)
164
- except Exception as e:
165
- errors.append(e)
166
- raise ValueError(errors) from e
167
- return jsonable_encoder(
168
- data,
169
- include=include,
170
- exclude=exclude,
171
- by_alias=by_alias,
172
- exclude_unset=exclude_unset,
173
- exclude_defaults=exclude_defaults,
174
- exclude_none=exclude_none,
175
- custom_encoder=custom_encoder,
176
- sqlalchemy_safe=sqlalchemy_safe,
177
- )
@@ -1,40 +0,0 @@
1
- from prefect._vendor.fastapi.encoders import jsonable_encoder
2
- from prefect._vendor.fastapi.exceptions import (
3
- RequestValidationError,
4
- WebSocketRequestValidationError,
5
- )
6
- from prefect._vendor.fastapi.utils import is_body_allowed_for_status_code
7
- from prefect._vendor.fastapi.websockets import WebSocket
8
- from prefect._vendor.starlette.exceptions import HTTPException
9
- from prefect._vendor.starlette.requests import Request
10
- from prefect._vendor.starlette.responses import JSONResponse, Response
11
- from prefect._vendor.starlette.status import (
12
- HTTP_422_UNPROCESSABLE_ENTITY,
13
- WS_1008_POLICY_VIOLATION,
14
- )
15
-
16
-
17
- async def http_exception_handler(request: Request, exc: HTTPException) -> Response:
18
- headers = getattr(exc, "headers", None)
19
- if not is_body_allowed_for_status_code(exc.status_code):
20
- return Response(status_code=exc.status_code, headers=headers)
21
- return JSONResponse(
22
- {"detail": exc.detail}, status_code=exc.status_code, headers=headers
23
- )
24
-
25
-
26
- async def request_validation_exception_handler(
27
- request: Request, exc: RequestValidationError
28
- ) -> JSONResponse:
29
- return JSONResponse(
30
- status_code=HTTP_422_UNPROCESSABLE_ENTITY,
31
- content={"detail": jsonable_encoder(exc.errors())},
32
- )
33
-
34
-
35
- async def websocket_request_validation_exception_handler(
36
- websocket: WebSocket, exc: WebSocketRequestValidationError
37
- ) -> None:
38
- await websocket.close(
39
- code=WS_1008_POLICY_VIOLATION, reason=jsonable_encoder(exc.errors())
40
- )
@@ -1,46 +0,0 @@
1
- from typing import Any, Dict, Optional, Sequence, Type
2
-
3
- from prefect._internal.pydantic import HAS_PYDANTIC_V2
4
-
5
- if HAS_PYDANTIC_V2:
6
- from pydantic.v1 import BaseModel, ValidationError, create_model
7
- from pydantic.v1.error_wrappers import ErrorList
8
- else:
9
- from pydantic import BaseModel, ValidationError, create_model
10
- from pydantic.error_wrappers import ErrorList
11
-
12
- from prefect._vendor.starlette.exceptions import HTTPException as StarletteHTTPException
13
- from prefect._vendor.starlette.exceptions import (
14
- WebSocketException as WebSocketException, # noqa: F401
15
- )
16
-
17
-
18
- class HTTPException(StarletteHTTPException):
19
- def __init__(
20
- self,
21
- status_code: int,
22
- detail: Any = None,
23
- headers: Optional[Dict[str, str]] = None,
24
- ) -> None:
25
- super().__init__(status_code=status_code, detail=detail, headers=headers)
26
-
27
-
28
- RequestErrorModel: Type[BaseModel] = create_model("Request")
29
- WebSocketErrorModel: Type[BaseModel] = create_model("WebSocket")
30
-
31
-
32
- class FastAPIError(RuntimeError):
33
- """
34
- A generic, FastAPI-specific error.
35
- """
36
-
37
-
38
- class RequestValidationError(ValidationError):
39
- def __init__(self, errors: Sequence[ErrorList], *, body: Any = None) -> None:
40
- self.body = body
41
- super().__init__(errors, RequestErrorModel)
42
-
43
-
44
- class WebSocketRequestValidationError(ValidationError):
45
- def __init__(self, errors: Sequence[ErrorList]) -> None:
46
- super().__init__(errors, WebSocketErrorModel)
@@ -1,3 +0,0 @@
1
- import logging
2
-
3
- logger = logging.getLogger("fastapi")
@@ -1 +0,0 @@
1
- from prefect._vendor.starlette.middleware import Middleware as Middleware
@@ -1,25 +0,0 @@
1
- from typing import Optional
2
-
3
- from prefect._vendor.fastapi.concurrency import AsyncExitStack
4
- from prefect._vendor.starlette.types import ASGIApp, Receive, Scope, Send
5
-
6
-
7
- class AsyncExitStackMiddleware:
8
- def __init__(self, app: ASGIApp, context_name: str = "fastapi_astack") -> None:
9
- self.app = app
10
- self.context_name = context_name
11
-
12
- async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None:
13
- dependency_exception: Optional[Exception] = None
14
- async with AsyncExitStack() as stack:
15
- scope[self.context_name] = stack
16
- try:
17
- await self.app(scope, receive, send)
18
- except Exception as e:
19
- dependency_exception = e
20
- raise e
21
- if dependency_exception:
22
- # This exception was possibly handled by the dependency but it should
23
- # still bubble up so that the ServerErrorMiddleware can return a 500
24
- # or the ExceptionMiddleware can catch and handle any other exceptions
25
- raise dependency_exception
@@ -1,3 +0,0 @@
1
- from prefect._vendor.starlette.middleware.cors import (
2
- CORSMiddleware as CORSMiddleware,
3
- )
@@ -1,3 +0,0 @@
1
- from prefect._vendor.starlette.middleware.gzip import (
2
- GZipMiddleware as GZipMiddleware,
3
- )
@@ -1,3 +0,0 @@
1
- from prefect._vendor.starlette.middleware.httpsredirect import ( # noqa
2
- HTTPSRedirectMiddleware as HTTPSRedirectMiddleware,
3
- )
@@ -1,3 +0,0 @@
1
- from prefect._vendor.starlette.middleware.trustedhost import ( # noqa
2
- TrustedHostMiddleware as TrustedHostMiddleware,
3
- )
@@ -1,3 +0,0 @@
1
- from prefect._vendor.starlette.middleware.wsgi import (
2
- WSGIMiddleware as WSGIMiddleware,
3
- )
File without changes
@@ -1,2 +0,0 @@
1
- METHODS_WITH_BODY = {"GET", "HEAD", "POST", "PUT", "DELETE", "PATCH"}
2
- REF_PREFIX = "#/components/schemas/"
@@ -1,203 +0,0 @@
1
- import json
2
- from typing import Any, Dict, Optional
3
-
4
- from prefect._vendor.fastapi.encoders import jsonable_encoder
5
- from prefect._vendor.starlette.responses import HTMLResponse
6
-
7
- swagger_ui_default_parameters = {
8
- "dom_id": "#swagger-ui",
9
- "layout": "BaseLayout",
10
- "deepLinking": True,
11
- "showExtensions": True,
12
- "showCommonExtensions": True,
13
- }
14
-
15
-
16
- def get_swagger_ui_html(
17
- *,
18
- openapi_url: str,
19
- title: str,
20
- swagger_js_url: str = "https://cdn.jsdelivr.net/npm/swagger-ui-dist@5/swagger-ui-bundle.js",
21
- swagger_css_url: str = "https://cdn.jsdelivr.net/npm/swagger-ui-dist@5/swagger-ui.css",
22
- swagger_favicon_url: str = "https://fastapi.tiangolo.com/img/favicon.png",
23
- oauth2_redirect_url: Optional[str] = None,
24
- init_oauth: Optional[Dict[str, Any]] = None,
25
- swagger_ui_parameters: Optional[Dict[str, Any]] = None,
26
- ) -> HTMLResponse:
27
- current_swagger_ui_parameters = swagger_ui_default_parameters.copy()
28
- if swagger_ui_parameters:
29
- current_swagger_ui_parameters.update(swagger_ui_parameters)
30
-
31
- html = f"""
32
- <!DOCTYPE html>
33
- <html>
34
- <head>
35
- <link type="text/css" rel="stylesheet" href="{swagger_css_url}">
36
- <link rel="shortcut icon" href="{swagger_favicon_url}">
37
- <title>{title}</title>
38
- </head>
39
- <body>
40
- <div id="swagger-ui">
41
- </div>
42
- <script src="{swagger_js_url}"></script>
43
- <!-- `SwaggerUIBundle` is now available on the page -->
44
- <script>
45
- const ui = SwaggerUIBundle({{
46
- url: '{openapi_url}',
47
- """
48
-
49
- for key, value in current_swagger_ui_parameters.items():
50
- html += f"{json.dumps(key)}: {json.dumps(jsonable_encoder(value))},\n"
51
-
52
- if oauth2_redirect_url:
53
- html += f"oauth2RedirectUrl: window.location.origin + '{oauth2_redirect_url}',"
54
-
55
- html += """
56
- presets: [
57
- SwaggerUIBundle.presets.apis,
58
- SwaggerUIBundle.SwaggerUIStandalonePreset
59
- ],
60
- })"""
61
-
62
- if init_oauth:
63
- html += f"""
64
- ui.initOAuth({json.dumps(jsonable_encoder(init_oauth))})
65
- """
66
-
67
- html += """
68
- </script>
69
- </body>
70
- </html>
71
- """
72
- return HTMLResponse(html)
73
-
74
-
75
- def get_redoc_html(
76
- *,
77
- openapi_url: str,
78
- title: str,
79
- redoc_js_url: str = "https://cdn.jsdelivr.net/npm/redoc@next/bundles/redoc.standalone.js",
80
- redoc_favicon_url: str = "https://fastapi.tiangolo.com/img/favicon.png",
81
- with_google_fonts: bool = True,
82
- ) -> HTMLResponse:
83
- html = f"""
84
- <!DOCTYPE html>
85
- <html>
86
- <head>
87
- <title>{title}</title>
88
- <!-- needed for adaptive design -->
89
- <meta charset="utf-8"/>
90
- <meta name="viewport" content="width=device-width, initial-scale=1">
91
- """
92
- if with_google_fonts:
93
- html += """
94
- <link href="https://fonts.googleapis.com/css?family=Montserrat:300,400,700|Roboto:300,400,700" rel="stylesheet">
95
- """
96
- html += f"""
97
- <link rel="shortcut icon" href="{redoc_favicon_url}">
98
- <!--
99
- ReDoc doesn't change outer page styles
100
- -->
101
- <style>
102
- body {{
103
- margin: 0;
104
- padding: 0;
105
- }}
106
- </style>
107
- </head>
108
- <body>
109
- <noscript>
110
- ReDoc requires Javascript to function. Please enable it to browse the documentation.
111
- </noscript>
112
- <redoc spec-url="{openapi_url}"></redoc>
113
- <script src="{redoc_js_url}"> </script>
114
- </body>
115
- </html>
116
- """
117
- return HTMLResponse(html)
118
-
119
-
120
- def get_swagger_ui_oauth2_redirect_html() -> HTMLResponse:
121
- # copied from https://github.com/swagger-api/swagger-ui/blob/v4.14.0/dist/oauth2-redirect.html
122
- html = """
123
- <!doctype html>
124
- <html lang="en-US">
125
- <head>
126
- <title>Swagger UI: OAuth2 Redirect</title>
127
- </head>
128
- <body>
129
- <script>
130
- 'use strict';
131
- function run () {
132
- var oauth2 = window.opener.swaggerUIRedirectOauth2;
133
- var sentState = oauth2.state;
134
- var redirectUrl = oauth2.redirectUrl;
135
- var isValid, qp, arr;
136
-
137
- if (/code|token|error/.test(window.location.hash)) {
138
- qp = window.location.hash.substring(1).replace('?', '&');
139
- } else {
140
- qp = location.search.substring(1);
141
- }
142
-
143
- arr = qp.split("&");
144
- arr.forEach(function (v,i,_arr) { _arr[i] = '"' + v.replace('=', '":"') + '"';});
145
- qp = qp ? JSON.parse('{' + arr.join() + '}',
146
- function (key, value) {
147
- return key === "" ? value : decodeURIComponent(value);
148
- }
149
- ) : {};
150
-
151
- isValid = qp.state === sentState;
152
-
153
- if ((
154
- oauth2.auth.schema.get("flow") === "accessCode" ||
155
- oauth2.auth.schema.get("flow") === "authorizationCode" ||
156
- oauth2.auth.schema.get("flow") === "authorization_code"
157
- ) && !oauth2.auth.code) {
158
- if (!isValid) {
159
- oauth2.errCb({
160
- authId: oauth2.auth.name,
161
- source: "auth",
162
- level: "warning",
163
- message: "Authorization may be unsafe, passed state was changed in server. The passed state wasn't returned from auth server."
164
- });
165
- }
166
-
167
- if (qp.code) {
168
- delete oauth2.state;
169
- oauth2.auth.code = qp.code;
170
- oauth2.callback({auth: oauth2.auth, redirectUrl: redirectUrl});
171
- } else {
172
- let oauthErrorMsg;
173
- if (qp.error) {
174
- oauthErrorMsg = "["+qp.error+"]: " +
175
- (qp.error_description ? qp.error_description+ ". " : "no accessCode received from the server. ") +
176
- (qp.error_uri ? "More info: "+qp.error_uri : "");
177
- }
178
-
179
- oauth2.errCb({
180
- authId: oauth2.auth.name,
181
- source: "auth",
182
- level: "error",
183
- message: oauthErrorMsg || "[Authorization failed]: no accessCode received from the server."
184
- });
185
- }
186
- } else {
187
- oauth2.callback({auth: oauth2.auth, token: qp, isValid: isValid, redirectUrl: redirectUrl});
188
- }
189
- window.close();
190
- }
191
-
192
- if (document.readyState !== 'loading') {
193
- run();
194
- } else {
195
- document.addEventListener('DOMContentLoaded', function () {
196
- run();
197
- });
198
- }
199
- </script>
200
- </body>
201
- </html>
202
- """
203
- return HTMLResponse(content=html)