prefect-client 3.1.11__py3-none-any.whl → 3.1.12__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/_experimental/sla/__init__.py +0 -0
- prefect/_experimental/sla/client.py +66 -0
- prefect/_experimental/sla/objects.py +53 -0
- prefect/_version.py +3 -3
- prefect/automations.py +236 -30
- prefect/blocks/__init__.py +3 -3
- prefect/blocks/abstract.py +53 -30
- prefect/blocks/core.py +181 -82
- prefect/blocks/notifications.py +133 -73
- prefect/blocks/redis.py +13 -9
- prefect/blocks/system.py +24 -11
- prefect/blocks/webhook.py +7 -5
- prefect/cache_policies.py +3 -2
- prefect/client/orchestration/__init__.py +103 -2006
- prefect/client/orchestration/_automations/__init__.py +0 -0
- prefect/client/orchestration/_automations/client.py +329 -0
- prefect/client/orchestration/_blocks_documents/__init__.py +0 -0
- prefect/client/orchestration/_blocks_documents/client.py +334 -0
- prefect/client/orchestration/_blocks_schemas/__init__.py +0 -0
- prefect/client/orchestration/_blocks_schemas/client.py +200 -0
- prefect/client/orchestration/_blocks_types/__init__.py +0 -0
- prefect/client/orchestration/_blocks_types/client.py +380 -0
- prefect/client/orchestration/_deployments/__init__.py +0 -0
- prefect/client/orchestration/_deployments/client.py +1128 -0
- prefect/client/orchestration/_flow_runs/__init__.py +0 -0
- prefect/client/orchestration/_flow_runs/client.py +903 -0
- prefect/client/orchestration/_flows/__init__.py +0 -0
- prefect/client/orchestration/_flows/client.py +343 -0
- prefect/client/orchestration/_logs/client.py +16 -14
- prefect/client/schemas/__init__.py +68 -28
- prefect/client/schemas/objects.py +5 -5
- prefect/context.py +15 -1
- prefect/deployments/base.py +6 -0
- prefect/deployments/runner.py +42 -1
- prefect/engine.py +17 -4
- prefect/filesystems.py +6 -2
- prefect/flow_engine.py +47 -38
- prefect/flows.py +10 -1
- prefect/logging/logging.yml +1 -1
- prefect/runner/runner.py +4 -2
- prefect/settings/models/cloud.py +5 -0
- prefect/settings/models/experiments.py +0 -5
- prefect/states.py +57 -38
- prefect/task_runners.py +56 -55
- prefect/task_worker.py +2 -2
- prefect/tasks.py +6 -4
- prefect/telemetry/bootstrap.py +10 -9
- prefect/telemetry/services.py +4 -0
- prefect/utilities/templating.py +25 -1
- prefect/workers/base.py +6 -3
- prefect/workers/process.py +1 -1
- {prefect_client-3.1.11.dist-info → prefect_client-3.1.12.dist-info}/METADATA +2 -2
- {prefect_client-3.1.11.dist-info → prefect_client-3.1.12.dist-info}/RECORD +56 -39
- {prefect_client-3.1.11.dist-info → prefect_client-3.1.12.dist-info}/LICENSE +0 -0
- {prefect_client-3.1.11.dist-info → prefect_client-3.1.12.dist-info}/WHEEL +0 -0
- {prefect_client-3.1.11.dist-info → prefect_client-3.1.12.dist-info}/top_level.txt +0 -0
File without changes
|
@@ -0,0 +1,329 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
|
3
|
+
from typing import TYPE_CHECKING
|
4
|
+
|
5
|
+
from httpx import HTTPStatusError
|
6
|
+
|
7
|
+
from prefect.client.orchestration.base import BaseAsyncClient, BaseClient
|
8
|
+
from prefect.exceptions import ObjectNotFound
|
9
|
+
|
10
|
+
if TYPE_CHECKING:
|
11
|
+
from uuid import UUID
|
12
|
+
|
13
|
+
from prefect.events.schemas.automations import Automation, AutomationCore
|
14
|
+
|
15
|
+
|
16
|
+
class AutomationClient(BaseClient):
|
17
|
+
def create_automation(self, automation: "AutomationCore") -> "UUID":
|
18
|
+
"""Creates an automation in Prefect Cloud."""
|
19
|
+
response = self.request(
|
20
|
+
"POST",
|
21
|
+
"/automations/",
|
22
|
+
json=automation.model_dump(mode="json"),
|
23
|
+
)
|
24
|
+
from uuid import UUID
|
25
|
+
|
26
|
+
return UUID(response.json()["id"])
|
27
|
+
|
28
|
+
def update_automation(
|
29
|
+
self, automation_id: "UUID", automation: "AutomationCore"
|
30
|
+
) -> None:
|
31
|
+
"""Updates an automation in Prefect Cloud."""
|
32
|
+
response = self.request(
|
33
|
+
"PUT",
|
34
|
+
"/automations/{id}",
|
35
|
+
path_params={"id": automation_id},
|
36
|
+
json=automation.model_dump(mode="json", exclude_unset=True),
|
37
|
+
)
|
38
|
+
response.raise_for_status()
|
39
|
+
|
40
|
+
def read_automations(self) -> list["Automation"]:
|
41
|
+
response = self.request("POST", "/automations/filter")
|
42
|
+
response.raise_for_status()
|
43
|
+
from prefect.events.schemas.automations import Automation
|
44
|
+
|
45
|
+
return Automation.model_validate_list(response.json())
|
46
|
+
|
47
|
+
def find_automation(self, id_or_name: "str | UUID") -> "Automation | None":
|
48
|
+
if isinstance(id_or_name, str):
|
49
|
+
name = id_or_name
|
50
|
+
try:
|
51
|
+
id = UUID(id_or_name)
|
52
|
+
except ValueError:
|
53
|
+
id = None
|
54
|
+
else:
|
55
|
+
id = id_or_name
|
56
|
+
name = str(id)
|
57
|
+
|
58
|
+
if id:
|
59
|
+
try:
|
60
|
+
automation = self.read_automation(id)
|
61
|
+
return automation
|
62
|
+
except HTTPStatusError as e:
|
63
|
+
if e.response.status_code == 404:
|
64
|
+
raise ObjectNotFound(http_exc=e) from e
|
65
|
+
|
66
|
+
automations = self.read_automations()
|
67
|
+
|
68
|
+
# Look for it by an exact name
|
69
|
+
for automation in automations:
|
70
|
+
if automation.name == name:
|
71
|
+
return automation
|
72
|
+
|
73
|
+
# Look for it by a case-insensitive name
|
74
|
+
for automation in automations:
|
75
|
+
if automation.name.lower() == name.lower():
|
76
|
+
return automation
|
77
|
+
|
78
|
+
return None
|
79
|
+
|
80
|
+
def read_automation(self, automation_id: "UUID | str") -> "Automation | None":
|
81
|
+
response = self.request(
|
82
|
+
"GET", "/automations/{id}", path_params={"id": automation_id}
|
83
|
+
)
|
84
|
+
if response.status_code == 404:
|
85
|
+
return None
|
86
|
+
response.raise_for_status()
|
87
|
+
from prefect.events.schemas.automations import Automation
|
88
|
+
|
89
|
+
return Automation.model_validate(response.json())
|
90
|
+
|
91
|
+
def read_automations_by_name(self, name: str) -> list["Automation"]:
|
92
|
+
"""
|
93
|
+
Query the Prefect API for an automation by name. Only automations matching the provided name will be returned.
|
94
|
+
|
95
|
+
Args:
|
96
|
+
name: the name of the automation to query
|
97
|
+
|
98
|
+
Returns:
|
99
|
+
a list of Automation model representations of the automations
|
100
|
+
"""
|
101
|
+
from prefect.client.schemas.sorting import AutomationSort
|
102
|
+
from prefect.events.filters import (
|
103
|
+
AutomationFilter,
|
104
|
+
AutomationFilterName,
|
105
|
+
)
|
106
|
+
|
107
|
+
automation_filter = AutomationFilter(name=AutomationFilterName(any_=[name]))
|
108
|
+
|
109
|
+
response = self.request(
|
110
|
+
"POST",
|
111
|
+
"/automations/filter",
|
112
|
+
json={
|
113
|
+
"sort": AutomationSort.UPDATED_DESC,
|
114
|
+
"automations": automation_filter.model_dump(mode="json")
|
115
|
+
if automation_filter
|
116
|
+
else None,
|
117
|
+
},
|
118
|
+
)
|
119
|
+
|
120
|
+
response.raise_for_status()
|
121
|
+
from prefect.events.schemas.automations import Automation
|
122
|
+
|
123
|
+
return Automation.model_validate_list(response.json())
|
124
|
+
|
125
|
+
def pause_automation(self, automation_id: "UUID") -> None:
|
126
|
+
response = self.request(
|
127
|
+
"PATCH",
|
128
|
+
"/automations/{id}",
|
129
|
+
path_params={"id": automation_id},
|
130
|
+
json={"enabled": False},
|
131
|
+
)
|
132
|
+
response.raise_for_status()
|
133
|
+
|
134
|
+
def resume_automation(self, automation_id: "UUID") -> None:
|
135
|
+
response = self.request(
|
136
|
+
"PATCH",
|
137
|
+
"/automations/{id}",
|
138
|
+
path_params={"id": automation_id},
|
139
|
+
json={"enabled": True},
|
140
|
+
)
|
141
|
+
response.raise_for_status()
|
142
|
+
|
143
|
+
def delete_automation(self, automation_id: "UUID") -> None:
|
144
|
+
response = self.request(
|
145
|
+
"DELETE",
|
146
|
+
"/automations/{id}",
|
147
|
+
path_params={"id": automation_id},
|
148
|
+
)
|
149
|
+
if response.status_code == 404:
|
150
|
+
return
|
151
|
+
|
152
|
+
response.raise_for_status()
|
153
|
+
|
154
|
+
def read_resource_related_automations(self, resource_id: str) -> list["Automation"]:
|
155
|
+
response = self.request(
|
156
|
+
"GET",
|
157
|
+
"/automations/related-to/{resource_id}",
|
158
|
+
path_params={"resource_id": resource_id},
|
159
|
+
)
|
160
|
+
response.raise_for_status()
|
161
|
+
from prefect.events.schemas.automations import Automation
|
162
|
+
|
163
|
+
return Automation.model_validate_list(response.json())
|
164
|
+
|
165
|
+
def delete_resource_owned_automations(self, resource_id: str) -> None:
|
166
|
+
self.request(
|
167
|
+
"DELETE",
|
168
|
+
"/automations/owned-by/{resource_id}",
|
169
|
+
path_params={"resource_id": resource_id},
|
170
|
+
)
|
171
|
+
|
172
|
+
|
173
|
+
class AutomationAsyncClient(BaseAsyncClient):
|
174
|
+
async def create_automation(self, automation: "AutomationCore") -> "UUID":
|
175
|
+
"""Creates an automation in Prefect Cloud."""
|
176
|
+
response = await self.request(
|
177
|
+
"POST",
|
178
|
+
"/automations/",
|
179
|
+
json=automation.model_dump(mode="json"),
|
180
|
+
)
|
181
|
+
from uuid import UUID
|
182
|
+
|
183
|
+
return UUID(response.json()["id"])
|
184
|
+
|
185
|
+
async def update_automation(
|
186
|
+
self, automation_id: "UUID", automation: "AutomationCore"
|
187
|
+
) -> None:
|
188
|
+
"""Updates an automation in Prefect Cloud."""
|
189
|
+
response = await self.request(
|
190
|
+
"PUT",
|
191
|
+
"/automations/{id}",
|
192
|
+
path_params={"id": automation_id},
|
193
|
+
json=automation.model_dump(mode="json", exclude_unset=True),
|
194
|
+
)
|
195
|
+
response.raise_for_status()
|
196
|
+
|
197
|
+
async def read_automations(self) -> list["Automation"]:
|
198
|
+
response = await self.request("POST", "/automations/filter")
|
199
|
+
response.raise_for_status()
|
200
|
+
from prefect.events.schemas.automations import Automation
|
201
|
+
|
202
|
+
return Automation.model_validate_list(response.json())
|
203
|
+
|
204
|
+
async def find_automation(self, id_or_name: "str | UUID") -> "Automation | None":
|
205
|
+
if isinstance(id_or_name, str):
|
206
|
+
name = id_or_name
|
207
|
+
try:
|
208
|
+
id = UUID(id_or_name)
|
209
|
+
except ValueError:
|
210
|
+
id = None
|
211
|
+
else:
|
212
|
+
id = id_or_name
|
213
|
+
name = str(id)
|
214
|
+
|
215
|
+
if id:
|
216
|
+
try:
|
217
|
+
automation = await self.read_automation(id)
|
218
|
+
return automation
|
219
|
+
except HTTPStatusError as e:
|
220
|
+
if e.response.status_code == 404:
|
221
|
+
raise ObjectNotFound(http_exc=e) from e
|
222
|
+
|
223
|
+
automations = await self.read_automations()
|
224
|
+
|
225
|
+
# Look for it by an exact name
|
226
|
+
for automation in automations:
|
227
|
+
if automation.name == name:
|
228
|
+
return automation
|
229
|
+
|
230
|
+
# Look for it by a case-insensitive name
|
231
|
+
for automation in automations:
|
232
|
+
if automation.name.lower() == name.lower():
|
233
|
+
return automation
|
234
|
+
|
235
|
+
return None
|
236
|
+
|
237
|
+
async def read_automation(self, automation_id: "UUID | str") -> "Automation | None":
|
238
|
+
response = await self.request(
|
239
|
+
"GET", "/automations/{id}", path_params={"id": automation_id}
|
240
|
+
)
|
241
|
+
if response.status_code == 404:
|
242
|
+
return None
|
243
|
+
response.raise_for_status()
|
244
|
+
from prefect.events.schemas.automations import Automation
|
245
|
+
|
246
|
+
return Automation.model_validate(response.json())
|
247
|
+
|
248
|
+
async def read_automations_by_name(self, name: str) -> list["Automation"]:
|
249
|
+
"""
|
250
|
+
Query the Prefect API for an automation by name. Only automations matching the provided name will be returned.
|
251
|
+
|
252
|
+
Args:
|
253
|
+
name: the name of the automation to query
|
254
|
+
|
255
|
+
Returns:
|
256
|
+
a list of Automation model representations of the automations
|
257
|
+
"""
|
258
|
+
from prefect.client.schemas.sorting import AutomationSort
|
259
|
+
from prefect.events.filters import (
|
260
|
+
AutomationFilter,
|
261
|
+
AutomationFilterName,
|
262
|
+
)
|
263
|
+
|
264
|
+
automation_filter = AutomationFilter(name=AutomationFilterName(any_=[name]))
|
265
|
+
|
266
|
+
response = await self.request(
|
267
|
+
"POST",
|
268
|
+
"/automations/filter",
|
269
|
+
json={
|
270
|
+
"sort": AutomationSort.UPDATED_DESC,
|
271
|
+
"automations": automation_filter.model_dump(mode="json")
|
272
|
+
if automation_filter
|
273
|
+
else None,
|
274
|
+
},
|
275
|
+
)
|
276
|
+
|
277
|
+
response.raise_for_status()
|
278
|
+
from prefect.events.schemas.automations import Automation
|
279
|
+
|
280
|
+
return Automation.model_validate_list(response.json())
|
281
|
+
|
282
|
+
async def pause_automation(self, automation_id: "UUID") -> None:
|
283
|
+
response = await self.request(
|
284
|
+
"PATCH",
|
285
|
+
"/automations/{id}",
|
286
|
+
path_params={"id": automation_id},
|
287
|
+
json={"enabled": False},
|
288
|
+
)
|
289
|
+
response.raise_for_status()
|
290
|
+
|
291
|
+
async def resume_automation(self, automation_id: "UUID") -> None:
|
292
|
+
response = await self.request(
|
293
|
+
"PATCH",
|
294
|
+
"/automations/{id}",
|
295
|
+
path_params={"id": automation_id},
|
296
|
+
json={"enabled": True},
|
297
|
+
)
|
298
|
+
response.raise_for_status()
|
299
|
+
|
300
|
+
async def delete_automation(self, automation_id: "UUID") -> None:
|
301
|
+
response = await self.request(
|
302
|
+
"DELETE",
|
303
|
+
"/automations/{id}",
|
304
|
+
path_params={"id": automation_id},
|
305
|
+
)
|
306
|
+
if response.status_code == 404:
|
307
|
+
return
|
308
|
+
|
309
|
+
response.raise_for_status()
|
310
|
+
|
311
|
+
async def read_resource_related_automations(
|
312
|
+
self, resource_id: str
|
313
|
+
) -> list["Automation"]:
|
314
|
+
response = await self.request(
|
315
|
+
"GET",
|
316
|
+
"/automations/related-to/{resource_id}",
|
317
|
+
path_params={"resource_id": resource_id},
|
318
|
+
)
|
319
|
+
response.raise_for_status()
|
320
|
+
from prefect.events.schemas.automations import Automation
|
321
|
+
|
322
|
+
return Automation.model_validate_list(response.json())
|
323
|
+
|
324
|
+
async def delete_resource_owned_automations(self, resource_id: str) -> None:
|
325
|
+
await self.request(
|
326
|
+
"DELETE",
|
327
|
+
"/automations/owned-by/{resource_id}",
|
328
|
+
path_params={"resource_id": resource_id},
|
329
|
+
)
|
File without changes
|
@@ -0,0 +1,334 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
|
3
|
+
from typing import TYPE_CHECKING
|
4
|
+
|
5
|
+
from httpx import HTTPStatusError
|
6
|
+
|
7
|
+
from prefect.client.orchestration.base import BaseAsyncClient, BaseClient
|
8
|
+
from prefect.exceptions import ObjectAlreadyExists, ObjectNotFound
|
9
|
+
|
10
|
+
if TYPE_CHECKING:
|
11
|
+
from uuid import UUID
|
12
|
+
|
13
|
+
from prefect.client.schemas.actions import (
|
14
|
+
BlockDocumentCreate,
|
15
|
+
BlockDocumentUpdate,
|
16
|
+
)
|
17
|
+
from prefect.client.schemas.objects import (
|
18
|
+
BlockDocument,
|
19
|
+
)
|
20
|
+
|
21
|
+
|
22
|
+
class BlocksDocumentClient(BaseClient):
|
23
|
+
def create_block_document(
|
24
|
+
self,
|
25
|
+
block_document: "BlockDocument | BlockDocumentCreate",
|
26
|
+
include_secrets: bool = True,
|
27
|
+
) -> "BlockDocument":
|
28
|
+
"""
|
29
|
+
Create a block document in the Prefect API. This data is used to configure a
|
30
|
+
corresponding Block.
|
31
|
+
|
32
|
+
Args:
|
33
|
+
include_secrets (bool): whether to include secret values
|
34
|
+
on the stored Block, corresponding to Pydantic's `SecretStr` and
|
35
|
+
`SecretBytes` fields. Note Blocks may not work as expected if
|
36
|
+
this is set to `False`.
|
37
|
+
"""
|
38
|
+
block_document_data = block_document.model_dump(
|
39
|
+
mode="json",
|
40
|
+
exclude_unset=True,
|
41
|
+
exclude={"id", "block_schema", "block_type"},
|
42
|
+
context={"include_secrets": include_secrets},
|
43
|
+
serialize_as_any=True,
|
44
|
+
)
|
45
|
+
try:
|
46
|
+
response = self.request(
|
47
|
+
"POST",
|
48
|
+
"/block_documents/",
|
49
|
+
json=block_document_data,
|
50
|
+
)
|
51
|
+
except HTTPStatusError as e:
|
52
|
+
if e.response.status_code == 409:
|
53
|
+
raise ObjectAlreadyExists(http_exc=e) from e
|
54
|
+
else:
|
55
|
+
raise
|
56
|
+
from prefect.client.schemas.objects import BlockDocument
|
57
|
+
|
58
|
+
return BlockDocument.model_validate(response.json())
|
59
|
+
|
60
|
+
def update_block_document(
|
61
|
+
self,
|
62
|
+
block_document_id: "UUID",
|
63
|
+
block_document: "BlockDocumentUpdate",
|
64
|
+
) -> None:
|
65
|
+
"""
|
66
|
+
Update a block document in the Prefect API.
|
67
|
+
"""
|
68
|
+
try:
|
69
|
+
self.request(
|
70
|
+
"PATCH",
|
71
|
+
"/block_documents/{id}",
|
72
|
+
path_params={"id": block_document_id},
|
73
|
+
json=block_document.model_dump(
|
74
|
+
mode="json",
|
75
|
+
exclude_unset=True,
|
76
|
+
include={"data", "merge_existing_data", "block_schema_id"},
|
77
|
+
),
|
78
|
+
)
|
79
|
+
except HTTPStatusError as e:
|
80
|
+
if e.response.status_code == 404:
|
81
|
+
raise ObjectNotFound(http_exc=e) from e
|
82
|
+
else:
|
83
|
+
raise
|
84
|
+
|
85
|
+
def delete_block_document(self, block_document_id: "UUID") -> None:
|
86
|
+
"""
|
87
|
+
Delete a block document.
|
88
|
+
"""
|
89
|
+
try:
|
90
|
+
self.request(
|
91
|
+
"DELETE",
|
92
|
+
"/block_documents/{id}",
|
93
|
+
path_params={"id": block_document_id},
|
94
|
+
)
|
95
|
+
except HTTPStatusError as e:
|
96
|
+
if e.response.status_code == 404:
|
97
|
+
raise ObjectNotFound(http_exc=e) from e
|
98
|
+
else:
|
99
|
+
raise
|
100
|
+
|
101
|
+
def read_block_document(
|
102
|
+
self,
|
103
|
+
block_document_id: "UUID",
|
104
|
+
include_secrets: bool = True,
|
105
|
+
) -> "BlockDocument":
|
106
|
+
"""
|
107
|
+
Read the block document with the specified ID.
|
108
|
+
|
109
|
+
Args:
|
110
|
+
block_document_id: the block document id
|
111
|
+
include_secrets (bool): whether to include secret values
|
112
|
+
on the Block, corresponding to Pydantic's `SecretStr` and
|
113
|
+
`SecretBytes` fields. These fields are automatically obfuscated
|
114
|
+
by Pydantic, but users can additionally choose not to receive
|
115
|
+
their values from the API. Note that any business logic on the
|
116
|
+
Block may not work if this is `False`.
|
117
|
+
|
118
|
+
Raises:
|
119
|
+
httpx.RequestError: if the block document was not found for any reason
|
120
|
+
|
121
|
+
Returns:
|
122
|
+
A block document or None.
|
123
|
+
"""
|
124
|
+
|
125
|
+
try:
|
126
|
+
response = self.request(
|
127
|
+
"GET",
|
128
|
+
"/block_documents/{id}",
|
129
|
+
path_params={"id": block_document_id},
|
130
|
+
params=dict(include_secrets=include_secrets),
|
131
|
+
)
|
132
|
+
except HTTPStatusError as e:
|
133
|
+
if e.response.status_code == 404:
|
134
|
+
raise ObjectNotFound(http_exc=e) from e
|
135
|
+
else:
|
136
|
+
raise
|
137
|
+
from prefect.client.schemas.objects import BlockDocument
|
138
|
+
|
139
|
+
return BlockDocument.model_validate(response.json())
|
140
|
+
|
141
|
+
def read_block_documents(
|
142
|
+
self,
|
143
|
+
block_schema_type: str | None = None,
|
144
|
+
offset: int | None = None,
|
145
|
+
limit: int | None = None,
|
146
|
+
include_secrets: bool = True,
|
147
|
+
) -> "list[BlockDocument]":
|
148
|
+
"""
|
149
|
+
Read block documents
|
150
|
+
|
151
|
+
Args:
|
152
|
+
block_schema_type: an optional block schema type
|
153
|
+
offset: an offset
|
154
|
+
limit: the number of blocks to return
|
155
|
+
include_secrets (bool): whether to include secret values
|
156
|
+
on the Block, corresponding to Pydantic's `SecretStr` and
|
157
|
+
`SecretBytes` fields. These fields are automatically obfuscated
|
158
|
+
by Pydantic, but users can additionally choose not to receive
|
159
|
+
their values from the API. Note that any business logic on the
|
160
|
+
Block may not work if this is `False`.
|
161
|
+
|
162
|
+
Returns:
|
163
|
+
A list of block documents
|
164
|
+
"""
|
165
|
+
response = self.request(
|
166
|
+
"POST",
|
167
|
+
"/block_documents/filter",
|
168
|
+
json=dict(
|
169
|
+
block_schema_type=block_schema_type,
|
170
|
+
offset=offset,
|
171
|
+
limit=limit,
|
172
|
+
include_secrets=include_secrets,
|
173
|
+
),
|
174
|
+
)
|
175
|
+
from prefect.client.schemas.objects import BlockDocument
|
176
|
+
|
177
|
+
return BlockDocument.model_validate_list(response.json())
|
178
|
+
|
179
|
+
|
180
|
+
class BlocksDocumentAsyncClient(BaseAsyncClient):
|
181
|
+
async def create_block_document(
|
182
|
+
self,
|
183
|
+
block_document: "BlockDocument | BlockDocumentCreate",
|
184
|
+
include_secrets: bool = True,
|
185
|
+
) -> "BlockDocument":
|
186
|
+
"""
|
187
|
+
Create a block document in the Prefect API. This data is used to configure a
|
188
|
+
corresponding Block.
|
189
|
+
|
190
|
+
Args:
|
191
|
+
include_secrets (bool): whether to include secret values
|
192
|
+
on the stored Block, corresponding to Pydantic's `SecretStr` and
|
193
|
+
`SecretBytes` fields. Note Blocks may not work as expected if
|
194
|
+
this is set to `False`.
|
195
|
+
"""
|
196
|
+
block_document_data = block_document.model_dump(
|
197
|
+
mode="json",
|
198
|
+
exclude_unset=True,
|
199
|
+
exclude={"id", "block_schema", "block_type"},
|
200
|
+
context={"include_secrets": include_secrets},
|
201
|
+
serialize_as_any=True,
|
202
|
+
)
|
203
|
+
try:
|
204
|
+
response = await self.request(
|
205
|
+
"POST",
|
206
|
+
"/block_documents/",
|
207
|
+
json=block_document_data,
|
208
|
+
)
|
209
|
+
except HTTPStatusError as e:
|
210
|
+
if e.response.status_code == 409:
|
211
|
+
raise ObjectAlreadyExists(http_exc=e) from e
|
212
|
+
else:
|
213
|
+
raise
|
214
|
+
from prefect.client.schemas.objects import BlockDocument
|
215
|
+
|
216
|
+
return BlockDocument.model_validate(response.json())
|
217
|
+
|
218
|
+
async def update_block_document(
|
219
|
+
self,
|
220
|
+
block_document_id: "UUID",
|
221
|
+
block_document: "BlockDocumentUpdate",
|
222
|
+
) -> None:
|
223
|
+
"""
|
224
|
+
Update a block document in the Prefect API.
|
225
|
+
"""
|
226
|
+
try:
|
227
|
+
await self.request(
|
228
|
+
"PATCH",
|
229
|
+
"/block_documents/{id}",
|
230
|
+
path_params={"id": block_document_id},
|
231
|
+
json=block_document.model_dump(
|
232
|
+
mode="json",
|
233
|
+
exclude_unset=True,
|
234
|
+
include={"data", "merge_existing_data", "block_schema_id"},
|
235
|
+
),
|
236
|
+
)
|
237
|
+
except HTTPStatusError as e:
|
238
|
+
if e.response.status_code == 404:
|
239
|
+
raise ObjectNotFound(http_exc=e) from e
|
240
|
+
else:
|
241
|
+
raise
|
242
|
+
|
243
|
+
async def delete_block_document(self, block_document_id: "UUID") -> None:
|
244
|
+
"""
|
245
|
+
Delete a block document.
|
246
|
+
"""
|
247
|
+
try:
|
248
|
+
await self.request(
|
249
|
+
"DELETE",
|
250
|
+
"/block_documents/{id}",
|
251
|
+
path_params={"id": block_document_id},
|
252
|
+
)
|
253
|
+
except HTTPStatusError as e:
|
254
|
+
if e.response.status_code == 404:
|
255
|
+
raise ObjectNotFound(http_exc=e) from e
|
256
|
+
else:
|
257
|
+
raise
|
258
|
+
|
259
|
+
async def read_block_document(
|
260
|
+
self,
|
261
|
+
block_document_id: "UUID",
|
262
|
+
include_secrets: bool = True,
|
263
|
+
) -> "BlockDocument":
|
264
|
+
"""
|
265
|
+
Read the block document with the specified ID.
|
266
|
+
|
267
|
+
Args:
|
268
|
+
block_document_id: the block document id
|
269
|
+
include_secrets (bool): whether to include secret values
|
270
|
+
on the Block, corresponding to Pydantic's `SecretStr` and
|
271
|
+
`SecretBytes` fields. These fields are automatically obfuscated
|
272
|
+
by Pydantic, but users can additionally choose not to receive
|
273
|
+
their values from the API. Note that any business logic on the
|
274
|
+
Block may not work if this is `False`.
|
275
|
+
|
276
|
+
Raises:
|
277
|
+
httpx.RequestError: if the block document was not found for any reason
|
278
|
+
|
279
|
+
Returns:
|
280
|
+
A block document or None.
|
281
|
+
"""
|
282
|
+
try:
|
283
|
+
response = await self.request(
|
284
|
+
"GET",
|
285
|
+
"/block_documents/{id}",
|
286
|
+
path_params={"id": block_document_id},
|
287
|
+
params=dict(include_secrets=include_secrets),
|
288
|
+
)
|
289
|
+
except HTTPStatusError as e:
|
290
|
+
if e.response.status_code == 404:
|
291
|
+
raise ObjectNotFound(http_exc=e) from e
|
292
|
+
else:
|
293
|
+
raise
|
294
|
+
from prefect.client.schemas.objects import BlockDocument
|
295
|
+
|
296
|
+
return BlockDocument.model_validate(response.json())
|
297
|
+
|
298
|
+
async def read_block_documents(
|
299
|
+
self,
|
300
|
+
block_schema_type: str | None = None,
|
301
|
+
offset: int | None = None,
|
302
|
+
limit: int | None = None,
|
303
|
+
include_secrets: bool = True,
|
304
|
+
) -> "list[BlockDocument]":
|
305
|
+
"""
|
306
|
+
Read block documents
|
307
|
+
|
308
|
+
Args:
|
309
|
+
block_schema_type: an optional block schema type
|
310
|
+
offset: an offset
|
311
|
+
limit: the number of blocks to return
|
312
|
+
include_secrets (bool): whether to include secret values
|
313
|
+
on the Block, corresponding to Pydantic's `SecretStr` and
|
314
|
+
`SecretBytes` fields. These fields are automatically obfuscated
|
315
|
+
by Pydantic, but users can additionally choose not to receive
|
316
|
+
their values from the API. Note that any business logic on the
|
317
|
+
Block may not work if this is `False`.
|
318
|
+
|
319
|
+
Returns:
|
320
|
+
A list of block documents
|
321
|
+
"""
|
322
|
+
response = await self.request(
|
323
|
+
"POST",
|
324
|
+
"/block_documents/filter",
|
325
|
+
json=dict(
|
326
|
+
block_schema_type=block_schema_type,
|
327
|
+
offset=offset,
|
328
|
+
limit=limit,
|
329
|
+
include_secrets=include_secrets,
|
330
|
+
),
|
331
|
+
)
|
332
|
+
from prefect.client.schemas.objects import BlockDocument
|
333
|
+
|
334
|
+
return BlockDocument.model_validate_list(response.json())
|
File without changes
|