prefect-client 2.19.4__py3-none-any.whl → 3.0.0rc2__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.
- prefect/__init__.py +8 -56
- prefect/_internal/compatibility/deprecated.py +6 -115
- prefect/_internal/compatibility/experimental.py +4 -79
- prefect/_internal/concurrency/api.py +0 -34
- prefect/_internal/concurrency/calls.py +0 -6
- prefect/_internal/concurrency/cancellation.py +0 -3
- prefect/_internal/concurrency/event_loop.py +0 -20
- prefect/_internal/concurrency/inspection.py +3 -3
- prefect/_internal/concurrency/threads.py +35 -0
- prefect/_internal/concurrency/waiters.py +0 -28
- prefect/_internal/pydantic/__init__.py +0 -45
- prefect/_internal/pydantic/v1_schema.py +21 -22
- prefect/_internal/pydantic/v2_schema.py +0 -2
- prefect/_internal/pydantic/v2_validated_func.py +18 -23
- prefect/_internal/schemas/bases.py +44 -177
- prefect/_internal/schemas/fields.py +1 -43
- prefect/_internal/schemas/validators.py +60 -158
- prefect/artifacts.py +161 -14
- prefect/automations.py +39 -4
- prefect/blocks/abstract.py +1 -1
- prefect/blocks/core.py +268 -148
- prefect/blocks/fields.py +2 -57
- prefect/blocks/kubernetes.py +8 -12
- prefect/blocks/notifications.py +40 -20
- prefect/blocks/redis.py +168 -0
- prefect/blocks/system.py +22 -11
- prefect/blocks/webhook.py +2 -9
- prefect/client/base.py +4 -4
- prefect/client/cloud.py +8 -13
- prefect/client/orchestration.py +362 -340
- prefect/client/schemas/actions.py +92 -86
- prefect/client/schemas/filters.py +20 -40
- prefect/client/schemas/objects.py +158 -152
- prefect/client/schemas/responses.py +16 -24
- prefect/client/schemas/schedules.py +47 -35
- prefect/client/subscriptions.py +2 -2
- prefect/client/utilities.py +5 -2
- prefect/concurrency/asyncio.py +4 -2
- prefect/concurrency/events.py +1 -1
- prefect/concurrency/services.py +7 -4
- prefect/context.py +195 -27
- prefect/deployments/__init__.py +5 -6
- prefect/deployments/base.py +7 -5
- prefect/deployments/flow_runs.py +185 -0
- prefect/deployments/runner.py +50 -45
- prefect/deployments/schedules.py +28 -23
- prefect/deployments/steps/__init__.py +0 -1
- prefect/deployments/steps/core.py +1 -0
- prefect/deployments/steps/pull.py +7 -21
- prefect/engine.py +12 -2422
- prefect/events/actions.py +17 -23
- prefect/events/cli/automations.py +19 -6
- prefect/events/clients.py +14 -37
- prefect/events/filters.py +14 -18
- prefect/events/related.py +2 -2
- prefect/events/schemas/__init__.py +0 -5
- prefect/events/schemas/automations.py +55 -46
- prefect/events/schemas/deployment_triggers.py +7 -197
- prefect/events/schemas/events.py +36 -65
- prefect/events/schemas/labelling.py +10 -14
- prefect/events/utilities.py +2 -3
- prefect/events/worker.py +2 -3
- prefect/filesystems.py +6 -517
- prefect/{new_flow_engine.py → flow_engine.py} +315 -74
- prefect/flow_runs.py +379 -7
- prefect/flows.py +248 -165
- prefect/futures.py +187 -345
- prefect/infrastructure/__init__.py +0 -27
- prefect/infrastructure/provisioners/__init__.py +5 -3
- prefect/infrastructure/provisioners/cloud_run.py +11 -6
- prefect/infrastructure/provisioners/container_instance.py +11 -7
- prefect/infrastructure/provisioners/ecs.py +6 -4
- prefect/infrastructure/provisioners/modal.py +8 -5
- prefect/input/actions.py +2 -4
- prefect/input/run_input.py +9 -9
- prefect/logging/formatters.py +0 -2
- prefect/logging/handlers.py +3 -11
- prefect/logging/loggers.py +2 -2
- prefect/manifests.py +2 -1
- prefect/records/__init__.py +1 -0
- prefect/records/cache_policies.py +179 -0
- prefect/records/result_store.py +42 -0
- prefect/records/store.py +9 -0
- prefect/results.py +43 -39
- prefect/runner/runner.py +9 -9
- prefect/runner/server.py +6 -10
- prefect/runner/storage.py +3 -8
- prefect/runner/submit.py +2 -2
- prefect/runner/utils.py +2 -2
- prefect/serializers.py +24 -35
- prefect/server/api/collections_data/views/aggregate-worker-metadata.json +5 -14
- prefect/settings.py +76 -136
- prefect/states.py +22 -50
- prefect/task_engine.py +666 -56
- prefect/task_runners.py +272 -300
- prefect/task_runs.py +203 -0
- prefect/{task_server.py → task_worker.py} +89 -60
- prefect/tasks.py +358 -341
- prefect/transactions.py +224 -0
- prefect/types/__init__.py +61 -82
- prefect/utilities/asyncutils.py +195 -136
- prefect/utilities/callables.py +121 -41
- prefect/utilities/collections.py +23 -38
- prefect/utilities/dispatch.py +11 -3
- prefect/utilities/dockerutils.py +4 -0
- prefect/utilities/engine.py +140 -20
- prefect/utilities/importtools.py +26 -27
- prefect/utilities/pydantic.py +128 -38
- prefect/utilities/schema_tools/hydration.py +5 -1
- prefect/utilities/templating.py +12 -2
- prefect/variables.py +84 -62
- prefect/workers/__init__.py +0 -1
- prefect/workers/base.py +26 -18
- prefect/workers/process.py +3 -8
- prefect/workers/server.py +2 -2
- {prefect_client-2.19.4.dist-info → prefect_client-3.0.0rc2.dist-info}/METADATA +23 -21
- prefect_client-3.0.0rc2.dist-info/RECORD +179 -0
- prefect/_internal/pydantic/_base_model.py +0 -51
- prefect/_internal/pydantic/_compat.py +0 -82
- prefect/_internal/pydantic/_flags.py +0 -20
- prefect/_internal/pydantic/_types.py +0 -8
- prefect/_internal/pydantic/utilities/__init__.py +0 -0
- prefect/_internal/pydantic/utilities/config_dict.py +0 -72
- prefect/_internal/pydantic/utilities/field_validator.py +0 -150
- prefect/_internal/pydantic/utilities/model_construct.py +0 -56
- prefect/_internal/pydantic/utilities/model_copy.py +0 -55
- prefect/_internal/pydantic/utilities/model_dump.py +0 -136
- prefect/_internal/pydantic/utilities/model_dump_json.py +0 -112
- prefect/_internal/pydantic/utilities/model_fields.py +0 -50
- prefect/_internal/pydantic/utilities/model_fields_set.py +0 -29
- prefect/_internal/pydantic/utilities/model_json_schema.py +0 -82
- prefect/_internal/pydantic/utilities/model_rebuild.py +0 -80
- prefect/_internal/pydantic/utilities/model_validate.py +0 -75
- prefect/_internal/pydantic/utilities/model_validate_json.py +0 -68
- prefect/_internal/pydantic/utilities/model_validator.py +0 -87
- prefect/_internal/pydantic/utilities/type_adapter.py +0 -71
- prefect/_vendor/__init__.py +0 -0
- prefect/_vendor/fastapi/__init__.py +0 -25
- prefect/_vendor/fastapi/applications.py +0 -946
- prefect/_vendor/fastapi/background.py +0 -3
- prefect/_vendor/fastapi/concurrency.py +0 -44
- prefect/_vendor/fastapi/datastructures.py +0 -58
- prefect/_vendor/fastapi/dependencies/__init__.py +0 -0
- prefect/_vendor/fastapi/dependencies/models.py +0 -64
- prefect/_vendor/fastapi/dependencies/utils.py +0 -877
- prefect/_vendor/fastapi/encoders.py +0 -177
- prefect/_vendor/fastapi/exception_handlers.py +0 -40
- prefect/_vendor/fastapi/exceptions.py +0 -46
- prefect/_vendor/fastapi/logger.py +0 -3
- prefect/_vendor/fastapi/middleware/__init__.py +0 -1
- prefect/_vendor/fastapi/middleware/asyncexitstack.py +0 -25
- prefect/_vendor/fastapi/middleware/cors.py +0 -3
- prefect/_vendor/fastapi/middleware/gzip.py +0 -3
- prefect/_vendor/fastapi/middleware/httpsredirect.py +0 -3
- prefect/_vendor/fastapi/middleware/trustedhost.py +0 -3
- prefect/_vendor/fastapi/middleware/wsgi.py +0 -3
- prefect/_vendor/fastapi/openapi/__init__.py +0 -0
- prefect/_vendor/fastapi/openapi/constants.py +0 -2
- prefect/_vendor/fastapi/openapi/docs.py +0 -203
- prefect/_vendor/fastapi/openapi/models.py +0 -480
- prefect/_vendor/fastapi/openapi/utils.py +0 -485
- prefect/_vendor/fastapi/param_functions.py +0 -340
- prefect/_vendor/fastapi/params.py +0 -453
- prefect/_vendor/fastapi/requests.py +0 -4
- prefect/_vendor/fastapi/responses.py +0 -40
- prefect/_vendor/fastapi/routing.py +0 -1331
- prefect/_vendor/fastapi/security/__init__.py +0 -15
- prefect/_vendor/fastapi/security/api_key.py +0 -98
- prefect/_vendor/fastapi/security/base.py +0 -6
- prefect/_vendor/fastapi/security/http.py +0 -172
- prefect/_vendor/fastapi/security/oauth2.py +0 -227
- prefect/_vendor/fastapi/security/open_id_connect_url.py +0 -34
- prefect/_vendor/fastapi/security/utils.py +0 -10
- prefect/_vendor/fastapi/staticfiles.py +0 -1
- prefect/_vendor/fastapi/templating.py +0 -3
- prefect/_vendor/fastapi/testclient.py +0 -1
- prefect/_vendor/fastapi/types.py +0 -3
- prefect/_vendor/fastapi/utils.py +0 -235
- prefect/_vendor/fastapi/websockets.py +0 -7
- prefect/_vendor/starlette/__init__.py +0 -1
- prefect/_vendor/starlette/_compat.py +0 -28
- prefect/_vendor/starlette/_exception_handler.py +0 -80
- prefect/_vendor/starlette/_utils.py +0 -88
- prefect/_vendor/starlette/applications.py +0 -261
- prefect/_vendor/starlette/authentication.py +0 -159
- prefect/_vendor/starlette/background.py +0 -43
- prefect/_vendor/starlette/concurrency.py +0 -59
- prefect/_vendor/starlette/config.py +0 -151
- prefect/_vendor/starlette/convertors.py +0 -87
- prefect/_vendor/starlette/datastructures.py +0 -707
- prefect/_vendor/starlette/endpoints.py +0 -130
- prefect/_vendor/starlette/exceptions.py +0 -60
- prefect/_vendor/starlette/formparsers.py +0 -276
- prefect/_vendor/starlette/middleware/__init__.py +0 -17
- prefect/_vendor/starlette/middleware/authentication.py +0 -52
- prefect/_vendor/starlette/middleware/base.py +0 -220
- prefect/_vendor/starlette/middleware/cors.py +0 -176
- prefect/_vendor/starlette/middleware/errors.py +0 -265
- prefect/_vendor/starlette/middleware/exceptions.py +0 -74
- prefect/_vendor/starlette/middleware/gzip.py +0 -113
- prefect/_vendor/starlette/middleware/httpsredirect.py +0 -19
- prefect/_vendor/starlette/middleware/sessions.py +0 -82
- prefect/_vendor/starlette/middleware/trustedhost.py +0 -64
- prefect/_vendor/starlette/middleware/wsgi.py +0 -147
- prefect/_vendor/starlette/requests.py +0 -328
- prefect/_vendor/starlette/responses.py +0 -347
- prefect/_vendor/starlette/routing.py +0 -933
- prefect/_vendor/starlette/schemas.py +0 -154
- prefect/_vendor/starlette/staticfiles.py +0 -248
- prefect/_vendor/starlette/status.py +0 -199
- prefect/_vendor/starlette/templating.py +0 -231
- prefect/_vendor/starlette/testclient.py +0 -804
- prefect/_vendor/starlette/types.py +0 -30
- prefect/_vendor/starlette/websockets.py +0 -193
- prefect/agent.py +0 -698
- prefect/deployments/deployments.py +0 -1042
- prefect/deprecated/__init__.py +0 -0
- prefect/deprecated/data_documents.py +0 -350
- prefect/deprecated/packaging/__init__.py +0 -12
- prefect/deprecated/packaging/base.py +0 -96
- prefect/deprecated/packaging/docker.py +0 -146
- prefect/deprecated/packaging/file.py +0 -92
- prefect/deprecated/packaging/orion.py +0 -80
- prefect/deprecated/packaging/serializers.py +0 -171
- prefect/events/instrument.py +0 -135
- prefect/infrastructure/base.py +0 -323
- prefect/infrastructure/container.py +0 -818
- prefect/infrastructure/kubernetes.py +0 -920
- prefect/infrastructure/process.py +0 -289
- prefect/new_task_engine.py +0 -423
- prefect/pydantic/__init__.py +0 -76
- prefect/pydantic/main.py +0 -39
- prefect/software/__init__.py +0 -2
- prefect/software/base.py +0 -50
- prefect/software/conda.py +0 -199
- prefect/software/pip.py +0 -122
- prefect/software/python.py +0 -52
- prefect/workers/block.py +0 -218
- prefect_client-2.19.4.dist-info/RECORD +0 -292
- {prefect_client-2.19.4.dist-info → prefect_client-3.0.0rc2.dist-info}/LICENSE +0 -0
- {prefect_client-2.19.4.dist-info → prefect_client-3.0.0rc2.dist-info}/WHEEL +0 -0
- {prefect_client-2.19.4.dist-info → prefect_client-3.0.0rc2.dist-info}/top_level.txt +0 -0
prefect/client/orchestration.py
CHANGED
@@ -8,12 +8,13 @@ from typing import (
|
|
8
8
|
Dict,
|
9
9
|
Iterable,
|
10
10
|
List,
|
11
|
-
|
11
|
+
Literal,
|
12
12
|
Optional,
|
13
13
|
Set,
|
14
14
|
Tuple,
|
15
15
|
TypeVar,
|
16
16
|
Union,
|
17
|
+
overload,
|
17
18
|
)
|
18
19
|
from uuid import UUID, uuid4
|
19
20
|
|
@@ -21,35 +22,20 @@ import certifi
|
|
21
22
|
import httpcore
|
22
23
|
import httpx
|
23
24
|
import pendulum
|
24
|
-
|
25
|
-
|
26
|
-
from prefect._internal.compatibility.deprecated import (
|
27
|
-
handle_deprecated_infra_overrides_parameter,
|
28
|
-
)
|
29
|
-
from prefect._internal.pydantic import HAS_PYDANTIC_V2
|
30
|
-
from prefect.client.schemas import sorting
|
31
|
-
from prefect.events import filters
|
32
|
-
from prefect.settings import (
|
33
|
-
PREFECT_API_SERVICES_TRIGGERS_ENABLED,
|
34
|
-
PREFECT_EXPERIMENTAL_EVENTS,
|
35
|
-
)
|
36
|
-
|
37
|
-
if HAS_PYDANTIC_V2:
|
38
|
-
import pydantic.v1 as pydantic
|
39
|
-
else:
|
40
|
-
import pydantic
|
41
|
-
|
25
|
+
import pydantic
|
42
26
|
from asgi_lifespan import LifespanManager
|
43
|
-
from
|
27
|
+
from starlette import status
|
28
|
+
from typing_extensions import ParamSpec
|
44
29
|
|
45
30
|
import prefect
|
46
31
|
import prefect.exceptions
|
47
32
|
import prefect.settings
|
48
33
|
import prefect.states
|
49
34
|
from prefect.client.constants import SERVER_API_VERSION
|
50
|
-
from prefect.client.schemas import FlowRun, OrchestrationResult, TaskRun
|
35
|
+
from prefect.client.schemas import FlowRun, OrchestrationResult, TaskRun, sorting
|
51
36
|
from prefect.client.schemas.actions import (
|
52
37
|
ArtifactCreate,
|
38
|
+
ArtifactUpdate,
|
53
39
|
BlockDocumentCreate,
|
54
40
|
BlockDocumentUpdate,
|
55
41
|
BlockSchemaCreate,
|
@@ -133,7 +119,7 @@ from prefect.client.schemas.sorting import (
|
|
133
119
|
LogSort,
|
134
120
|
TaskRunSort,
|
135
121
|
)
|
136
|
-
from prefect.
|
122
|
+
from prefect.events import filters
|
137
123
|
from prefect.events.schemas.automations import Automation, AutomationCore
|
138
124
|
from prefect.logging import get_logger
|
139
125
|
from prefect.settings import (
|
@@ -171,16 +157,24 @@ class ServerType(AutoEnum):
|
|
171
157
|
SERVER = AutoEnum.auto()
|
172
158
|
CLOUD = AutoEnum.auto()
|
173
159
|
|
174
|
-
def supports_automations(self) -> bool:
|
175
|
-
if self == ServerType.CLOUD:
|
176
|
-
return True
|
177
160
|
|
178
|
-
|
161
|
+
@overload
|
162
|
+
def get_client(
|
163
|
+
httpx_settings: Optional[Dict[str, Any]] = None, sync_client: Literal[False] = False
|
164
|
+
) -> "PrefectClient":
|
165
|
+
...
|
166
|
+
|
167
|
+
|
168
|
+
@overload
|
169
|
+
def get_client(
|
170
|
+
httpx_settings: Optional[Dict[str, Any]] = None, sync_client: Literal[True] = True
|
171
|
+
) -> "SyncPrefectClient":
|
172
|
+
...
|
179
173
|
|
180
174
|
|
181
175
|
def get_client(
|
182
176
|
httpx_settings: Optional[Dict[str, Any]] = None, sync_client: bool = False
|
183
|
-
)
|
177
|
+
):
|
184
178
|
"""
|
185
179
|
Retrieve a HTTP client for communicating with the Prefect REST API.
|
186
180
|
|
@@ -198,14 +192,39 @@ def get_client(
|
|
198
192
|
client.hello()
|
199
193
|
```
|
200
194
|
"""
|
201
|
-
|
195
|
+
import prefect.context
|
196
|
+
|
197
|
+
settings_ctx = prefect.context.get_settings_context()
|
198
|
+
|
199
|
+
# try to load clients from a client context, if possible
|
200
|
+
# only load clients that match the provided config / loop
|
201
|
+
try:
|
202
|
+
loop = asyncio.get_running_loop()
|
203
|
+
except RuntimeError:
|
204
|
+
loop = None
|
205
|
+
|
206
|
+
if client_ctx := prefect.context.ClientContext.get():
|
207
|
+
if (
|
208
|
+
sync_client
|
209
|
+
and client_ctx.sync_client
|
210
|
+
and client_ctx._httpx_settings == httpx_settings
|
211
|
+
):
|
212
|
+
return client_ctx.sync_client
|
213
|
+
elif (
|
214
|
+
not sync_client
|
215
|
+
and client_ctx.async_client
|
216
|
+
and client_ctx._httpx_settings == httpx_settings
|
217
|
+
and loop in (client_ctx.async_client._loop, None)
|
218
|
+
):
|
219
|
+
return client_ctx.async_client
|
220
|
+
|
202
221
|
api = PREFECT_API_URL.value()
|
203
222
|
|
204
223
|
if not api:
|
205
224
|
# create an ephemeral API if none was provided
|
206
225
|
from prefect.server.api.server import create_app
|
207
226
|
|
208
|
-
api = create_app(
|
227
|
+
api = create_app(settings_ctx.settings, ephemeral=True)
|
209
228
|
|
210
229
|
if sync_client:
|
211
230
|
return SyncPrefectClient(
|
@@ -273,6 +292,7 @@ class PrefectClient:
|
|
273
292
|
httpx_settings["headers"].setdefault("Authorization", f"Bearer {api_key}")
|
274
293
|
|
275
294
|
# Context management
|
295
|
+
self._context_stack: int = 0
|
276
296
|
self._exit_stack = AsyncExitStack()
|
277
297
|
self._ephemeral_app: Optional[ASGIApp] = None
|
278
298
|
self.manage_lifespan = True
|
@@ -453,7 +473,7 @@ class PrefectClient:
|
|
453
473
|
"""
|
454
474
|
flow_data = FlowCreate(name=flow_name)
|
455
475
|
response = await self._client.post(
|
456
|
-
"/flows/", json=flow_data.
|
476
|
+
"/flows/", json=flow_data.model_dump(mode="json")
|
457
477
|
)
|
458
478
|
|
459
479
|
flow_id = response.json().get("id")
|
@@ -474,7 +494,7 @@ class PrefectClient:
|
|
474
494
|
a [Flow model][prefect.client.schemas.objects.Flow] representation of the flow
|
475
495
|
"""
|
476
496
|
response = await self._client.get(f"/flows/{flow_id}")
|
477
|
-
return Flow.
|
497
|
+
return Flow.model_validate(response.json())
|
478
498
|
|
479
499
|
async def read_flows(
|
480
500
|
self,
|
@@ -508,29 +528,23 @@ class PrefectClient:
|
|
508
528
|
a list of Flow model representations of the flows
|
509
529
|
"""
|
510
530
|
body = {
|
511
|
-
"flows": flow_filter.
|
531
|
+
"flows": flow_filter.model_dump(mode="json") if flow_filter else None,
|
512
532
|
"flow_runs": (
|
513
|
-
flow_run_filter.
|
533
|
+
flow_run_filter.model_dump(mode="json", exclude_unset=True)
|
514
534
|
if flow_run_filter
|
515
535
|
else None
|
516
536
|
),
|
517
537
|
"task_runs": (
|
518
|
-
task_run_filter.
|
538
|
+
task_run_filter.model_dump(mode="json") if task_run_filter else None
|
519
539
|
),
|
520
540
|
"deployments": (
|
521
|
-
deployment_filter.
|
522
|
-
if deployment_filter
|
523
|
-
else None
|
541
|
+
deployment_filter.model_dump(mode="json") if deployment_filter else None
|
524
542
|
),
|
525
543
|
"work_pools": (
|
526
|
-
work_pool_filter.
|
527
|
-
if work_pool_filter
|
528
|
-
else None
|
544
|
+
work_pool_filter.model_dump(mode="json") if work_pool_filter else None
|
529
545
|
),
|
530
546
|
"work_queues": (
|
531
|
-
work_queue_filter.
|
532
|
-
if work_queue_filter
|
533
|
-
else None
|
547
|
+
work_queue_filter.model_dump(mode="json") if work_queue_filter else None
|
534
548
|
),
|
535
549
|
"sort": sort,
|
536
550
|
"limit": limit,
|
@@ -538,7 +552,7 @@ class PrefectClient:
|
|
538
552
|
}
|
539
553
|
|
540
554
|
response = await self._client.post("/flows/filter", json=body)
|
541
|
-
return pydantic.
|
555
|
+
return pydantic.TypeAdapter(List[Flow]).validate_python(response.json())
|
542
556
|
|
543
557
|
async def read_flow_by_name(
|
544
558
|
self,
|
@@ -554,7 +568,7 @@ class PrefectClient:
|
|
554
568
|
a fully hydrated Flow model
|
555
569
|
"""
|
556
570
|
response = await self._client.get(f"/flows/name/{flow_name}")
|
557
|
-
return Flow.
|
571
|
+
return Flow.model_validate(response.json())
|
558
572
|
|
559
573
|
async def create_flow_run_from_deployment(
|
560
574
|
self,
|
@@ -622,9 +636,9 @@ class PrefectClient:
|
|
622
636
|
|
623
637
|
response = await self._client.post(
|
624
638
|
f"/deployments/{deployment_id}/create_flow_run",
|
625
|
-
json=flow_run_create.
|
639
|
+
json=flow_run_create.model_dump(mode="json", exclude_unset=True),
|
626
640
|
)
|
627
|
-
return FlowRun.
|
641
|
+
return FlowRun.model_validate(response.json())
|
628
642
|
|
629
643
|
async def create_flow_run(
|
630
644
|
self,
|
@@ -680,9 +694,9 @@ class PrefectClient:
|
|
680
694
|
),
|
681
695
|
)
|
682
696
|
|
683
|
-
flow_run_create_json = flow_run_create.
|
697
|
+
flow_run_create_json = flow_run_create.model_dump(mode="json")
|
684
698
|
response = await self._client.post("/flow_runs/", json=flow_run_create_json)
|
685
|
-
flow_run = FlowRun.
|
699
|
+
flow_run = FlowRun.model_validate(response.json())
|
686
700
|
|
687
701
|
# Restore the parameters to the local objects to retain expectations about
|
688
702
|
# Python objects
|
@@ -740,7 +754,7 @@ class PrefectClient:
|
|
740
754
|
|
741
755
|
return await self._client.patch(
|
742
756
|
f"/flow_runs/{flow_run_id}",
|
743
|
-
json=flow_run_data.
|
757
|
+
json=flow_run_data.model_dump(mode="json", exclude_unset=True),
|
744
758
|
)
|
745
759
|
|
746
760
|
async def delete_flow_run(
|
@@ -790,7 +804,7 @@ class PrefectClient:
|
|
790
804
|
)
|
791
805
|
response = await self._client.post(
|
792
806
|
"/concurrency_limits/",
|
793
|
-
json=concurrency_limit_create.
|
807
|
+
json=concurrency_limit_create.model_dump(mode="json"),
|
794
808
|
)
|
795
809
|
|
796
810
|
concurrency_limit_id = response.json().get("id")
|
@@ -832,7 +846,7 @@ class PrefectClient:
|
|
832
846
|
if not concurrency_limit_id:
|
833
847
|
raise httpx.RequestError(f"Malformed response: {response}")
|
834
848
|
|
835
|
-
concurrency_limit = ConcurrencyLimit.
|
849
|
+
concurrency_limit = ConcurrencyLimit.model_validate(response.json())
|
836
850
|
return concurrency_limit
|
837
851
|
|
838
852
|
async def read_concurrency_limits(
|
@@ -857,7 +871,9 @@ class PrefectClient:
|
|
857
871
|
}
|
858
872
|
|
859
873
|
response = await self._client.post("/concurrency_limits/filter", json=body)
|
860
|
-
return pydantic.
|
874
|
+
return pydantic.TypeAdapter(List[ConcurrencyLimit]).validate_python(
|
875
|
+
response.json()
|
876
|
+
)
|
861
877
|
|
862
878
|
async def reset_concurrency_limit_by_tag(
|
863
879
|
self,
|
@@ -969,7 +985,7 @@ class PrefectClient:
|
|
969
985
|
if priority is not None:
|
970
986
|
create_model.priority = priority
|
971
987
|
|
972
|
-
data = create_model.
|
988
|
+
data = create_model.model_dump(mode="json")
|
973
989
|
try:
|
974
990
|
if work_pool_name is not None:
|
975
991
|
response = await self._client.post(
|
@@ -984,7 +1000,7 @@ class PrefectClient:
|
|
984
1000
|
raise prefect.exceptions.ObjectNotFound(http_exc=e) from e
|
985
1001
|
else:
|
986
1002
|
raise
|
987
|
-
return WorkQueue.
|
1003
|
+
return WorkQueue.model_validate(response.json())
|
988
1004
|
|
989
1005
|
async def read_work_queue_by_name(
|
990
1006
|
self,
|
@@ -1019,7 +1035,7 @@ class PrefectClient:
|
|
1019
1035
|
else:
|
1020
1036
|
raise
|
1021
1037
|
|
1022
|
-
return WorkQueue.
|
1038
|
+
return WorkQueue.model_validate(response.json())
|
1023
1039
|
|
1024
1040
|
async def update_work_queue(self, id: UUID, **kwargs):
|
1025
1041
|
"""
|
@@ -1038,7 +1054,7 @@ class PrefectClient:
|
|
1038
1054
|
if not kwargs:
|
1039
1055
|
raise ValueError("No fields provided to update.")
|
1040
1056
|
|
1041
|
-
data = WorkQueueUpdate(**kwargs).
|
1057
|
+
data = WorkQueueUpdate(**kwargs).model_dump(mode="json", exclude_unset=True)
|
1042
1058
|
try:
|
1043
1059
|
await self._client.patch(f"/work_queues/{id}", json=data)
|
1044
1060
|
except httpx.HTTPStatusError as e:
|
@@ -1085,7 +1101,7 @@ class PrefectClient:
|
|
1085
1101
|
raise prefect.exceptions.ObjectNotFound(http_exc=e) from e
|
1086
1102
|
else:
|
1087
1103
|
raise
|
1088
|
-
return pydantic.
|
1104
|
+
return pydantic.TypeAdapter(List[FlowRun]).validate_python(response.json())
|
1089
1105
|
|
1090
1106
|
async def read_work_queue(
|
1091
1107
|
self,
|
@@ -1111,7 +1127,7 @@ class PrefectClient:
|
|
1111
1127
|
raise prefect.exceptions.ObjectNotFound(http_exc=e) from e
|
1112
1128
|
else:
|
1113
1129
|
raise
|
1114
|
-
return WorkQueue.
|
1130
|
+
return WorkQueue.model_validate(response.json())
|
1115
1131
|
|
1116
1132
|
async def read_work_queue_status(
|
1117
1133
|
self,
|
@@ -1137,7 +1153,7 @@ class PrefectClient:
|
|
1137
1153
|
raise prefect.exceptions.ObjectNotFound(http_exc=e) from e
|
1138
1154
|
else:
|
1139
1155
|
raise
|
1140
|
-
return WorkQueueStatusDetail.
|
1156
|
+
return WorkQueueStatusDetail.model_validate(response.json())
|
1141
1157
|
|
1142
1158
|
async def match_work_queues(
|
1143
1159
|
self,
|
@@ -1206,8 +1222,8 @@ class PrefectClient:
|
|
1206
1222
|
try:
|
1207
1223
|
response = await self._client.post(
|
1208
1224
|
"/block_types/",
|
1209
|
-
json=block_type.
|
1210
|
-
|
1225
|
+
json=block_type.model_dump(
|
1226
|
+
mode="json", exclude_unset=True, exclude={"id"}
|
1211
1227
|
),
|
1212
1228
|
)
|
1213
1229
|
except httpx.HTTPStatusError as e:
|
@@ -1215,7 +1231,7 @@ class PrefectClient:
|
|
1215
1231
|
raise prefect.exceptions.ObjectAlreadyExists(http_exc=e) from e
|
1216
1232
|
else:
|
1217
1233
|
raise
|
1218
|
-
return BlockType.
|
1234
|
+
return BlockType.model_validate(response.json())
|
1219
1235
|
|
1220
1236
|
async def create_block_schema(self, block_schema: BlockSchemaCreate) -> BlockSchema:
|
1221
1237
|
"""
|
@@ -1224,8 +1240,8 @@ class PrefectClient:
|
|
1224
1240
|
try:
|
1225
1241
|
response = await self._client.post(
|
1226
1242
|
"/block_schemas/",
|
1227
|
-
json=block_schema.
|
1228
|
-
|
1243
|
+
json=block_schema.model_dump(
|
1244
|
+
mode="json",
|
1229
1245
|
exclude_unset=True,
|
1230
1246
|
exclude={"id", "block_type", "checksum"},
|
1231
1247
|
),
|
@@ -1235,7 +1251,7 @@ class PrefectClient:
|
|
1235
1251
|
raise prefect.exceptions.ObjectAlreadyExists(http_exc=e) from e
|
1236
1252
|
else:
|
1237
1253
|
raise
|
1238
|
-
return BlockSchema.
|
1254
|
+
return BlockSchema.model_validate(response.json())
|
1239
1255
|
|
1240
1256
|
async def create_block_document(
|
1241
1257
|
self,
|
@@ -1252,24 +1268,14 @@ class PrefectClient:
|
|
1252
1268
|
`SecretBytes` fields. Note Blocks may not work as expected if
|
1253
1269
|
this is set to `False`.
|
1254
1270
|
"""
|
1255
|
-
if isinstance(block_document, BlockDocument):
|
1256
|
-
block_document = BlockDocumentCreate.parse_obj(
|
1257
|
-
block_document.dict(
|
1258
|
-
json_compatible=True,
|
1259
|
-
include_secrets=include_secrets,
|
1260
|
-
exclude_unset=True,
|
1261
|
-
exclude={"id", "block_schema", "block_type"},
|
1262
|
-
),
|
1263
|
-
)
|
1264
|
-
|
1265
1271
|
try:
|
1266
1272
|
response = await self._client.post(
|
1267
1273
|
"/block_documents/",
|
1268
|
-
json=block_document.
|
1269
|
-
|
1270
|
-
include_secrets=include_secrets,
|
1274
|
+
json=block_document.model_dump(
|
1275
|
+
mode="json",
|
1271
1276
|
exclude_unset=True,
|
1272
1277
|
exclude={"id", "block_schema", "block_type"},
|
1278
|
+
context={"include_secrets": include_secrets},
|
1273
1279
|
),
|
1274
1280
|
)
|
1275
1281
|
except httpx.HTTPStatusError as e:
|
@@ -1277,7 +1283,7 @@ class PrefectClient:
|
|
1277
1283
|
raise prefect.exceptions.ObjectAlreadyExists(http_exc=e) from e
|
1278
1284
|
else:
|
1279
1285
|
raise
|
1280
|
-
return BlockDocument.
|
1286
|
+
return BlockDocument.model_validate(response.json())
|
1281
1287
|
|
1282
1288
|
async def update_block_document(
|
1283
1289
|
self,
|
@@ -1290,11 +1296,10 @@ class PrefectClient:
|
|
1290
1296
|
try:
|
1291
1297
|
await self._client.patch(
|
1292
1298
|
f"/block_documents/{block_document_id}",
|
1293
|
-
json=block_document.
|
1294
|
-
|
1299
|
+
json=block_document.model_dump(
|
1300
|
+
mode="json",
|
1295
1301
|
exclude_unset=True,
|
1296
1302
|
include={"data", "merge_existing_data", "block_schema_id"},
|
1297
|
-
include_secrets=True,
|
1298
1303
|
),
|
1299
1304
|
)
|
1300
1305
|
except httpx.HTTPStatusError as e:
|
@@ -1326,7 +1331,7 @@ class PrefectClient:
|
|
1326
1331
|
raise prefect.exceptions.ObjectNotFound(http_exc=e) from e
|
1327
1332
|
else:
|
1328
1333
|
raise
|
1329
|
-
return BlockType.
|
1334
|
+
return BlockType.model_validate(response.json())
|
1330
1335
|
|
1331
1336
|
async def read_block_schema_by_checksum(
|
1332
1337
|
self, checksum: str, version: Optional[str] = None
|
@@ -1344,7 +1349,7 @@ class PrefectClient:
|
|
1344
1349
|
raise prefect.exceptions.ObjectNotFound(http_exc=e) from e
|
1345
1350
|
else:
|
1346
1351
|
raise
|
1347
|
-
return BlockSchema.
|
1352
|
+
return BlockSchema.model_validate(response.json())
|
1348
1353
|
|
1349
1354
|
async def update_block_type(self, block_type_id: UUID, block_type: BlockTypeUpdate):
|
1350
1355
|
"""
|
@@ -1353,11 +1358,10 @@ class PrefectClient:
|
|
1353
1358
|
try:
|
1354
1359
|
await self._client.patch(
|
1355
1360
|
f"/block_types/{block_type_id}",
|
1356
|
-
json=block_type.
|
1357
|
-
|
1361
|
+
json=block_type.model_dump(
|
1362
|
+
mode="json",
|
1358
1363
|
exclude_unset=True,
|
1359
1364
|
include=BlockTypeUpdate.updatable_fields(),
|
1360
|
-
include_secrets=True,
|
1361
1365
|
),
|
1362
1366
|
)
|
1363
1367
|
except httpx.HTTPStatusError as e:
|
@@ -1396,7 +1400,7 @@ class PrefectClient:
|
|
1396
1400
|
List of BlockTypes.
|
1397
1401
|
"""
|
1398
1402
|
response = await self._client.post("/block_types/filter", json={})
|
1399
|
-
return pydantic.
|
1403
|
+
return pydantic.TypeAdapter(List[BlockType]).validate_python(response.json())
|
1400
1404
|
|
1401
1405
|
async def read_block_schemas(self) -> List[BlockSchema]:
|
1402
1406
|
"""
|
@@ -1408,7 +1412,7 @@ class PrefectClient:
|
|
1408
1412
|
A BlockSchema.
|
1409
1413
|
"""
|
1410
1414
|
response = await self._client.post("/block_schemas/filter", json={})
|
1411
|
-
return pydantic.
|
1415
|
+
return pydantic.TypeAdapter(List[BlockSchema]).validate_python(response.json())
|
1412
1416
|
|
1413
1417
|
async def get_most_recent_block_schema_for_block_type(
|
1414
1418
|
self,
|
@@ -1436,7 +1440,9 @@ class PrefectClient:
|
|
1436
1440
|
)
|
1437
1441
|
except httpx.HTTPStatusError:
|
1438
1442
|
raise
|
1439
|
-
return
|
1443
|
+
return (
|
1444
|
+
BlockSchema.model_validate(response.json()[0]) if response.json() else None
|
1445
|
+
)
|
1440
1446
|
|
1441
1447
|
async def read_block_document(
|
1442
1448
|
self,
|
@@ -1474,7 +1480,7 @@ class PrefectClient:
|
|
1474
1480
|
raise prefect.exceptions.ObjectNotFound(http_exc=e) from e
|
1475
1481
|
else:
|
1476
1482
|
raise
|
1477
|
-
return BlockDocument.
|
1483
|
+
return BlockDocument.model_validate(response.json())
|
1478
1484
|
|
1479
1485
|
async def read_block_document_by_name(
|
1480
1486
|
self,
|
@@ -1512,7 +1518,7 @@ class PrefectClient:
|
|
1512
1518
|
raise prefect.exceptions.ObjectNotFound(http_exc=e) from e
|
1513
1519
|
else:
|
1514
1520
|
raise
|
1515
|
-
return BlockDocument.
|
1521
|
+
return BlockDocument.model_validate(response.json())
|
1516
1522
|
|
1517
1523
|
async def read_block_documents(
|
1518
1524
|
self,
|
@@ -1547,7 +1553,9 @@ class PrefectClient:
|
|
1547
1553
|
include_secrets=include_secrets,
|
1548
1554
|
),
|
1549
1555
|
)
|
1550
|
-
return pydantic.
|
1556
|
+
return pydantic.TypeAdapter(List[BlockDocument]).validate_python(
|
1557
|
+
response.json()
|
1558
|
+
)
|
1551
1559
|
|
1552
1560
|
async def read_block_documents_by_type(
|
1553
1561
|
self,
|
@@ -1576,26 +1584,27 @@ class PrefectClient:
|
|
1576
1584
|
),
|
1577
1585
|
)
|
1578
1586
|
|
1579
|
-
return pydantic.
|
1587
|
+
return pydantic.TypeAdapter(List[BlockDocument]).validate_python(
|
1588
|
+
response.json()
|
1589
|
+
)
|
1580
1590
|
|
1581
1591
|
async def create_deployment(
|
1582
1592
|
self,
|
1583
1593
|
flow_id: UUID,
|
1584
1594
|
name: str,
|
1585
|
-
version: str = None,
|
1586
|
-
schedule: SCHEDULE_TYPES = None,
|
1587
|
-
schedules: List[DeploymentScheduleCreate] = None,
|
1595
|
+
version: Optional[str] = None,
|
1596
|
+
schedule: Optional[SCHEDULE_TYPES] = None,
|
1597
|
+
schedules: Optional[List[DeploymentScheduleCreate]] = None,
|
1588
1598
|
parameters: Optional[Dict[str, Any]] = None,
|
1589
|
-
description: str = None,
|
1590
|
-
work_queue_name: str = None,
|
1591
|
-
work_pool_name: str = None,
|
1592
|
-
tags: List[str] = None,
|
1593
|
-
storage_document_id: UUID = None,
|
1594
|
-
manifest_path: str = None,
|
1595
|
-
path: str = None,
|
1596
|
-
entrypoint: str = None,
|
1597
|
-
infrastructure_document_id: UUID = None,
|
1598
|
-
infra_overrides: Optional[Dict[str, Any]] = None, # for backwards compat
|
1599
|
+
description: Optional[str] = None,
|
1600
|
+
work_queue_name: Optional[str] = None,
|
1601
|
+
work_pool_name: Optional[str] = None,
|
1602
|
+
tags: Optional[List[str]] = None,
|
1603
|
+
storage_document_id: Optional[UUID] = None,
|
1604
|
+
manifest_path: Optional[str] = None,
|
1605
|
+
path: Optional[str] = None,
|
1606
|
+
entrypoint: Optional[str] = None,
|
1607
|
+
infrastructure_document_id: Optional[UUID] = None,
|
1599
1608
|
parameter_openapi_schema: Optional[Dict[str, Any]] = None,
|
1600
1609
|
is_schedule_active: Optional[bool] = None,
|
1601
1610
|
paused: Optional[bool] = None,
|
@@ -1627,8 +1636,9 @@ class PrefectClient:
|
|
1627
1636
|
Returns:
|
1628
1637
|
the ID of the deployment in the backend
|
1629
1638
|
"""
|
1630
|
-
jv = handle_deprecated_infra_overrides_parameter(job_variables, infra_overrides)
|
1631
1639
|
|
1640
|
+
if parameter_openapi_schema is None:
|
1641
|
+
parameter_openapi_schema = {}
|
1632
1642
|
deployment_create = DeploymentCreate(
|
1633
1643
|
flow_id=flow_id,
|
1634
1644
|
name=name,
|
@@ -1642,7 +1652,7 @@ class PrefectClient:
|
|
1642
1652
|
entrypoint=entrypoint,
|
1643
1653
|
manifest_path=manifest_path, # for backwards compat
|
1644
1654
|
infrastructure_document_id=infrastructure_document_id,
|
1645
|
-
job_variables=
|
1655
|
+
job_variables=dict(job_variables or {}),
|
1646
1656
|
parameter_openapi_schema=parameter_openapi_schema,
|
1647
1657
|
is_schedule_active=is_schedule_active,
|
1648
1658
|
paused=paused,
|
@@ -1659,7 +1669,7 @@ class PrefectClient:
|
|
1659
1669
|
exclude = {
|
1660
1670
|
field
|
1661
1671
|
for field in ["work_pool_name", "work_queue_name"]
|
1662
|
-
if field not in deployment_create.
|
1672
|
+
if field not in deployment_create.model_fields_set
|
1663
1673
|
}
|
1664
1674
|
|
1665
1675
|
if deployment_create.is_schedule_active is None:
|
@@ -1674,7 +1684,7 @@ class PrefectClient:
|
|
1674
1684
|
if deployment_create.enforce_parameter_schema is None:
|
1675
1685
|
exclude.add("enforce_parameter_schema")
|
1676
1686
|
|
1677
|
-
json = deployment_create.
|
1687
|
+
json = deployment_create.model_dump(mode="json", exclude=exclude)
|
1678
1688
|
response = await self._client.post(
|
1679
1689
|
"/deployments/",
|
1680
1690
|
json=json,
|
@@ -1732,7 +1742,7 @@ class PrefectClient:
|
|
1732
1742
|
|
1733
1743
|
await self._client.patch(
|
1734
1744
|
f"/deployments/{deployment.id}",
|
1735
|
-
json=deployment_update.
|
1745
|
+
json=deployment_update.model_dump(mode="json", exclude=exclude),
|
1736
1746
|
)
|
1737
1747
|
|
1738
1748
|
async def _create_deployment_from_schema(self, schema: DeploymentCreate) -> UUID:
|
@@ -1742,7 +1752,7 @@ class PrefectClient:
|
|
1742
1752
|
# TODO: We are likely to remove this method once we have considered the
|
1743
1753
|
# packaging interface for deployments further.
|
1744
1754
|
response = await self._client.post(
|
1745
|
-
"/deployments/", json=schema.
|
1755
|
+
"/deployments/", json=schema.model_dump(mode="json")
|
1746
1756
|
)
|
1747
1757
|
deployment_id = response.json().get("id")
|
1748
1758
|
if not deployment_id:
|
@@ -1770,7 +1780,7 @@ class PrefectClient:
|
|
1770
1780
|
raise prefect.exceptions.ObjectNotFound(http_exc=e) from e
|
1771
1781
|
else:
|
1772
1782
|
raise
|
1773
|
-
return DeploymentResponse.
|
1783
|
+
return DeploymentResponse.model_validate(response.json())
|
1774
1784
|
|
1775
1785
|
async def read_deployment_by_name(
|
1776
1786
|
self,
|
@@ -1797,19 +1807,19 @@ class PrefectClient:
|
|
1797
1807
|
else:
|
1798
1808
|
raise
|
1799
1809
|
|
1800
|
-
return DeploymentResponse.
|
1810
|
+
return DeploymentResponse.model_validate(response.json())
|
1801
1811
|
|
1802
1812
|
async def read_deployments(
|
1803
1813
|
self,
|
1804
1814
|
*,
|
1805
|
-
flow_filter: FlowFilter = None,
|
1806
|
-
flow_run_filter: FlowRunFilter = None,
|
1807
|
-
task_run_filter: TaskRunFilter = None,
|
1808
|
-
deployment_filter: DeploymentFilter = None,
|
1809
|
-
work_pool_filter: WorkPoolFilter = None,
|
1810
|
-
work_queue_filter: WorkQueueFilter = None,
|
1811
|
-
limit: int = None,
|
1812
|
-
sort: DeploymentSort = None,
|
1815
|
+
flow_filter: Optional[FlowFilter] = None,
|
1816
|
+
flow_run_filter: Optional[FlowRunFilter] = None,
|
1817
|
+
task_run_filter: Optional[TaskRunFilter] = None,
|
1818
|
+
deployment_filter: Optional[DeploymentFilter] = None,
|
1819
|
+
work_pool_filter: Optional[WorkPoolFilter] = None,
|
1820
|
+
work_queue_filter: Optional[WorkQueueFilter] = None,
|
1821
|
+
limit: Optional[int] = None,
|
1822
|
+
sort: Optional[DeploymentSort] = None,
|
1813
1823
|
offset: int = 0,
|
1814
1824
|
) -> List[DeploymentResponse]:
|
1815
1825
|
"""
|
@@ -1831,29 +1841,23 @@ class PrefectClient:
|
|
1831
1841
|
of the deployments
|
1832
1842
|
"""
|
1833
1843
|
body = {
|
1834
|
-
"flows": flow_filter.
|
1844
|
+
"flows": flow_filter.model_dump(mode="json") if flow_filter else None,
|
1835
1845
|
"flow_runs": (
|
1836
|
-
flow_run_filter.
|
1846
|
+
flow_run_filter.model_dump(mode="json", exclude_unset=True)
|
1837
1847
|
if flow_run_filter
|
1838
1848
|
else None
|
1839
1849
|
),
|
1840
1850
|
"task_runs": (
|
1841
|
-
task_run_filter.
|
1851
|
+
task_run_filter.model_dump(mode="json") if task_run_filter else None
|
1842
1852
|
),
|
1843
1853
|
"deployments": (
|
1844
|
-
deployment_filter.
|
1845
|
-
if deployment_filter
|
1846
|
-
else None
|
1854
|
+
deployment_filter.model_dump(mode="json") if deployment_filter else None
|
1847
1855
|
),
|
1848
1856
|
"work_pools": (
|
1849
|
-
work_pool_filter.
|
1850
|
-
if work_pool_filter
|
1851
|
-
else None
|
1857
|
+
work_pool_filter.model_dump(mode="json") if work_pool_filter else None
|
1852
1858
|
),
|
1853
1859
|
"work_pool_queues": (
|
1854
|
-
work_queue_filter.
|
1855
|
-
if work_queue_filter
|
1856
|
-
else None
|
1860
|
+
work_queue_filter.model_dump(mode="json") if work_queue_filter else None
|
1857
1861
|
),
|
1858
1862
|
"limit": limit,
|
1859
1863
|
"offset": offset,
|
@@ -1861,7 +1865,9 @@ class PrefectClient:
|
|
1861
1865
|
}
|
1862
1866
|
|
1863
1867
|
response = await self._client.post("/deployments/filter", json=body)
|
1864
|
-
return pydantic.
|
1868
|
+
return pydantic.TypeAdapter(List[DeploymentResponse]).validate_python(
|
1869
|
+
response.json()
|
1870
|
+
)
|
1865
1871
|
|
1866
1872
|
async def delete_deployment(
|
1867
1873
|
self,
|
@@ -1909,13 +1915,15 @@ class PrefectClient:
|
|
1909
1915
|
]
|
1910
1916
|
|
1911
1917
|
json = [
|
1912
|
-
deployment_schedule_create.
|
1918
|
+
deployment_schedule_create.model_dump(mode="json")
|
1913
1919
|
for deployment_schedule_create in deployment_schedule_create
|
1914
1920
|
]
|
1915
1921
|
response = await self._client.post(
|
1916
1922
|
f"/deployments/{deployment_id}/schedules", json=json
|
1917
1923
|
)
|
1918
|
-
return pydantic.
|
1924
|
+
return pydantic.TypeAdapter(List[DeploymentSchedule]).validate_python(
|
1925
|
+
response.json()
|
1926
|
+
)
|
1919
1927
|
|
1920
1928
|
async def read_deployment_schedules(
|
1921
1929
|
self,
|
@@ -1937,7 +1945,9 @@ class PrefectClient:
|
|
1937
1945
|
raise prefect.exceptions.ObjectNotFound(http_exc=e) from e
|
1938
1946
|
else:
|
1939
1947
|
raise
|
1940
|
-
return pydantic.
|
1948
|
+
return pydantic.TypeAdapter(List[DeploymentSchedule]).validate_python(
|
1949
|
+
response.json()
|
1950
|
+
)
|
1941
1951
|
|
1942
1952
|
async def update_deployment_schedule(
|
1943
1953
|
self,
|
@@ -1962,7 +1972,7 @@ class PrefectClient:
|
|
1962
1972
|
kwargs["schedule"] = schedule
|
1963
1973
|
|
1964
1974
|
deployment_schedule_update = DeploymentScheduleUpdate(**kwargs)
|
1965
|
-
json = deployment_schedule_update.
|
1975
|
+
json = deployment_schedule_update.model_dump(mode="json", exclude_unset=True)
|
1966
1976
|
|
1967
1977
|
try:
|
1968
1978
|
await self._client.patch(
|
@@ -2016,7 +2026,7 @@ class PrefectClient:
|
|
2016
2026
|
raise prefect.exceptions.ObjectNotFound(http_exc=e) from e
|
2017
2027
|
else:
|
2018
2028
|
raise
|
2019
|
-
return FlowRun.
|
2029
|
+
return FlowRun.model_validate(response.json())
|
2020
2030
|
|
2021
2031
|
async def resume_flow_run(
|
2022
2032
|
self, flow_run_id: UUID, run_input: Optional[Dict] = None
|
@@ -2038,7 +2048,7 @@ class PrefectClient:
|
|
2038
2048
|
except httpx.HTTPStatusError:
|
2039
2049
|
raise
|
2040
2050
|
|
2041
|
-
return OrchestrationResult.
|
2051
|
+
return OrchestrationResult.model_validate(response.json())
|
2042
2052
|
|
2043
2053
|
async def read_flow_runs(
|
2044
2054
|
self,
|
@@ -2073,29 +2083,23 @@ class PrefectClient:
|
|
2073
2083
|
of the flow runs
|
2074
2084
|
"""
|
2075
2085
|
body = {
|
2076
|
-
"flows": flow_filter.
|
2086
|
+
"flows": flow_filter.model_dump(mode="json") if flow_filter else None,
|
2077
2087
|
"flow_runs": (
|
2078
|
-
flow_run_filter.
|
2088
|
+
flow_run_filter.model_dump(mode="json", exclude_unset=True)
|
2079
2089
|
if flow_run_filter
|
2080
2090
|
else None
|
2081
2091
|
),
|
2082
2092
|
"task_runs": (
|
2083
|
-
task_run_filter.
|
2093
|
+
task_run_filter.model_dump(mode="json") if task_run_filter else None
|
2084
2094
|
),
|
2085
2095
|
"deployments": (
|
2086
|
-
deployment_filter.
|
2087
|
-
if deployment_filter
|
2088
|
-
else None
|
2096
|
+
deployment_filter.model_dump(mode="json") if deployment_filter else None
|
2089
2097
|
),
|
2090
2098
|
"work_pools": (
|
2091
|
-
work_pool_filter.
|
2092
|
-
if work_pool_filter
|
2093
|
-
else None
|
2099
|
+
work_pool_filter.model_dump(mode="json") if work_pool_filter else None
|
2094
2100
|
),
|
2095
2101
|
"work_pool_queues": (
|
2096
|
-
work_queue_filter.
|
2097
|
-
if work_queue_filter
|
2098
|
-
else None
|
2102
|
+
work_queue_filter.model_dump(mode="json") if work_queue_filter else None
|
2099
2103
|
),
|
2100
2104
|
"sort": sort,
|
2101
2105
|
"limit": limit,
|
@@ -2103,7 +2107,7 @@ class PrefectClient:
|
|
2103
2107
|
}
|
2104
2108
|
|
2105
2109
|
response = await self._client.post("/flow_runs/filter", json=body)
|
2106
|
-
return pydantic.
|
2110
|
+
return pydantic.TypeAdapter(List[FlowRun]).validate_python(response.json())
|
2107
2111
|
|
2108
2112
|
async def set_flow_run_state(
|
2109
2113
|
self,
|
@@ -2123,13 +2127,17 @@ class PrefectClient:
|
|
2123
2127
|
Returns:
|
2124
2128
|
an OrchestrationResult model representation of state orchestration output
|
2125
2129
|
"""
|
2130
|
+
flow_run_id = (
|
2131
|
+
flow_run_id if isinstance(flow_run_id, UUID) else UUID(flow_run_id)
|
2132
|
+
)
|
2126
2133
|
state_create = state.to_state_create()
|
2127
2134
|
state_create.state_details.flow_run_id = flow_run_id
|
2128
2135
|
state_create.state_details.transition_id = uuid4()
|
2136
|
+
print(repr(state_create))
|
2129
2137
|
try:
|
2130
2138
|
response = await self._client.post(
|
2131
2139
|
f"/flow_runs/{flow_run_id}/set_state",
|
2132
|
-
json=dict(state=state_create.
|
2140
|
+
json=dict(state=state_create.model_dump(mode="json"), force=force),
|
2133
2141
|
)
|
2134
2142
|
except httpx.HTTPStatusError as e:
|
2135
2143
|
if e.response.status_code == status.HTTP_404_NOT_FOUND:
|
@@ -2137,7 +2145,7 @@ class PrefectClient:
|
|
2137
2145
|
else:
|
2138
2146
|
raise
|
2139
2147
|
|
2140
|
-
return OrchestrationResult.
|
2148
|
+
return OrchestrationResult.model_validate(response.json())
|
2141
2149
|
|
2142
2150
|
async def read_flow_run_states(
|
2143
2151
|
self, flow_run_id: UUID
|
@@ -2155,13 +2163,15 @@ class PrefectClient:
|
|
2155
2163
|
response = await self._client.get(
|
2156
2164
|
"/flow_run_states/", params=dict(flow_run_id=str(flow_run_id))
|
2157
2165
|
)
|
2158
|
-
return pydantic.
|
2166
|
+
return pydantic.TypeAdapter(List[prefect.states.State]).validate_python(
|
2167
|
+
response.json()
|
2168
|
+
)
|
2159
2169
|
|
2160
2170
|
async def set_task_run_name(self, task_run_id: UUID, name: str):
|
2161
2171
|
task_run_data = TaskRunUpdate(name=name)
|
2162
2172
|
return await self._client.patch(
|
2163
2173
|
f"/task_runs/{task_run_id}",
|
2164
|
-
json=task_run_data.
|
2174
|
+
json=task_run_data.model_dump(mode="json", exclude_unset=True),
|
2165
2175
|
)
|
2166
2176
|
|
2167
2177
|
async def create_task_run(
|
@@ -2169,6 +2179,7 @@ class PrefectClient:
|
|
2169
2179
|
task: "TaskObject[P, R]",
|
2170
2180
|
flow_run_id: Optional[UUID],
|
2171
2181
|
dynamic_key: str,
|
2182
|
+
id: Optional[UUID] = None,
|
2172
2183
|
name: Optional[str] = None,
|
2173
2184
|
extra_tags: Optional[Iterable[str]] = None,
|
2174
2185
|
state: Optional[prefect.states.State[R]] = None,
|
@@ -2192,6 +2203,8 @@ class PrefectClient:
|
|
2192
2203
|
task: The Task to run
|
2193
2204
|
flow_run_id: The flow run id with which to associate the task run
|
2194
2205
|
dynamic_key: A key unique to this particular run of a Task within the flow
|
2206
|
+
id: An optional ID for the task run. If not provided, one will be generated
|
2207
|
+
server-side.
|
2195
2208
|
name: An optional name for the task run
|
2196
2209
|
extra_tags: an optional list of extra tags to apply to the task run in
|
2197
2210
|
addition to `task.tags`
|
@@ -2208,10 +2221,11 @@ class PrefectClient:
|
|
2208
2221
|
state = prefect.states.Pending()
|
2209
2222
|
|
2210
2223
|
task_run_data = TaskRunCreate(
|
2224
|
+
id=id,
|
2211
2225
|
name=name,
|
2212
2226
|
flow_run_id=flow_run_id,
|
2213
2227
|
task_key=task.task_key,
|
2214
|
-
dynamic_key=dynamic_key,
|
2228
|
+
dynamic_key=str(dynamic_key),
|
2215
2229
|
tags=list(tags),
|
2216
2230
|
task_version=task.version,
|
2217
2231
|
empirical_policy=TaskRunPolicy(
|
@@ -2222,11 +2236,10 @@ class PrefectClient:
|
|
2222
2236
|
state=state.to_state_create(),
|
2223
2237
|
task_inputs=task_inputs or {},
|
2224
2238
|
)
|
2239
|
+
content = task_run_data.model_dump_json(exclude={"id"} if id is None else None)
|
2225
2240
|
|
2226
|
-
response = await self._client.post(
|
2227
|
-
|
2228
|
-
)
|
2229
|
-
return TaskRun.parse_obj(response.json())
|
2241
|
+
response = await self._client.post("/task_runs/", content=content)
|
2242
|
+
return TaskRun.model_validate(response.json())
|
2230
2243
|
|
2231
2244
|
async def read_task_run(self, task_run_id: UUID) -> TaskRun:
|
2232
2245
|
"""
|
@@ -2238,8 +2251,14 @@ class PrefectClient:
|
|
2238
2251
|
Returns:
|
2239
2252
|
a Task Run model representation of the task run
|
2240
2253
|
"""
|
2241
|
-
|
2242
|
-
|
2254
|
+
try:
|
2255
|
+
response = await self._client.get(f"/task_runs/{task_run_id}")
|
2256
|
+
return TaskRun.model_validate(response.json())
|
2257
|
+
except httpx.HTTPStatusError as e:
|
2258
|
+
if e.response.status_code == status.HTTP_404_NOT_FOUND:
|
2259
|
+
raise prefect.exceptions.ObjectNotFound(http_exc=e) from e
|
2260
|
+
else:
|
2261
|
+
raise
|
2243
2262
|
|
2244
2263
|
async def read_task_runs(
|
2245
2264
|
self,
|
@@ -2270,26 +2289,24 @@ class PrefectClient:
|
|
2270
2289
|
of the task runs
|
2271
2290
|
"""
|
2272
2291
|
body = {
|
2273
|
-
"flows": flow_filter.
|
2292
|
+
"flows": flow_filter.model_dump(mode="json") if flow_filter else None,
|
2274
2293
|
"flow_runs": (
|
2275
|
-
flow_run_filter.
|
2294
|
+
flow_run_filter.model_dump(mode="json", exclude_unset=True)
|
2276
2295
|
if flow_run_filter
|
2277
2296
|
else None
|
2278
2297
|
),
|
2279
2298
|
"task_runs": (
|
2280
|
-
task_run_filter.
|
2299
|
+
task_run_filter.model_dump(mode="json") if task_run_filter else None
|
2281
2300
|
),
|
2282
2301
|
"deployments": (
|
2283
|
-
deployment_filter.
|
2284
|
-
if deployment_filter
|
2285
|
-
else None
|
2302
|
+
deployment_filter.model_dump(mode="json") if deployment_filter else None
|
2286
2303
|
),
|
2287
2304
|
"sort": sort,
|
2288
2305
|
"limit": limit,
|
2289
2306
|
"offset": offset,
|
2290
2307
|
}
|
2291
2308
|
response = await self._client.post("/task_runs/filter", json=body)
|
2292
|
-
return pydantic.
|
2309
|
+
return pydantic.TypeAdapter(List[TaskRun]).validate_python(response.json())
|
2293
2310
|
|
2294
2311
|
async def delete_task_run(self, task_run_id: UUID) -> None:
|
2295
2312
|
"""
|
@@ -2331,9 +2348,9 @@ class PrefectClient:
|
|
2331
2348
|
state_create.state_details.task_run_id = task_run_id
|
2332
2349
|
response = await self._client.post(
|
2333
2350
|
f"/task_runs/{task_run_id}/set_state",
|
2334
|
-
json=dict(state=state_create.
|
2351
|
+
json=dict(state=state_create.model_dump(mode="json"), force=force),
|
2335
2352
|
)
|
2336
|
-
return OrchestrationResult.
|
2353
|
+
return OrchestrationResult.model_validate(response.json())
|
2337
2354
|
|
2338
2355
|
async def read_task_run_states(
|
2339
2356
|
self, task_run_id: UUID
|
@@ -2350,7 +2367,9 @@ class PrefectClient:
|
|
2350
2367
|
response = await self._client.get(
|
2351
2368
|
"/task_run_states/", params=dict(task_run_id=str(task_run_id))
|
2352
2369
|
)
|
2353
|
-
return pydantic.
|
2370
|
+
return pydantic.TypeAdapter(List[prefect.states.State]).validate_python(
|
2371
|
+
response.json()
|
2372
|
+
)
|
2354
2373
|
|
2355
2374
|
async def create_logs(self, logs: Iterable[Union[LogCreate, dict]]) -> None:
|
2356
2375
|
"""
|
@@ -2360,7 +2379,7 @@ class PrefectClient:
|
|
2360
2379
|
logs: An iterable of `LogCreate` objects or already json-compatible dicts
|
2361
2380
|
"""
|
2362
2381
|
serialized_logs = [
|
2363
|
-
log.
|
2382
|
+
log.model_dump(mode="json") if isinstance(log, LogCreate) else log
|
2364
2383
|
for log in logs
|
2365
2384
|
]
|
2366
2385
|
await self._client.post("/logs/", json=serialized_logs)
|
@@ -2397,7 +2416,7 @@ class PrefectClient:
|
|
2397
2416
|
)
|
2398
2417
|
response = await self._client.post(
|
2399
2418
|
"/flow_run_notification_policies/",
|
2400
|
-
json=policy.
|
2419
|
+
json=policy.model_dump(mode="json"),
|
2401
2420
|
)
|
2402
2421
|
|
2403
2422
|
policy_id = response.json().get("id")
|
@@ -2467,7 +2486,7 @@ class PrefectClient:
|
|
2467
2486
|
try:
|
2468
2487
|
await self._client.patch(
|
2469
2488
|
f"/flow_run_notification_policies/{id}",
|
2470
|
-
json=policy.
|
2489
|
+
json=policy.model_dump(mode="json", exclude_unset=True),
|
2471
2490
|
)
|
2472
2491
|
except httpx.HTTPStatusError as e:
|
2473
2492
|
if e.response.status_code == status.HTTP_404_NOT_FOUND:
|
@@ -2496,7 +2515,7 @@ class PrefectClient:
|
|
2496
2515
|
"""
|
2497
2516
|
body = {
|
2498
2517
|
"flow_run_notification_policy_filter": (
|
2499
|
-
flow_run_notification_policy_filter.
|
2518
|
+
flow_run_notification_policy_filter.model_dump(mode="json")
|
2500
2519
|
if flow_run_notification_policy_filter
|
2501
2520
|
else None
|
2502
2521
|
),
|
@@ -2506,7 +2525,9 @@ class PrefectClient:
|
|
2506
2525
|
response = await self._client.post(
|
2507
2526
|
"/flow_run_notification_policies/filter", json=body
|
2508
2527
|
)
|
2509
|
-
return pydantic.
|
2528
|
+
return pydantic.TypeAdapter(List[FlowRunNotificationPolicy]).validate_python(
|
2529
|
+
response.json()
|
2530
|
+
)
|
2510
2531
|
|
2511
2532
|
async def read_logs(
|
2512
2533
|
self,
|
@@ -2519,45 +2540,14 @@ class PrefectClient:
|
|
2519
2540
|
Read flow and task run logs.
|
2520
2541
|
"""
|
2521
2542
|
body = {
|
2522
|
-
"logs": log_filter.
|
2543
|
+
"logs": log_filter.model_dump(mode="json") if log_filter else None,
|
2523
2544
|
"limit": limit,
|
2524
2545
|
"offset": offset,
|
2525
2546
|
"sort": sort,
|
2526
2547
|
}
|
2527
2548
|
|
2528
2549
|
response = await self._client.post("/logs/filter", json=body)
|
2529
|
-
return pydantic.
|
2530
|
-
|
2531
|
-
async def resolve_datadoc(self, datadoc: DataDocument) -> Any:
|
2532
|
-
"""
|
2533
|
-
Recursively decode possibly nested data documents.
|
2534
|
-
|
2535
|
-
"server" encoded documents will be retrieved from the server.
|
2536
|
-
|
2537
|
-
Args:
|
2538
|
-
datadoc: The data document to resolve
|
2539
|
-
|
2540
|
-
Returns:
|
2541
|
-
a decoded object, the innermost data
|
2542
|
-
"""
|
2543
|
-
if not isinstance(datadoc, DataDocument):
|
2544
|
-
raise TypeError(
|
2545
|
-
f"`resolve_datadoc` received invalid type {type(datadoc).__name__}"
|
2546
|
-
)
|
2547
|
-
|
2548
|
-
async def resolve_inner(data):
|
2549
|
-
if isinstance(data, bytes):
|
2550
|
-
try:
|
2551
|
-
data = DataDocument.parse_raw(data)
|
2552
|
-
except pydantic.ValidationError:
|
2553
|
-
return data
|
2554
|
-
|
2555
|
-
if isinstance(data, DataDocument):
|
2556
|
-
return await resolve_inner(data.decode())
|
2557
|
-
|
2558
|
-
return data
|
2559
|
-
|
2560
|
-
return await resolve_inner(datadoc)
|
2550
|
+
return pydantic.TypeAdapter(List[Log]).validate_python(response.json())
|
2561
2551
|
|
2562
2552
|
async def send_worker_heartbeat(
|
2563
2553
|
self,
|
@@ -2601,7 +2591,7 @@ class PrefectClient:
|
|
2601
2591
|
f"/work_pools/{work_pool_name}/workers/filter",
|
2602
2592
|
json={
|
2603
2593
|
"worker_filter": (
|
2604
|
-
worker_filter.
|
2594
|
+
worker_filter.model_dump(mode="json", exclude_unset=True)
|
2605
2595
|
if worker_filter
|
2606
2596
|
else None
|
2607
2597
|
),
|
@@ -2610,7 +2600,7 @@ class PrefectClient:
|
|
2610
2600
|
},
|
2611
2601
|
)
|
2612
2602
|
|
2613
|
-
return pydantic.
|
2603
|
+
return pydantic.TypeAdapter(List[Worker]).validate_python(response.json())
|
2614
2604
|
|
2615
2605
|
async def read_work_pool(self, work_pool_name: str) -> WorkPool:
|
2616
2606
|
"""
|
@@ -2625,7 +2615,7 @@ class PrefectClient:
|
|
2625
2615
|
"""
|
2626
2616
|
try:
|
2627
2617
|
response = await self._client.get(f"/work_pools/{work_pool_name}")
|
2628
|
-
return
|
2618
|
+
return WorkPool.model_validate(response.json())
|
2629
2619
|
except httpx.HTTPStatusError as e:
|
2630
2620
|
if e.response.status_code == status.HTTP_404_NOT_FOUND:
|
2631
2621
|
raise prefect.exceptions.ObjectNotFound(http_exc=e) from e
|
@@ -2654,13 +2644,11 @@ class PrefectClient:
|
|
2654
2644
|
"limit": limit,
|
2655
2645
|
"offset": offset,
|
2656
2646
|
"work_pools": (
|
2657
|
-
work_pool_filter.
|
2658
|
-
if work_pool_filter
|
2659
|
-
else None
|
2647
|
+
work_pool_filter.model_dump(mode="json") if work_pool_filter else None
|
2660
2648
|
),
|
2661
2649
|
}
|
2662
2650
|
response = await self._client.post("/work_pools/filter", json=body)
|
2663
|
-
return pydantic.
|
2651
|
+
return pydantic.TypeAdapter(List[WorkPool]).validate_python(response.json())
|
2664
2652
|
|
2665
2653
|
async def create_work_pool(
|
2666
2654
|
self,
|
@@ -2678,7 +2666,7 @@ class PrefectClient:
|
|
2678
2666
|
try:
|
2679
2667
|
response = await self._client.post(
|
2680
2668
|
"/work_pools/",
|
2681
|
-
json=work_pool.
|
2669
|
+
json=work_pool.model_dump(mode="json", exclude_unset=True),
|
2682
2670
|
)
|
2683
2671
|
except httpx.HTTPStatusError as e:
|
2684
2672
|
if e.response.status_code == status.HTTP_409_CONFLICT:
|
@@ -2686,7 +2674,7 @@ class PrefectClient:
|
|
2686
2674
|
else:
|
2687
2675
|
raise
|
2688
2676
|
|
2689
|
-
return
|
2677
|
+
return WorkPool.model_validate(response.json())
|
2690
2678
|
|
2691
2679
|
async def update_work_pool(
|
2692
2680
|
self,
|
@@ -2703,7 +2691,7 @@ class PrefectClient:
|
|
2703
2691
|
try:
|
2704
2692
|
await self._client.patch(
|
2705
2693
|
f"/work_pools/{work_pool_name}",
|
2706
|
-
json=work_pool.
|
2694
|
+
json=work_pool.model_dump(mode="json", exclude_unset=True),
|
2707
2695
|
)
|
2708
2696
|
except httpx.HTTPStatusError as e:
|
2709
2697
|
if e.response.status_code == status.HTTP_404_NOT_FOUND:
|
@@ -2750,7 +2738,7 @@ class PrefectClient:
|
|
2750
2738
|
"""
|
2751
2739
|
json = {
|
2752
2740
|
"work_queues": (
|
2753
|
-
work_queue_filter.
|
2741
|
+
work_queue_filter.model_dump(mode="json", exclude_unset=True)
|
2754
2742
|
if work_queue_filter
|
2755
2743
|
else None
|
2756
2744
|
),
|
@@ -2772,14 +2760,14 @@ class PrefectClient:
|
|
2772
2760
|
else:
|
2773
2761
|
response = await self._client.post("/work_queues/filter", json=json)
|
2774
2762
|
|
2775
|
-
return pydantic.
|
2763
|
+
return pydantic.TypeAdapter(List[WorkQueue]).validate_python(response.json())
|
2776
2764
|
|
2777
2765
|
async def get_scheduled_flow_runs_for_deployments(
|
2778
2766
|
self,
|
2779
2767
|
deployment_ids: List[UUID],
|
2780
2768
|
scheduled_before: Optional[datetime.datetime] = None,
|
2781
2769
|
limit: Optional[int] = None,
|
2782
|
-
):
|
2770
|
+
) -> List[FlowRunResponse]:
|
2783
2771
|
body: Dict[str, Any] = dict(deployment_ids=[str(id) for id in deployment_ids])
|
2784
2772
|
if scheduled_before:
|
2785
2773
|
body["scheduled_before"] = str(scheduled_before)
|
@@ -2791,7 +2779,9 @@ class PrefectClient:
|
|
2791
2779
|
json=body,
|
2792
2780
|
)
|
2793
2781
|
|
2794
|
-
return pydantic.
|
2782
|
+
return pydantic.TypeAdapter(List[FlowRunResponse]).validate_python(
|
2783
|
+
response.json()
|
2784
|
+
)
|
2795
2785
|
|
2796
2786
|
async def get_scheduled_flow_runs_for_work_pool(
|
2797
2787
|
self,
|
@@ -2824,7 +2814,9 @@ class PrefectClient:
|
|
2824
2814
|
f"/work_pools/{work_pool_name}/get_scheduled_flow_runs",
|
2825
2815
|
json=body,
|
2826
2816
|
)
|
2827
|
-
return pydantic.
|
2817
|
+
return pydantic.TypeAdapter(List[WorkerFlowRunResponse]).validate_python(
|
2818
|
+
response.json()
|
2819
|
+
)
|
2828
2820
|
|
2829
2821
|
async def create_artifact(
|
2830
2822
|
self,
|
@@ -2841,10 +2833,29 @@ class PrefectClient:
|
|
2841
2833
|
|
2842
2834
|
response = await self._client.post(
|
2843
2835
|
"/artifacts/",
|
2844
|
-
json=artifact.
|
2836
|
+
json=artifact.model_dump(mode="json", exclude_unset=True),
|
2845
2837
|
)
|
2846
2838
|
|
2847
|
-
return
|
2839
|
+
return Artifact.model_validate(response.json())
|
2840
|
+
|
2841
|
+
async def update_artifact(
|
2842
|
+
self,
|
2843
|
+
artifact_id: UUID,
|
2844
|
+
artifact: ArtifactUpdate,
|
2845
|
+
) -> None:
|
2846
|
+
"""
|
2847
|
+
Updates an artifact
|
2848
|
+
|
2849
|
+
Args:
|
2850
|
+
artifact: Desired values for the updated artifact.
|
2851
|
+
Returns:
|
2852
|
+
Information about the updated artifact.
|
2853
|
+
"""
|
2854
|
+
|
2855
|
+
await self._client.patch(
|
2856
|
+
f"/artifacts/{artifact_id}",
|
2857
|
+
json=artifact.model_dump(mode="json", exclude_unset=True),
|
2858
|
+
)
|
2848
2859
|
|
2849
2860
|
async def read_artifacts(
|
2850
2861
|
self,
|
@@ -2871,20 +2882,20 @@ class PrefectClient:
|
|
2871
2882
|
"""
|
2872
2883
|
body = {
|
2873
2884
|
"artifacts": (
|
2874
|
-
artifact_filter.
|
2885
|
+
artifact_filter.model_dump(mode="json") if artifact_filter else None
|
2875
2886
|
),
|
2876
2887
|
"flow_runs": (
|
2877
|
-
flow_run_filter.
|
2888
|
+
flow_run_filter.model_dump(mode="json") if flow_run_filter else None
|
2878
2889
|
),
|
2879
2890
|
"task_runs": (
|
2880
|
-
task_run_filter.
|
2891
|
+
task_run_filter.model_dump(mode="json") if task_run_filter else None
|
2881
2892
|
),
|
2882
2893
|
"sort": sort,
|
2883
2894
|
"limit": limit,
|
2884
2895
|
"offset": offset,
|
2885
2896
|
}
|
2886
2897
|
response = await self._client.post("/artifacts/filter", json=body)
|
2887
|
-
return pydantic.
|
2898
|
+
return pydantic.TypeAdapter(List[Artifact]).validate_python(response.json())
|
2888
2899
|
|
2889
2900
|
async def read_latest_artifacts(
|
2890
2901
|
self,
|
@@ -2911,20 +2922,22 @@ class PrefectClient:
|
|
2911
2922
|
"""
|
2912
2923
|
body = {
|
2913
2924
|
"artifacts": (
|
2914
|
-
artifact_filter.
|
2925
|
+
artifact_filter.model_dump(mode="json") if artifact_filter else None
|
2915
2926
|
),
|
2916
2927
|
"flow_runs": (
|
2917
|
-
flow_run_filter.
|
2928
|
+
flow_run_filter.model_dump(mode="json") if flow_run_filter else None
|
2918
2929
|
),
|
2919
2930
|
"task_runs": (
|
2920
|
-
task_run_filter.
|
2931
|
+
task_run_filter.model_dump(mode="json") if task_run_filter else None
|
2921
2932
|
),
|
2922
2933
|
"sort": sort,
|
2923
2934
|
"limit": limit,
|
2924
2935
|
"offset": offset,
|
2925
2936
|
}
|
2926
2937
|
response = await self._client.post("/artifacts/latest/filter", json=body)
|
2927
|
-
return pydantic.
|
2938
|
+
return pydantic.TypeAdapter(List[ArtifactCollection]).validate_python(
|
2939
|
+
response.json()
|
2940
|
+
)
|
2928
2941
|
|
2929
2942
|
async def delete_artifact(self, artifact_id: UUID) -> None:
|
2930
2943
|
"""
|
@@ -2952,7 +2965,7 @@ class PrefectClient:
|
|
2952
2965
|
"""
|
2953
2966
|
response = await self._client.post(
|
2954
2967
|
"/variables/",
|
2955
|
-
json=variable.
|
2968
|
+
json=variable.model_dump(mode="json", exclude_unset=True),
|
2956
2969
|
)
|
2957
2970
|
return Variable(**response.json())
|
2958
2971
|
|
@@ -2967,7 +2980,7 @@ class PrefectClient:
|
|
2967
2980
|
"""
|
2968
2981
|
await self._client.patch(
|
2969
2982
|
f"/variables/name/{variable.name}",
|
2970
|
-
json=variable.
|
2983
|
+
json=variable.model_dump(mode="json", exclude_unset=True),
|
2971
2984
|
)
|
2972
2985
|
|
2973
2986
|
async def read_variable_by_name(self, name: str) -> Optional[Variable]:
|
@@ -2994,7 +3007,7 @@ class PrefectClient:
|
|
2994
3007
|
async def read_variables(self, limit: int = None) -> List[Variable]:
|
2995
3008
|
"""Reads all variables."""
|
2996
3009
|
response = await self._client.post("/variables/filter", json={"limit": limit})
|
2997
|
-
return pydantic.
|
3010
|
+
return pydantic.TypeAdapter(List[Variable]).validate_python(response.json())
|
2998
3011
|
|
2999
3012
|
async def read_worker_metadata(self) -> Dict[str, Any]:
|
3000
3013
|
"""Reads worker metadata stored in Prefect collection registry."""
|
@@ -3027,7 +3040,7 @@ class PrefectClient:
|
|
3027
3040
|
) -> UUID:
|
3028
3041
|
response = await self._client.post(
|
3029
3042
|
"/v2/concurrency_limits/",
|
3030
|
-
json=concurrency_limit.
|
3043
|
+
json=concurrency_limit.model_dump(mode="json", exclude_unset=True),
|
3031
3044
|
)
|
3032
3045
|
return UUID(response.json()["id"])
|
3033
3046
|
|
@@ -3037,7 +3050,7 @@ class PrefectClient:
|
|
3037
3050
|
try:
|
3038
3051
|
response = await self._client.patch(
|
3039
3052
|
f"/v2/concurrency_limits/{name}",
|
3040
|
-
json=concurrency_limit.
|
3053
|
+
json=concurrency_limit.model_dump(mode="json", exclude_unset=True),
|
3041
3054
|
)
|
3042
3055
|
return response
|
3043
3056
|
except httpx.HTTPStatusError as e:
|
@@ -3063,7 +3076,7 @@ class PrefectClient:
|
|
3063
3076
|
) -> GlobalConcurrencyLimitResponse:
|
3064
3077
|
try:
|
3065
3078
|
response = await self._client.get(f"/v2/concurrency_limits/{name}")
|
3066
|
-
return GlobalConcurrencyLimitResponse.
|
3079
|
+
return GlobalConcurrencyLimitResponse.model_validate(response.json())
|
3067
3080
|
except httpx.HTTPStatusError as e:
|
3068
3081
|
if e.response.status_code == status.HTTP_404_NOT_FOUND:
|
3069
3082
|
raise prefect.exceptions.ObjectNotFound(http_exc=e) from e
|
@@ -3080,9 +3093,9 @@ class PrefectClient:
|
|
3080
3093
|
"offset": offset,
|
3081
3094
|
},
|
3082
3095
|
)
|
3083
|
-
return pydantic.
|
3084
|
-
List[GlobalConcurrencyLimitResponse]
|
3085
|
-
)
|
3096
|
+
return pydantic.TypeAdapter(
|
3097
|
+
List[GlobalConcurrencyLimitResponse]
|
3098
|
+
).validate_python(response.json())
|
3086
3099
|
|
3087
3100
|
async def create_flow_run_input(
|
3088
3101
|
self, flow_run_id: UUID, key: str, value: str, sender: Optional[str] = None
|
@@ -3118,7 +3131,7 @@ class PrefectClient:
|
|
3118
3131
|
},
|
3119
3132
|
)
|
3120
3133
|
response.raise_for_status()
|
3121
|
-
return pydantic.
|
3134
|
+
return pydantic.TypeAdapter(List[FlowRunInput]).validate_python(response.json())
|
3122
3135
|
|
3123
3136
|
async def read_flow_run_input(self, flow_run_id: UUID, key: str) -> str:
|
3124
3137
|
"""
|
@@ -3143,49 +3156,27 @@ class PrefectClient:
|
|
3143
3156
|
response = await self._client.delete(f"/flow_runs/{flow_run_id}/input/{key}")
|
3144
3157
|
response.raise_for_status()
|
3145
3158
|
|
3146
|
-
def _raise_for_unsupported_automations(self) -> NoReturn:
|
3147
|
-
if not PREFECT_EXPERIMENTAL_EVENTS:
|
3148
|
-
raise RuntimeError(
|
3149
|
-
"The current server and client configuration does not support "
|
3150
|
-
"events. Enable experimental events support with the "
|
3151
|
-
"PREFECT_EXPERIMENTAL_EVENTS setting."
|
3152
|
-
)
|
3153
|
-
else:
|
3154
|
-
raise RuntimeError(
|
3155
|
-
"The current server and client configuration does not support "
|
3156
|
-
"automations. Enable experimental automations with the "
|
3157
|
-
"PREFECT_API_SERVICES_TRIGGERS_ENABLED setting."
|
3158
|
-
)
|
3159
|
-
|
3160
3159
|
async def create_automation(self, automation: AutomationCore) -> UUID:
|
3161
3160
|
"""Creates an automation in Prefect Cloud."""
|
3162
|
-
if not self.server_type.supports_automations():
|
3163
|
-
self._raise_for_unsupported_automations()
|
3164
|
-
|
3165
3161
|
response = await self._client.post(
|
3166
3162
|
"/automations/",
|
3167
|
-
json=automation.
|
3163
|
+
json=automation.model_dump(mode="json"),
|
3168
3164
|
)
|
3169
3165
|
|
3170
3166
|
return UUID(response.json()["id"])
|
3171
3167
|
|
3172
3168
|
async def update_automation(self, automation_id: UUID, automation: AutomationCore):
|
3173
3169
|
"""Updates an automation in Prefect Cloud."""
|
3174
|
-
if not self.server_type.supports_automations():
|
3175
|
-
self._raise_for_unsupported_automations()
|
3176
3170
|
response = await self._client.put(
|
3177
3171
|
f"/automations/{automation_id}",
|
3178
|
-
json=automation.
|
3172
|
+
json=automation.model_dump(mode="json", exclude_unset=True),
|
3179
3173
|
)
|
3180
3174
|
response.raise_for_status
|
3181
3175
|
|
3182
3176
|
async def read_automations(self) -> List[Automation]:
|
3183
|
-
if not self.server_type.supports_automations():
|
3184
|
-
self._raise_for_unsupported_automations()
|
3185
|
-
|
3186
3177
|
response = await self._client.post("/automations/filter")
|
3187
3178
|
response.raise_for_status()
|
3188
|
-
return pydantic.
|
3179
|
+
return pydantic.TypeAdapter(List[Automation]).validate_python(response.json())
|
3189
3180
|
|
3190
3181
|
async def find_automation(
|
3191
3182
|
self, id_or_name: Union[str, UUID], exit_if_not_found: bool = True
|
@@ -3221,14 +3212,11 @@ class PrefectClient:
|
|
3221
3212
|
return None
|
3222
3213
|
|
3223
3214
|
async def read_automation(self, automation_id: UUID) -> Optional[Automation]:
|
3224
|
-
if not self.server_type.supports_automations():
|
3225
|
-
self._raise_for_unsupported_automations()
|
3226
|
-
|
3227
3215
|
response = await self._client.get(f"/automations/{automation_id}")
|
3228
3216
|
if response.status_code == 404:
|
3229
3217
|
return None
|
3230
3218
|
response.raise_for_status()
|
3231
|
-
return Automation.
|
3219
|
+
return Automation.model_validate(response.json())
|
3232
3220
|
|
3233
3221
|
async def read_automations_by_name(self, name: str) -> List[Automation]:
|
3234
3222
|
"""
|
@@ -3240,15 +3228,13 @@ class PrefectClient:
|
|
3240
3228
|
Returns:
|
3241
3229
|
a list of Automation model representations of the automations
|
3242
3230
|
"""
|
3243
|
-
if not self.server_type.supports_automations():
|
3244
|
-
self._raise_for_unsupported_automations()
|
3245
3231
|
automation_filter = filters.AutomationFilter(name=dict(any_=[name]))
|
3246
3232
|
|
3247
3233
|
response = await self._client.post(
|
3248
3234
|
"/automations/filter",
|
3249
3235
|
json={
|
3250
3236
|
"sort": sorting.AutomationSort.UPDATED_DESC,
|
3251
|
-
"automations": automation_filter.
|
3237
|
+
"automations": automation_filter.model_dump(mode="json")
|
3252
3238
|
if automation_filter
|
3253
3239
|
else None,
|
3254
3240
|
},
|
@@ -3256,30 +3242,21 @@ class PrefectClient:
|
|
3256
3242
|
|
3257
3243
|
response.raise_for_status()
|
3258
3244
|
|
3259
|
-
return pydantic.
|
3245
|
+
return pydantic.TypeAdapter(List[Automation]).validate_python(response.json())
|
3260
3246
|
|
3261
3247
|
async def pause_automation(self, automation_id: UUID):
|
3262
|
-
if not self.server_type.supports_automations():
|
3263
|
-
self._raise_for_unsupported_automations()
|
3264
|
-
|
3265
3248
|
response = await self._client.patch(
|
3266
3249
|
f"/automations/{automation_id}", json={"enabled": False}
|
3267
3250
|
)
|
3268
3251
|
response.raise_for_status()
|
3269
3252
|
|
3270
3253
|
async def resume_automation(self, automation_id: UUID):
|
3271
|
-
if not self.server_type.supports_automations():
|
3272
|
-
self._raise_for_unsupported_automations()
|
3273
|
-
|
3274
3254
|
response = await self._client.patch(
|
3275
3255
|
f"/automations/{automation_id}", json={"enabled": True}
|
3276
3256
|
)
|
3277
3257
|
response.raise_for_status()
|
3278
3258
|
|
3279
3259
|
async def delete_automation(self, automation_id: UUID):
|
3280
|
-
if not self.server_type.supports_automations():
|
3281
|
-
self._raise_for_unsupported_automations()
|
3282
|
-
|
3283
3260
|
response = await self._client.delete(f"/automations/{automation_id}")
|
3284
3261
|
if response.status_code == 404:
|
3285
3262
|
return
|
@@ -3289,17 +3266,11 @@ class PrefectClient:
|
|
3289
3266
|
async def read_resource_related_automations(
|
3290
3267
|
self, resource_id: str
|
3291
3268
|
) -> List[Automation]:
|
3292
|
-
if not self.server_type.supports_automations():
|
3293
|
-
self._raise_for_unsupported_automations()
|
3294
|
-
|
3295
3269
|
response = await self._client.get(f"/automations/related-to/{resource_id}")
|
3296
3270
|
response.raise_for_status()
|
3297
|
-
return pydantic.
|
3271
|
+
return pydantic.TypeAdapter(List[Automation]).validate_python(response.json())
|
3298
3272
|
|
3299
3273
|
async def delete_resource_owned_automations(self, resource_id: str):
|
3300
|
-
if not self.server_type.supports_automations():
|
3301
|
-
self._raise_for_unsupported_automations()
|
3302
|
-
|
3303
3274
|
await self._client.delete(f"/automations/owned-by/{resource_id}")
|
3304
3275
|
|
3305
3276
|
async def __aenter__(self):
|
@@ -3318,9 +3289,11 @@ class PrefectClient:
|
|
3318
3289
|
"Retrieve a new client with `get_client()` instead."
|
3319
3290
|
)
|
3320
3291
|
|
3292
|
+
self._context_stack += 1
|
3293
|
+
|
3321
3294
|
if self._started:
|
3322
|
-
#
|
3323
|
-
|
3295
|
+
# allow reentrancy
|
3296
|
+
return self
|
3324
3297
|
|
3325
3298
|
self._loop = asyncio.get_running_loop()
|
3326
3299
|
await self._exit_stack.__aenter__()
|
@@ -3351,6 +3324,10 @@ class PrefectClient:
|
|
3351
3324
|
"""
|
3352
3325
|
Shutdown the client.
|
3353
3326
|
"""
|
3327
|
+
|
3328
|
+
self._context_stack -= 1
|
3329
|
+
if self._context_stack > 0:
|
3330
|
+
return
|
3354
3331
|
self._closed = True
|
3355
3332
|
return await self._exit_stack.__aexit__(*exc_info)
|
3356
3333
|
|
@@ -3416,6 +3393,7 @@ class SyncPrefectClient:
|
|
3416
3393
|
httpx_settings["headers"].setdefault("Authorization", f"Bearer {api_key}")
|
3417
3394
|
|
3418
3395
|
# Context management
|
3396
|
+
self._context_stack: int = 0
|
3419
3397
|
self._ephemeral_app: Optional[ASGIApp] = None
|
3420
3398
|
self.manage_lifespan = True
|
3421
3399
|
self.server_type: ServerType
|
@@ -3547,9 +3525,12 @@ class SyncPrefectClient:
|
|
3547
3525
|
"Retrieve a new client with `get_client()` instead."
|
3548
3526
|
)
|
3549
3527
|
|
3528
|
+
self._context_stack += 1
|
3529
|
+
|
3550
3530
|
if self._started:
|
3551
|
-
#
|
3552
|
-
|
3531
|
+
# allow reentrancy
|
3532
|
+
return self
|
3533
|
+
|
3553
3534
|
self._client.__enter__()
|
3554
3535
|
self._started = True
|
3555
3536
|
|
@@ -3559,6 +3540,9 @@ class SyncPrefectClient:
|
|
3559
3540
|
"""
|
3560
3541
|
Shutdown the client.
|
3561
3542
|
"""
|
3543
|
+
self._context_stack -= 1
|
3544
|
+
if self._context_stack > 0:
|
3545
|
+
return
|
3562
3546
|
self._closed = True
|
3563
3547
|
self._client.__exit__(*exc_info)
|
3564
3548
|
|
@@ -3612,9 +3596,7 @@ class SyncPrefectClient:
|
|
3612
3596
|
the ID of the flow in the backend
|
3613
3597
|
"""
|
3614
3598
|
flow_data = FlowCreate(name=flow_name)
|
3615
|
-
response = self._client.post(
|
3616
|
-
"/flows/", json=flow_data.dict(json_compatible=True)
|
3617
|
-
)
|
3599
|
+
response = self._client.post("/flows/", json=flow_data.model_dump(mode="json"))
|
3618
3600
|
|
3619
3601
|
flow_id = response.json().get("id")
|
3620
3602
|
if not flow_id:
|
@@ -3677,9 +3659,9 @@ class SyncPrefectClient:
|
|
3677
3659
|
),
|
3678
3660
|
)
|
3679
3661
|
|
3680
|
-
flow_run_create_json = flow_run_create.
|
3662
|
+
flow_run_create_json = flow_run_create.model_dump(mode="json")
|
3681
3663
|
response = self._client.post("/flow_runs/", json=flow_run_create_json)
|
3682
|
-
flow_run = FlowRun.
|
3664
|
+
flow_run = FlowRun.model_validate(response.json())
|
3683
3665
|
|
3684
3666
|
# Restore the parameters to the local objects to retain expectations about
|
3685
3667
|
# Python objects
|
@@ -3704,7 +3686,7 @@ class SyncPrefectClient:
|
|
3704
3686
|
raise prefect.exceptions.ObjectNotFound(http_exc=e) from e
|
3705
3687
|
else:
|
3706
3688
|
raise
|
3707
|
-
return FlowRun.
|
3689
|
+
return FlowRun.model_validate(response.json())
|
3708
3690
|
|
3709
3691
|
def read_flow_runs(
|
3710
3692
|
self,
|
@@ -3739,29 +3721,23 @@ class SyncPrefectClient:
|
|
3739
3721
|
of the flow runs
|
3740
3722
|
"""
|
3741
3723
|
body = {
|
3742
|
-
"flows": flow_filter.
|
3724
|
+
"flows": flow_filter.model_dump(mode="json") if flow_filter else None,
|
3743
3725
|
"flow_runs": (
|
3744
|
-
flow_run_filter.
|
3726
|
+
flow_run_filter.model_dump(mode="json", exclude_unset=True)
|
3745
3727
|
if flow_run_filter
|
3746
3728
|
else None
|
3747
3729
|
),
|
3748
3730
|
"task_runs": (
|
3749
|
-
task_run_filter.
|
3731
|
+
task_run_filter.model_dump(mode="json") if task_run_filter else None
|
3750
3732
|
),
|
3751
3733
|
"deployments": (
|
3752
|
-
deployment_filter.
|
3753
|
-
if deployment_filter
|
3754
|
-
else None
|
3734
|
+
deployment_filter.model_dump(mode="json") if deployment_filter else None
|
3755
3735
|
),
|
3756
3736
|
"work_pools": (
|
3757
|
-
work_pool_filter.
|
3758
|
-
if work_pool_filter
|
3759
|
-
else None
|
3737
|
+
work_pool_filter.model_dump(mode="json") if work_pool_filter else None
|
3760
3738
|
),
|
3761
3739
|
"work_pool_queues": (
|
3762
|
-
work_queue_filter.
|
3763
|
-
if work_queue_filter
|
3764
|
-
else None
|
3740
|
+
work_queue_filter.model_dump(mode="json") if work_queue_filter else None
|
3765
3741
|
),
|
3766
3742
|
"sort": sort,
|
3767
3743
|
"limit": limit,
|
@@ -3769,7 +3745,7 @@ class SyncPrefectClient:
|
|
3769
3745
|
}
|
3770
3746
|
|
3771
3747
|
response = self._client.post("/flow_runs/filter", json=body)
|
3772
|
-
return pydantic.
|
3748
|
+
return pydantic.TypeAdapter(List[FlowRun]).validate_python(response.json())
|
3773
3749
|
|
3774
3750
|
def set_flow_run_state(
|
3775
3751
|
self,
|
@@ -3795,7 +3771,7 @@ class SyncPrefectClient:
|
|
3795
3771
|
try:
|
3796
3772
|
response = self._client.post(
|
3797
3773
|
f"/flow_runs/{flow_run_id}/set_state",
|
3798
|
-
json=dict(state=state_create.
|
3774
|
+
json=dict(state=state_create.model_dump(mode="json"), force=force),
|
3799
3775
|
)
|
3800
3776
|
except httpx.HTTPStatusError as e:
|
3801
3777
|
if e.response.status_code == status.HTTP_404_NOT_FOUND:
|
@@ -3803,13 +3779,28 @@ class SyncPrefectClient:
|
|
3803
3779
|
else:
|
3804
3780
|
raise
|
3805
3781
|
|
3806
|
-
return OrchestrationResult.
|
3782
|
+
return OrchestrationResult.model_validate(response.json())
|
3783
|
+
|
3784
|
+
def set_flow_run_name(self, flow_run_id: UUID, name: str):
|
3785
|
+
flow_run_data = TaskRunUpdate(name=name)
|
3786
|
+
return self._client.patch(
|
3787
|
+
f"/flow_runs/{flow_run_id}",
|
3788
|
+
json=flow_run_data.model_dump(mode="json", exclude_unset=True),
|
3789
|
+
)
|
3790
|
+
|
3791
|
+
def set_task_run_name(self, task_run_id: UUID, name: str):
|
3792
|
+
task_run_data = TaskRunUpdate(name=name)
|
3793
|
+
return self._client.patch(
|
3794
|
+
f"/task_runs/{task_run_id}",
|
3795
|
+
json=task_run_data.model_dump(mode="json", exclude_unset=True),
|
3796
|
+
)
|
3807
3797
|
|
3808
3798
|
def create_task_run(
|
3809
3799
|
self,
|
3810
3800
|
task: "TaskObject[P, R]",
|
3811
3801
|
flow_run_id: Optional[UUID],
|
3812
3802
|
dynamic_key: str,
|
3803
|
+
id: Optional[UUID] = None,
|
3813
3804
|
name: Optional[str] = None,
|
3814
3805
|
extra_tags: Optional[Iterable[str]] = None,
|
3815
3806
|
state: Optional[prefect.states.State[R]] = None,
|
@@ -3833,6 +3824,8 @@ class SyncPrefectClient:
|
|
3833
3824
|
task: The Task to run
|
3834
3825
|
flow_run_id: The flow run id with which to associate the task run
|
3835
3826
|
dynamic_key: A key unique to this particular run of a Task within the flow
|
3827
|
+
id: An optional ID for the task run. If not provided, one will be generated
|
3828
|
+
server-side.
|
3836
3829
|
name: An optional name for the task run
|
3837
3830
|
extra_tags: an optional list of extra tags to apply to the task run in
|
3838
3831
|
addition to `task.tags`
|
@@ -3849,6 +3842,7 @@ class SyncPrefectClient:
|
|
3849
3842
|
state = prefect.states.Pending()
|
3850
3843
|
|
3851
3844
|
task_run_data = TaskRunCreate(
|
3845
|
+
id=id,
|
3852
3846
|
name=name,
|
3853
3847
|
flow_run_id=flow_run_id,
|
3854
3848
|
task_key=task.task_key,
|
@@ -3864,10 +3858,10 @@ class SyncPrefectClient:
|
|
3864
3858
|
task_inputs=task_inputs or {},
|
3865
3859
|
)
|
3866
3860
|
|
3867
|
-
|
3868
|
-
|
3869
|
-
)
|
3870
|
-
return TaskRun.
|
3861
|
+
content = task_run_data.model_dump_json(exclude={"id"} if id is None else None)
|
3862
|
+
|
3863
|
+
response = self._client.post("/task_runs/", content=content)
|
3864
|
+
return TaskRun.model_validate(response.json())
|
3871
3865
|
|
3872
3866
|
def read_task_run(self, task_run_id: UUID) -> TaskRun:
|
3873
3867
|
"""
|
@@ -3879,8 +3873,14 @@ class SyncPrefectClient:
|
|
3879
3873
|
Returns:
|
3880
3874
|
a Task Run model representation of the task run
|
3881
3875
|
"""
|
3882
|
-
|
3883
|
-
|
3876
|
+
try:
|
3877
|
+
response = self._client.get(f"/task_runs/{task_run_id}")
|
3878
|
+
return TaskRun.model_validate(response.json())
|
3879
|
+
except httpx.HTTPStatusError as e:
|
3880
|
+
if e.response.status_code == status.HTTP_404_NOT_FOUND:
|
3881
|
+
raise prefect.exceptions.ObjectNotFound(http_exc=e) from e
|
3882
|
+
else:
|
3883
|
+
raise
|
3884
3884
|
|
3885
3885
|
def read_task_runs(
|
3886
3886
|
self,
|
@@ -3911,26 +3911,24 @@ class SyncPrefectClient:
|
|
3911
3911
|
of the task runs
|
3912
3912
|
"""
|
3913
3913
|
body = {
|
3914
|
-
"flows": flow_filter.
|
3914
|
+
"flows": flow_filter.model_dump(mode="json") if flow_filter else None,
|
3915
3915
|
"flow_runs": (
|
3916
|
-
flow_run_filter.
|
3916
|
+
flow_run_filter.model_dump(mode="json", exclude_unset=True)
|
3917
3917
|
if flow_run_filter
|
3918
3918
|
else None
|
3919
3919
|
),
|
3920
3920
|
"task_runs": (
|
3921
|
-
task_run_filter.
|
3921
|
+
task_run_filter.model_dump(mode="json") if task_run_filter else None
|
3922
3922
|
),
|
3923
3923
|
"deployments": (
|
3924
|
-
deployment_filter.
|
3925
|
-
if deployment_filter
|
3926
|
-
else None
|
3924
|
+
deployment_filter.model_dump(mode="json") if deployment_filter else None
|
3927
3925
|
),
|
3928
3926
|
"sort": sort,
|
3929
3927
|
"limit": limit,
|
3930
3928
|
"offset": offset,
|
3931
3929
|
}
|
3932
3930
|
response = self._client.post("/task_runs/filter", json=body)
|
3933
|
-
return pydantic.
|
3931
|
+
return pydantic.TypeAdapter(List[TaskRun]).validate_python(response.json())
|
3934
3932
|
|
3935
3933
|
def set_task_run_state(
|
3936
3934
|
self,
|
@@ -3954,9 +3952,9 @@ class SyncPrefectClient:
|
|
3954
3952
|
state_create.state_details.task_run_id = task_run_id
|
3955
3953
|
response = self._client.post(
|
3956
3954
|
f"/task_runs/{task_run_id}/set_state",
|
3957
|
-
json=dict(state=state_create.
|
3955
|
+
json=dict(state=state_create.model_dump(mode="json"), force=force),
|
3958
3956
|
)
|
3959
|
-
return OrchestrationResult.
|
3957
|
+
return OrchestrationResult.model_validate(response.json())
|
3960
3958
|
|
3961
3959
|
def read_task_run_states(self, task_run_id: UUID) -> List[prefect.states.State]:
|
3962
3960
|
"""
|
@@ -3971,4 +3969,28 @@ class SyncPrefectClient:
|
|
3971
3969
|
response = self._client.get(
|
3972
3970
|
"/task_run_states/", params=dict(task_run_id=str(task_run_id))
|
3973
3971
|
)
|
3974
|
-
return pydantic.
|
3972
|
+
return pydantic.TypeAdapter(List[prefect.states.State]).validate_python(
|
3973
|
+
response.json()
|
3974
|
+
)
|
3975
|
+
|
3976
|
+
def read_deployment(
|
3977
|
+
self,
|
3978
|
+
deployment_id: UUID,
|
3979
|
+
) -> DeploymentResponse:
|
3980
|
+
"""
|
3981
|
+
Query the Prefect API for a deployment by id.
|
3982
|
+
|
3983
|
+
Args:
|
3984
|
+
deployment_id: the deployment ID of interest
|
3985
|
+
|
3986
|
+
Returns:
|
3987
|
+
a [Deployment model][prefect.client.schemas.objects.Deployment] representation of the deployment
|
3988
|
+
"""
|
3989
|
+
try:
|
3990
|
+
response = self._client.get(f"/deployments/{deployment_id}")
|
3991
|
+
except httpx.HTTPStatusError as e:
|
3992
|
+
if e.response.status_code == status.HTTP_404_NOT_FOUND:
|
3993
|
+
raise prefect.exceptions.ObjectNotFound(http_exc=e) from e
|
3994
|
+
else:
|
3995
|
+
raise
|
3996
|
+
return DeploymentResponse.model_validate(response.json())
|