prefect-client 2.20.2__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 +423 -164
  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 +667 -440
  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 -2466
  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 +124 -51
  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 +138 -48
  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.2.dist-info → prefect_client-3.0.0.dist-info}/METADATA +30 -26
  161. prefect_client-3.0.0.dist-info/RECORD +201 -0
  162. {prefect_client-2.20.2.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.2.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.2.dist-info → prefect_client-3.0.0.dist-info}/LICENSE +0 -0
  288. {prefect_client-2.20.2.dist-info → prefect_client-3.0.0.dist-info}/top_level.txt +0 -0
@@ -1,15 +0,0 @@
1
- from .api_key import APIKeyCookie as APIKeyCookie
2
- from .api_key import APIKeyHeader as APIKeyHeader
3
- from .api_key import APIKeyQuery as APIKeyQuery
4
- from .http import HTTPAuthorizationCredentials as HTTPAuthorizationCredentials
5
- from .http import HTTPBasic as HTTPBasic
6
- from .http import HTTPBasicCredentials as HTTPBasicCredentials
7
- from .http import HTTPBearer as HTTPBearer
8
- from .http import HTTPDigest as HTTPDigest
9
- from .oauth2 import OAuth2 as OAuth2
10
- from .oauth2 import OAuth2AuthorizationCodeBearer as OAuth2AuthorizationCodeBearer
11
- from .oauth2 import OAuth2PasswordBearer as OAuth2PasswordBearer
12
- from .oauth2 import OAuth2PasswordRequestForm as OAuth2PasswordRequestForm
13
- from .oauth2 import OAuth2PasswordRequestFormStrict as OAuth2PasswordRequestFormStrict
14
- from .oauth2 import SecurityScopes as SecurityScopes
15
- from .open_id_connect_url import OpenIdConnect as OpenIdConnect
@@ -1,98 +0,0 @@
1
- from typing import Optional
2
-
3
- from prefect._vendor.fastapi.openapi.models import APIKey, APIKeyIn
4
- from prefect._vendor.fastapi.security.base import SecurityBase
5
- from prefect._vendor.starlette.exceptions import HTTPException
6
- from prefect._vendor.starlette.requests import Request
7
- from prefect._vendor.starlette.status import HTTP_403_FORBIDDEN
8
-
9
-
10
- class APIKeyBase(SecurityBase):
11
- pass
12
-
13
-
14
- class APIKeyQuery(APIKeyBase):
15
- def __init__(
16
- self,
17
- *,
18
- name: str,
19
- scheme_name: Optional[str] = None,
20
- description: Optional[str] = None,
21
- auto_error: bool = True,
22
- ):
23
- self.model: APIKey = APIKey(
24
- **{"in": APIKeyIn.query}, # type: ignore[arg-type]
25
- name=name,
26
- description=description,
27
- )
28
- self.scheme_name = scheme_name or self.__class__.__name__
29
- self.auto_error = auto_error
30
-
31
- async def __call__(self, request: Request) -> Optional[str]:
32
- api_key = request.query_params.get(self.model.name)
33
- if not api_key:
34
- if self.auto_error:
35
- raise HTTPException(
36
- status_code=HTTP_403_FORBIDDEN, detail="Not authenticated"
37
- )
38
- else:
39
- return None
40
- return api_key
41
-
42
-
43
- class APIKeyHeader(APIKeyBase):
44
- def __init__(
45
- self,
46
- *,
47
- name: str,
48
- scheme_name: Optional[str] = None,
49
- description: Optional[str] = None,
50
- auto_error: bool = True,
51
- ):
52
- self.model: APIKey = APIKey(
53
- **{"in": APIKeyIn.header}, # type: ignore[arg-type]
54
- name=name,
55
- description=description,
56
- )
57
- self.scheme_name = scheme_name or self.__class__.__name__
58
- self.auto_error = auto_error
59
-
60
- async def __call__(self, request: Request) -> Optional[str]:
61
- api_key = request.headers.get(self.model.name)
62
- if not api_key:
63
- if self.auto_error:
64
- raise HTTPException(
65
- status_code=HTTP_403_FORBIDDEN, detail="Not authenticated"
66
- )
67
- else:
68
- return None
69
- return api_key
70
-
71
-
72
- class APIKeyCookie(APIKeyBase):
73
- def __init__(
74
- self,
75
- *,
76
- name: str,
77
- scheme_name: Optional[str] = None,
78
- description: Optional[str] = None,
79
- auto_error: bool = True,
80
- ):
81
- self.model: APIKey = APIKey(
82
- **{"in": APIKeyIn.cookie}, # type: ignore[arg-type]
83
- name=name,
84
- description=description,
85
- )
86
- self.scheme_name = scheme_name or self.__class__.__name__
87
- self.auto_error = auto_error
88
-
89
- async def __call__(self, request: Request) -> Optional[str]:
90
- api_key = request.cookies.get(self.model.name)
91
- if not api_key:
92
- if self.auto_error:
93
- raise HTTPException(
94
- status_code=HTTP_403_FORBIDDEN, detail="Not authenticated"
95
- )
96
- else:
97
- return None
98
- return api_key
@@ -1,6 +0,0 @@
1
- from prefect._vendor.fastapi.openapi.models import SecurityBase as SecurityBaseModel
2
-
3
-
4
- class SecurityBase:
5
- model: SecurityBaseModel
6
- scheme_name: str
@@ -1,172 +0,0 @@
1
- import binascii
2
- from base64 import b64decode
3
- from typing import Optional
4
-
5
- from prefect._vendor.fastapi.exceptions import HTTPException
6
- from prefect._vendor.fastapi.openapi.models import HTTPBase as HTTPBaseModel
7
- from prefect._vendor.fastapi.openapi.models import HTTPBearer as HTTPBearerModel
8
- from prefect._vendor.fastapi.security.base import SecurityBase
9
- from prefect._vendor.fastapi.security.utils import get_authorization_scheme_param
10
-
11
- from prefect._internal.pydantic import HAS_PYDANTIC_V2
12
-
13
- if HAS_PYDANTIC_V2:
14
- from pydantic.v1 import BaseModel
15
- else:
16
- from pydantic import BaseModel
17
-
18
- from prefect._vendor.starlette.requests import Request
19
- from prefect._vendor.starlette.status import HTTP_401_UNAUTHORIZED, HTTP_403_FORBIDDEN
20
-
21
-
22
- class HTTPBasicCredentials(BaseModel):
23
- username: str
24
- password: str
25
-
26
-
27
- class HTTPAuthorizationCredentials(BaseModel):
28
- scheme: str
29
- credentials: str
30
-
31
-
32
- class HTTPBase(SecurityBase):
33
- def __init__(
34
- self,
35
- *,
36
- scheme: str,
37
- scheme_name: Optional[str] = None,
38
- description: Optional[str] = None,
39
- auto_error: bool = True,
40
- ):
41
- self.model = HTTPBaseModel(scheme=scheme, description=description)
42
- self.scheme_name = scheme_name or self.__class__.__name__
43
- self.auto_error = auto_error
44
-
45
- async def __call__(
46
- self, request: Request
47
- ) -> Optional[HTTPAuthorizationCredentials]:
48
- authorization = request.headers.get("Authorization")
49
- scheme, credentials = get_authorization_scheme_param(authorization)
50
- if not (authorization and scheme and credentials):
51
- if self.auto_error:
52
- raise HTTPException(
53
- status_code=HTTP_403_FORBIDDEN, detail="Not authenticated"
54
- )
55
- else:
56
- return None
57
- return HTTPAuthorizationCredentials(scheme=scheme, credentials=credentials)
58
-
59
-
60
- class HTTPBasic(HTTPBase):
61
- def __init__(
62
- self,
63
- *,
64
- scheme_name: Optional[str] = None,
65
- realm: Optional[str] = None,
66
- description: Optional[str] = None,
67
- auto_error: bool = True,
68
- ):
69
- self.model = HTTPBaseModel(scheme="basic", description=description)
70
- self.scheme_name = scheme_name or self.__class__.__name__
71
- self.realm = realm
72
- self.auto_error = auto_error
73
-
74
- async def __call__( # type: ignore
75
- self, request: Request
76
- ) -> Optional[HTTPBasicCredentials]:
77
- authorization = request.headers.get("Authorization")
78
- scheme, param = get_authorization_scheme_param(authorization)
79
- if self.realm:
80
- unauthorized_headers = {"WWW-Authenticate": f'Basic realm="{self.realm}"'}
81
- else:
82
- unauthorized_headers = {"WWW-Authenticate": "Basic"}
83
- if not authorization or scheme.lower() != "basic":
84
- if self.auto_error:
85
- raise HTTPException(
86
- status_code=HTTP_401_UNAUTHORIZED,
87
- detail="Not authenticated",
88
- headers=unauthorized_headers,
89
- )
90
- else:
91
- return None
92
- invalid_user_credentials_exc = HTTPException(
93
- status_code=HTTP_401_UNAUTHORIZED,
94
- detail="Invalid authentication credentials",
95
- headers=unauthorized_headers,
96
- )
97
- try:
98
- data = b64decode(param).decode("ascii")
99
- except (ValueError, UnicodeDecodeError, binascii.Error):
100
- raise invalid_user_credentials_exc
101
- username, separator, password = data.partition(":")
102
- if not separator:
103
- raise invalid_user_credentials_exc
104
- return HTTPBasicCredentials(username=username, password=password)
105
-
106
-
107
- class HTTPBearer(HTTPBase):
108
- def __init__(
109
- self,
110
- *,
111
- bearerFormat: Optional[str] = None,
112
- scheme_name: Optional[str] = None,
113
- description: Optional[str] = None,
114
- auto_error: bool = True,
115
- ):
116
- self.model = HTTPBearerModel(bearerFormat=bearerFormat, description=description)
117
- self.scheme_name = scheme_name or self.__class__.__name__
118
- self.auto_error = auto_error
119
-
120
- async def __call__(
121
- self, request: Request
122
- ) -> Optional[HTTPAuthorizationCredentials]:
123
- authorization = request.headers.get("Authorization")
124
- scheme, credentials = get_authorization_scheme_param(authorization)
125
- if not (authorization and scheme and credentials):
126
- if self.auto_error:
127
- raise HTTPException(
128
- status_code=HTTP_403_FORBIDDEN, detail="Not authenticated"
129
- )
130
- else:
131
- return None
132
- if scheme.lower() != "bearer":
133
- if self.auto_error:
134
- raise HTTPException(
135
- status_code=HTTP_403_FORBIDDEN,
136
- detail="Invalid authentication credentials",
137
- )
138
- else:
139
- return None
140
- return HTTPAuthorizationCredentials(scheme=scheme, credentials=credentials)
141
-
142
-
143
- class HTTPDigest(HTTPBase):
144
- def __init__(
145
- self,
146
- *,
147
- scheme_name: Optional[str] = None,
148
- description: Optional[str] = None,
149
- auto_error: bool = True,
150
- ):
151
- self.model = HTTPBaseModel(scheme="digest", description=description)
152
- self.scheme_name = scheme_name or self.__class__.__name__
153
- self.auto_error = auto_error
154
-
155
- async def __call__(
156
- self, request: Request
157
- ) -> Optional[HTTPAuthorizationCredentials]:
158
- authorization = request.headers.get("Authorization")
159
- scheme, credentials = get_authorization_scheme_param(authorization)
160
- if not (authorization and scheme and credentials):
161
- if self.auto_error:
162
- raise HTTPException(
163
- status_code=HTTP_403_FORBIDDEN, detail="Not authenticated"
164
- )
165
- else:
166
- return None
167
- if scheme.lower() != "digest":
168
- raise HTTPException(
169
- status_code=HTTP_403_FORBIDDEN,
170
- detail="Invalid authentication credentials",
171
- )
172
- return HTTPAuthorizationCredentials(scheme=scheme, credentials=credentials)
@@ -1,227 +0,0 @@
1
- from typing import Any, Dict, List, Optional, Union, cast
2
-
3
- from prefect._vendor.fastapi.exceptions import HTTPException
4
- from prefect._vendor.fastapi.openapi.models import OAuth2 as OAuth2Model
5
- from prefect._vendor.fastapi.openapi.models import OAuthFlows as OAuthFlowsModel
6
- from prefect._vendor.fastapi.param_functions import Form
7
- from prefect._vendor.fastapi.security.base import SecurityBase
8
- from prefect._vendor.fastapi.security.utils import get_authorization_scheme_param
9
- from prefect._vendor.starlette.requests import Request
10
- from prefect._vendor.starlette.status import HTTP_401_UNAUTHORIZED, HTTP_403_FORBIDDEN
11
-
12
-
13
- class OAuth2PasswordRequestForm:
14
- """
15
- This is a dependency class, use it like:
16
-
17
- @app.post("/login")
18
- def login(form_data: OAuth2PasswordRequestForm = Depends()):
19
- data = form_data.parse()
20
- print(data.username)
21
- print(data.password)
22
- for scope in data.scopes:
23
- print(scope)
24
- if data.client_id:
25
- print(data.client_id)
26
- if data.client_secret:
27
- print(data.client_secret)
28
- return data
29
-
30
-
31
- It creates the following Form request parameters in your endpoint:
32
-
33
- grant_type: the OAuth2 spec says it is required and MUST be the fixed string "password".
34
- Nevertheless, this dependency class is permissive and allows not passing it. If you want to enforce it,
35
- use instead the OAuth2PasswordRequestFormStrict dependency.
36
- username: username string. The OAuth2 spec requires the exact field name "username".
37
- password: password string. The OAuth2 spec requires the exact field name "password".
38
- scope: Optional string. Several scopes (each one a string) separated by spaces. E.g.
39
- "items:read items:write users:read profile openid"
40
- client_id: optional string. OAuth2 recommends sending the client_id and client_secret (if any)
41
- using HTTP Basic auth, as: client_id:client_secret
42
- client_secret: optional string. OAuth2 recommends sending the client_id and client_secret (if any)
43
- using HTTP Basic auth, as: client_id:client_secret
44
- """
45
-
46
- def __init__(
47
- self,
48
- grant_type: str = Form(default=None, regex="password"),
49
- username: str = Form(),
50
- password: str = Form(),
51
- scope: str = Form(default=""),
52
- client_id: Optional[str] = Form(default=None),
53
- client_secret: Optional[str] = Form(default=None),
54
- ):
55
- self.grant_type = grant_type
56
- self.username = username
57
- self.password = password
58
- self.scopes = scope.split()
59
- self.client_id = client_id
60
- self.client_secret = client_secret
61
-
62
-
63
- class OAuth2PasswordRequestFormStrict(OAuth2PasswordRequestForm):
64
- """
65
- This is a dependency class, use it like:
66
-
67
- @app.post("/login")
68
- def login(form_data: OAuth2PasswordRequestFormStrict = Depends()):
69
- data = form_data.parse()
70
- print(data.username)
71
- print(data.password)
72
- for scope in data.scopes:
73
- print(scope)
74
- if data.client_id:
75
- print(data.client_id)
76
- if data.client_secret:
77
- print(data.client_secret)
78
- return data
79
-
80
-
81
- It creates the following Form request parameters in your endpoint:
82
-
83
- grant_type: the OAuth2 spec says it is required and MUST be the fixed string "password".
84
- This dependency is strict about it. If you want to be permissive, use instead the
85
- OAuth2PasswordRequestForm dependency class.
86
- username: username string. The OAuth2 spec requires the exact field name "username".
87
- password: password string. The OAuth2 spec requires the exact field name "password".
88
- scope: Optional string. Several scopes (each one a string) separated by spaces. E.g.
89
- "items:read items:write users:read profile openid"
90
- client_id: optional string. OAuth2 recommends sending the client_id and client_secret (if any)
91
- using HTTP Basic auth, as: client_id:client_secret
92
- client_secret: optional string. OAuth2 recommends sending the client_id and client_secret (if any)
93
- using HTTP Basic auth, as: client_id:client_secret
94
- """
95
-
96
- def __init__(
97
- self,
98
- grant_type: str = Form(regex="password"),
99
- username: str = Form(),
100
- password: str = Form(),
101
- scope: str = Form(default=""),
102
- client_id: Optional[str] = Form(default=None),
103
- client_secret: Optional[str] = Form(default=None),
104
- ):
105
- super().__init__(
106
- grant_type=grant_type,
107
- username=username,
108
- password=password,
109
- scope=scope,
110
- client_id=client_id,
111
- client_secret=client_secret,
112
- )
113
-
114
-
115
- class OAuth2(SecurityBase):
116
- def __init__(
117
- self,
118
- *,
119
- flows: Union[OAuthFlowsModel, Dict[str, Dict[str, Any]]] = OAuthFlowsModel(),
120
- scheme_name: Optional[str] = None,
121
- description: Optional[str] = None,
122
- auto_error: bool = True,
123
- ):
124
- self.model = OAuth2Model(
125
- flows=cast(OAuthFlowsModel, flows), description=description
126
- )
127
- self.scheme_name = scheme_name or self.__class__.__name__
128
- self.auto_error = auto_error
129
-
130
- async def __call__(self, request: Request) -> Optional[str]:
131
- authorization = request.headers.get("Authorization")
132
- if not authorization:
133
- if self.auto_error:
134
- raise HTTPException(
135
- status_code=HTTP_403_FORBIDDEN, detail="Not authenticated"
136
- )
137
- else:
138
- return None
139
- return authorization
140
-
141
-
142
- class OAuth2PasswordBearer(OAuth2):
143
- def __init__(
144
- self,
145
- tokenUrl: str,
146
- scheme_name: Optional[str] = None,
147
- scopes: Optional[Dict[str, str]] = None,
148
- description: Optional[str] = None,
149
- auto_error: bool = True,
150
- ):
151
- if not scopes:
152
- scopes = {}
153
- flows = OAuthFlowsModel(
154
- password=cast(Any, {"tokenUrl": tokenUrl, "scopes": scopes})
155
- )
156
- super().__init__(
157
- flows=flows,
158
- scheme_name=scheme_name,
159
- description=description,
160
- auto_error=auto_error,
161
- )
162
-
163
- async def __call__(self, request: Request) -> Optional[str]:
164
- authorization = request.headers.get("Authorization")
165
- scheme, param = get_authorization_scheme_param(authorization)
166
- if not authorization or scheme.lower() != "bearer":
167
- if self.auto_error:
168
- raise HTTPException(
169
- status_code=HTTP_401_UNAUTHORIZED,
170
- detail="Not authenticated",
171
- headers={"WWW-Authenticate": "Bearer"},
172
- )
173
- else:
174
- return None
175
- return param
176
-
177
-
178
- class OAuth2AuthorizationCodeBearer(OAuth2):
179
- def __init__(
180
- self,
181
- authorizationUrl: str,
182
- tokenUrl: str,
183
- refreshUrl: Optional[str] = None,
184
- scheme_name: Optional[str] = None,
185
- scopes: Optional[Dict[str, str]] = None,
186
- description: Optional[str] = None,
187
- auto_error: bool = True,
188
- ):
189
- if not scopes:
190
- scopes = {}
191
- flows = OAuthFlowsModel(
192
- authorizationCode=cast(
193
- Any,
194
- {
195
- "authorizationUrl": authorizationUrl,
196
- "tokenUrl": tokenUrl,
197
- "refreshUrl": refreshUrl,
198
- "scopes": scopes,
199
- },
200
- )
201
- )
202
- super().__init__(
203
- flows=flows,
204
- scheme_name=scheme_name,
205
- description=description,
206
- auto_error=auto_error,
207
- )
208
-
209
- async def __call__(self, request: Request) -> Optional[str]:
210
- authorization = request.headers.get("Authorization")
211
- scheme, param = get_authorization_scheme_param(authorization)
212
- if not authorization or scheme.lower() != "bearer":
213
- if self.auto_error:
214
- raise HTTPException(
215
- status_code=HTTP_401_UNAUTHORIZED,
216
- detail="Not authenticated",
217
- headers={"WWW-Authenticate": "Bearer"},
218
- )
219
- else:
220
- return None # pragma: nocover
221
- return param
222
-
223
-
224
- class SecurityScopes:
225
- def __init__(self, scopes: Optional[List[str]] = None):
226
- self.scopes = scopes or []
227
- self.scope_str = " ".join(self.scopes)
@@ -1,34 +0,0 @@
1
- from typing import Optional
2
-
3
- from prefect._vendor.fastapi.openapi.models import OpenIdConnect as OpenIdConnectModel
4
- from prefect._vendor.fastapi.security.base import SecurityBase
5
- from prefect._vendor.starlette.exceptions import HTTPException
6
- from prefect._vendor.starlette.requests import Request
7
- from prefect._vendor.starlette.status import HTTP_403_FORBIDDEN
8
-
9
-
10
- class OpenIdConnect(SecurityBase):
11
- def __init__(
12
- self,
13
- *,
14
- openIdConnectUrl: str,
15
- scheme_name: Optional[str] = None,
16
- description: Optional[str] = None,
17
- auto_error: bool = True,
18
- ):
19
- self.model = OpenIdConnectModel(
20
- openIdConnectUrl=openIdConnectUrl, description=description
21
- )
22
- self.scheme_name = scheme_name or self.__class__.__name__
23
- self.auto_error = auto_error
24
-
25
- async def __call__(self, request: Request) -> Optional[str]:
26
- authorization = request.headers.get("Authorization")
27
- if not authorization:
28
- if self.auto_error:
29
- raise HTTPException(
30
- status_code=HTTP_403_FORBIDDEN, detail="Not authenticated"
31
- )
32
- else:
33
- return None
34
- return authorization
@@ -1,10 +0,0 @@
1
- from typing import Optional, Tuple
2
-
3
-
4
- def get_authorization_scheme_param(
5
- authorization_header_value: Optional[str],
6
- ) -> Tuple[str, str]:
7
- if not authorization_header_value:
8
- return "", ""
9
- scheme, _, param = authorization_header_value.partition(" ")
10
- return scheme, param
@@ -1 +0,0 @@
1
- from prefect._vendor.starlette.staticfiles import StaticFiles as StaticFiles # noqa
@@ -1,3 +0,0 @@
1
- from prefect._vendor.starlette.templating import (
2
- Jinja2Templates as Jinja2Templates,
3
- )
@@ -1 +0,0 @@
1
- from prefect._vendor.starlette.testclient import TestClient as TestClient # noqa
@@ -1,3 +0,0 @@
1
- from typing import Any, Callable, TypeVar
2
-
3
- DecoratedCallable = TypeVar("DecoratedCallable", bound=Callable[..., Any])