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,235 +0,0 @@
1
- import re
2
- import warnings
3
- from dataclasses import is_dataclass
4
- from enum import Enum
5
- from typing import (
6
- TYPE_CHECKING,
7
- Any,
8
- Dict,
9
- MutableMapping,
10
- Optional,
11
- Set,
12
- Type,
13
- Union,
14
- cast,
15
- )
16
- from weakref import WeakKeyDictionary
17
-
18
- from prefect._vendor.fastapi.datastructures import DefaultPlaceholder, DefaultType
19
- from prefect._vendor.fastapi.exceptions import FastAPIError
20
- from prefect._vendor.fastapi.openapi.constants import REF_PREFIX
21
-
22
- from prefect._internal.pydantic import HAS_PYDANTIC_V2
23
-
24
- if HAS_PYDANTIC_V2:
25
- from pydantic.v1 import BaseConfig, BaseModel, create_model
26
- from pydantic.v1.class_validators import Validator
27
- from pydantic.v1.fields import FieldInfo, ModelField, UndefinedType
28
- from pydantic.v1.schema import model_process_schema
29
- from pydantic.v1.utils import lenient_issubclass
30
- else:
31
- from pydantic import BaseConfig, BaseModel, create_model
32
- from pydantic.class_validators import Validator
33
- from pydantic.fields import FieldInfo, ModelField, UndefinedType
34
- from pydantic.schema import model_process_schema
35
- from pydantic.utils import lenient_issubclass
36
-
37
-
38
- if TYPE_CHECKING: # pragma: nocover
39
- from .routing import APIRoute
40
-
41
- # Cache for `create_cloned_field`
42
- _CLONED_TYPES_CACHE: MutableMapping[
43
- Type[BaseModel], Type[BaseModel]
44
- ] = WeakKeyDictionary()
45
-
46
-
47
- def is_body_allowed_for_status_code(status_code: Union[int, str, None]) -> bool:
48
- if status_code is None:
49
- return True
50
- # Ref: https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#patterned-fields-1
51
- if status_code in {
52
- "default",
53
- "1XX",
54
- "2XX",
55
- "3XX",
56
- "4XX",
57
- "5XX",
58
- }:
59
- return True
60
- current_status_code = int(status_code)
61
- return not (current_status_code < 200 or current_status_code in {204, 304})
62
-
63
-
64
- def get_model_definitions(
65
- *,
66
- flat_models: Set[Union[Type[BaseModel], Type[Enum]]],
67
- model_name_map: Dict[Union[Type[BaseModel], Type[Enum]], str],
68
- ) -> Dict[str, Any]:
69
- definitions: Dict[str, Dict[str, Any]] = {}
70
- for model in flat_models:
71
- m_schema, m_definitions, m_nested_models = model_process_schema(
72
- model, model_name_map=model_name_map, ref_prefix=REF_PREFIX
73
- )
74
- definitions.update(m_definitions)
75
- model_name = model_name_map[model]
76
- if "description" in m_schema:
77
- m_schema["description"] = m_schema["description"].split("\f")[0]
78
- definitions[model_name] = m_schema
79
- return definitions
80
-
81
-
82
- def get_path_param_names(path: str) -> Set[str]:
83
- return set(re.findall("{(.*?)}", path))
84
-
85
-
86
- def create_response_field(
87
- name: str,
88
- type_: Type[Any],
89
- class_validators: Optional[Dict[str, Validator]] = None,
90
- default: Optional[Any] = None,
91
- required: Union[bool, UndefinedType] = True,
92
- model_config: Type[BaseConfig] = BaseConfig,
93
- field_info: Optional[FieldInfo] = None,
94
- alias: Optional[str] = None,
95
- ) -> ModelField:
96
- """
97
- Create a new response field. Raises if type_ is invalid.
98
- """
99
- class_validators = class_validators or {}
100
- field_info = field_info or FieldInfo()
101
-
102
- try:
103
- return ModelField(
104
- name=name,
105
- type_=type_,
106
- class_validators=class_validators,
107
- default=default,
108
- required=required,
109
- model_config=model_config,
110
- alias=alias,
111
- field_info=field_info,
112
- )
113
- except RuntimeError:
114
- raise FastAPIError(
115
- "Invalid args for response field! Hint: "
116
- f"check that {type_} is a valid Pydantic field type. "
117
- "If you are using a return type annotation that is not a valid Pydantic "
118
- "field (e.g. Union[Response, dict, None]) you can disable generating the "
119
- "response model from the type annotation with the path operation decorator "
120
- "parameter response_model=None. Read more: "
121
- "https://fastapi.tiangolo.com/tutorial/response-model/"
122
- ) from None
123
-
124
-
125
- def create_cloned_field(
126
- field: ModelField,
127
- *,
128
- cloned_types: Optional[MutableMapping[Type[BaseModel], Type[BaseModel]]] = None,
129
- ) -> ModelField:
130
- # cloned_types caches already cloned types to support recursive models and improve
131
- # performance by avoiding unecessary cloning
132
- if cloned_types is None:
133
- cloned_types = _CLONED_TYPES_CACHE
134
-
135
- original_type = field.type_
136
- if is_dataclass(original_type) and hasattr(original_type, "__pydantic_model__"):
137
- original_type = original_type.__pydantic_model__
138
- use_type = original_type
139
- if lenient_issubclass(original_type, BaseModel):
140
- original_type = cast(Type[BaseModel], original_type)
141
- use_type = cloned_types.get(original_type)
142
- if use_type is None:
143
- use_type = create_model(original_type.__name__, __base__=original_type)
144
- cloned_types[original_type] = use_type
145
- for f in original_type.__fields__.values():
146
- use_type.__fields__[f.name] = create_cloned_field(
147
- f, cloned_types=cloned_types
148
- )
149
- new_field = create_response_field(name=field.name, type_=use_type)
150
- new_field.has_alias = field.has_alias
151
- new_field.alias = field.alias
152
- new_field.class_validators = field.class_validators
153
- new_field.default = field.default
154
- new_field.required = field.required
155
- new_field.model_config = field.model_config
156
- new_field.field_info = field.field_info
157
- new_field.allow_none = field.allow_none
158
- new_field.validate_always = field.validate_always
159
- if field.sub_fields:
160
- new_field.sub_fields = [
161
- create_cloned_field(sub_field, cloned_types=cloned_types)
162
- for sub_field in field.sub_fields
163
- ]
164
- if field.key_field:
165
- new_field.key_field = create_cloned_field(
166
- field.key_field, cloned_types=cloned_types
167
- )
168
- new_field.validators = field.validators
169
- new_field.pre_validators = field.pre_validators
170
- new_field.post_validators = field.post_validators
171
- new_field.parse_json = field.parse_json
172
- new_field.shape = field.shape
173
- new_field.populate_validators()
174
- return new_field
175
-
176
-
177
- def generate_operation_id_for_path(
178
- *, name: str, path: str, method: str
179
- ) -> str: # pragma: nocover
180
- warnings.warn(
181
- (
182
- "fastapi.utils.generate_operation_id_for_path() was deprecated, "
183
- "it is not used internally, and will be removed soon"
184
- ),
185
- DeprecationWarning,
186
- stacklevel=2,
187
- )
188
- operation_id = name + path
189
- operation_id = re.sub(r"\W", "_", operation_id)
190
- operation_id = operation_id + "_" + method.lower()
191
- return operation_id
192
-
193
-
194
- def generate_unique_id(route: "APIRoute") -> str:
195
- operation_id = route.name + route.path_format
196
- operation_id = re.sub(r"\W", "_", operation_id)
197
- assert route.methods
198
- operation_id = operation_id + "_" + list(route.methods)[0].lower()
199
- return operation_id
200
-
201
-
202
- def deep_dict_update(main_dict: Dict[Any, Any], update_dict: Dict[Any, Any]) -> None:
203
- for key, value in update_dict.items():
204
- if (
205
- key in main_dict
206
- and isinstance(main_dict[key], dict)
207
- and isinstance(value, dict)
208
- ):
209
- deep_dict_update(main_dict[key], value)
210
- elif (
211
- key in main_dict
212
- and isinstance(main_dict[key], list)
213
- and isinstance(update_dict[key], list)
214
- ):
215
- main_dict[key] = main_dict[key] + update_dict[key]
216
- else:
217
- main_dict[key] = value
218
-
219
-
220
- def get_value_or_default(
221
- first_item: Union[DefaultPlaceholder, DefaultType],
222
- *extra_items: Union[DefaultPlaceholder, DefaultType],
223
- ) -> Union[DefaultPlaceholder, DefaultType]:
224
- """
225
- Pass items or `DefaultPlaceholder`s by descending priority.
226
-
227
- The first one to _not_ be a `DefaultPlaceholder` will be returned.
228
-
229
- Otherwise, the first item (a `DefaultPlaceholder`) will be returned.
230
- """
231
- items = (first_item,) + extra_items
232
- for item in items:
233
- if not isinstance(item, DefaultPlaceholder):
234
- return item
235
- return first_item
@@ -1,7 +0,0 @@
1
- from prefect._vendor.starlette.websockets import WebSocket as WebSocket # noqa
2
- from prefect._vendor.starlette.websockets import (
3
- WebSocketDisconnect as WebSocketDisconnect,
4
- ) # noqa
5
- from prefect._vendor.starlette.websockets import (
6
- WebSocketState as WebSocketState,
7
- ) # noqa
@@ -1 +0,0 @@
1
- __version__ = "0.33.0"
@@ -1,28 +0,0 @@
1
- import hashlib
2
-
3
- # Compat wrapper to always include the `usedforsecurity=...` parameter,
4
- # which is only added from Python 3.9 onwards.
5
- # We use this flag to indicate that we use `md5` hashes only for non-security
6
- # cases (our ETag checksums).
7
- # If we don't indicate that we're using MD5 for non-security related reasons,
8
- # then attempting to use this function will raise an error when used
9
- # environments which enable a strict "FIPs mode".
10
- #
11
- # See issue: https://github.com/encode/starlette/issues/1365
12
- try:
13
- # check if the Python version supports the parameter
14
- # using usedforsecurity=False to avoid an exception on FIPS systems
15
- # that reject usedforsecurity=True
16
- hashlib.md5(b"data", usedforsecurity=False) # type: ignore[call-arg]
17
-
18
- def md5_hexdigest(
19
- data: bytes, *, usedforsecurity: bool = True
20
- ) -> str: # pragma: no cover
21
- return hashlib.md5( # type: ignore[call-arg]
22
- data, usedforsecurity=usedforsecurity
23
- ).hexdigest()
24
-
25
- except TypeError: # pragma: no cover
26
-
27
- def md5_hexdigest(data: bytes, *, usedforsecurity: bool = True) -> str:
28
- return hashlib.md5(data).hexdigest()
@@ -1,80 +0,0 @@
1
- import typing
2
-
3
- from prefect._vendor.starlette._utils import is_async_callable
4
- from prefect._vendor.starlette.concurrency import run_in_threadpool
5
- from prefect._vendor.starlette.exceptions import HTTPException
6
- from prefect._vendor.starlette.requests import Request
7
- from prefect._vendor.starlette.types import (
8
- ASGIApp,
9
- ExceptionHandler,
10
- Message,
11
- Receive,
12
- Scope,
13
- Send,
14
- )
15
- from prefect._vendor.starlette.websockets import WebSocket
16
-
17
- ExceptionHandlers = typing.Dict[typing.Any, ExceptionHandler]
18
- StatusHandlers = typing.Dict[int, ExceptionHandler]
19
-
20
-
21
- def _lookup_exception_handler(
22
- exc_handlers: ExceptionHandlers, exc: Exception
23
- ) -> typing.Optional[ExceptionHandler]:
24
- for cls in type(exc).__mro__:
25
- if cls in exc_handlers:
26
- return exc_handlers[cls]
27
- return None
28
-
29
-
30
- def wrap_app_handling_exceptions(
31
- app: ASGIApp, conn: typing.Union[Request, WebSocket]
32
- ) -> ASGIApp:
33
- exception_handlers: ExceptionHandlers
34
- status_handlers: StatusHandlers
35
- try:
36
- exception_handlers, status_handlers = conn.scope["starlette.exception_handlers"]
37
- except KeyError:
38
- exception_handlers, status_handlers = {}, {}
39
-
40
- async def wrapped_app(scope: Scope, receive: Receive, send: Send) -> None:
41
- response_started = False
42
-
43
- async def sender(message: Message) -> None:
44
- nonlocal response_started
45
-
46
- if message["type"] == "http.response.start":
47
- response_started = True
48
- await send(message)
49
-
50
- try:
51
- await app(scope, receive, sender)
52
- except Exception as exc:
53
- handler = None
54
-
55
- if isinstance(exc, HTTPException):
56
- handler = status_handlers.get(exc.status_code)
57
-
58
- if handler is None:
59
- handler = _lookup_exception_handler(exception_handlers, exc)
60
-
61
- if handler is None:
62
- raise exc
63
-
64
- if response_started:
65
- msg = "Caught handled exception, but response already started."
66
- raise RuntimeError(msg) from exc
67
-
68
- if scope["type"] == "http":
69
- if is_async_callable(handler):
70
- response = await handler(conn, exc)
71
- else:
72
- response = await run_in_threadpool(handler, conn, exc)
73
- await response(scope, receive, sender)
74
- elif scope["type"] == "websocket":
75
- if is_async_callable(handler):
76
- await handler(conn, exc)
77
- else:
78
- await run_in_threadpool(handler, conn, exc)
79
-
80
- return wrapped_app
@@ -1,88 +0,0 @@
1
- import asyncio
2
- import functools
3
- import sys
4
- import typing
5
- from contextlib import contextmanager
6
-
7
- if sys.version_info >= (3, 10): # pragma: no cover
8
- from typing import TypeGuard
9
- else: # pragma: no cover
10
- from typing_extensions import TypeGuard
11
-
12
- has_exceptiongroups = True
13
- if sys.version_info < (3, 11): # pragma: no cover
14
- try:
15
- from exceptiongroup import BaseExceptionGroup
16
- except ImportError:
17
- has_exceptiongroups = False
18
-
19
- T = typing.TypeVar("T")
20
- AwaitableCallable = typing.Callable[..., typing.Awaitable[T]]
21
-
22
-
23
- @typing.overload
24
- def is_async_callable(obj: AwaitableCallable[T]) -> TypeGuard[AwaitableCallable[T]]:
25
- ...
26
-
27
-
28
- @typing.overload
29
- def is_async_callable(obj: typing.Any) -> TypeGuard[AwaitableCallable[typing.Any]]:
30
- ...
31
-
32
-
33
- def is_async_callable(obj: typing.Any) -> typing.Any:
34
- while isinstance(obj, functools.partial):
35
- obj = obj.func
36
-
37
- return asyncio.iscoroutinefunction(obj) or (
38
- callable(obj) and asyncio.iscoroutinefunction(obj.__call__)
39
- )
40
-
41
-
42
- T_co = typing.TypeVar("T_co", covariant=True)
43
-
44
-
45
- class AwaitableOrContextManager(
46
- typing.Awaitable[T_co], typing.AsyncContextManager[T_co], typing.Protocol[T_co]
47
- ):
48
- ...
49
-
50
-
51
- class SupportsAsyncClose(typing.Protocol):
52
- async def close(self) -> None:
53
- ... # pragma: no cover
54
-
55
-
56
- SupportsAsyncCloseType = typing.TypeVar(
57
- "SupportsAsyncCloseType", bound=SupportsAsyncClose, covariant=False
58
- )
59
-
60
-
61
- class AwaitableOrContextManagerWrapper(typing.Generic[SupportsAsyncCloseType]):
62
- __slots__ = ("aw", "entered")
63
-
64
- def __init__(self, aw: typing.Awaitable[SupportsAsyncCloseType]) -> None:
65
- self.aw = aw
66
-
67
- def __await__(self) -> typing.Generator[typing.Any, None, SupportsAsyncCloseType]:
68
- return self.aw.__await__()
69
-
70
- async def __aenter__(self) -> SupportsAsyncCloseType:
71
- self.entered = await self.aw
72
- return self.entered
73
-
74
- async def __aexit__(self, *args: typing.Any) -> typing.Union[None, bool]:
75
- await self.entered.close()
76
- return None
77
-
78
-
79
- @contextmanager
80
- def collapse_excgroups() -> typing.Generator[None, None, None]:
81
- try:
82
- yield
83
- except BaseException as exc:
84
- if has_exceptiongroups:
85
- while isinstance(exc, BaseExceptionGroup) and len(exc.exceptions) == 1:
86
- exc = exc.exceptions[0] # pragma: no cover
87
-
88
- raise exc