prefect-client 3.1.10__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.
Files changed (141) hide show
  1. prefect/_experimental/lineage.py +7 -8
  2. prefect/_experimental/sla/__init__.py +0 -0
  3. prefect/_experimental/sla/client.py +66 -0
  4. prefect/_experimental/sla/objects.py +53 -0
  5. prefect/_internal/_logging.py +15 -3
  6. prefect/_internal/compatibility/async_dispatch.py +22 -16
  7. prefect/_internal/compatibility/deprecated.py +42 -18
  8. prefect/_internal/compatibility/migration.py +2 -2
  9. prefect/_internal/concurrency/inspection.py +12 -14
  10. prefect/_internal/concurrency/primitives.py +2 -2
  11. prefect/_internal/concurrency/services.py +154 -80
  12. prefect/_internal/concurrency/waiters.py +13 -9
  13. prefect/_internal/pydantic/annotations/pendulum.py +7 -7
  14. prefect/_internal/pytz.py +4 -3
  15. prefect/_internal/retries.py +10 -5
  16. prefect/_internal/schemas/bases.py +19 -10
  17. prefect/_internal/schemas/validators.py +227 -388
  18. prefect/_version.py +3 -3
  19. prefect/automations.py +236 -30
  20. prefect/blocks/__init__.py +3 -3
  21. prefect/blocks/abstract.py +53 -30
  22. prefect/blocks/core.py +183 -84
  23. prefect/blocks/notifications.py +133 -73
  24. prefect/blocks/redis.py +13 -9
  25. prefect/blocks/system.py +24 -11
  26. prefect/blocks/webhook.py +7 -5
  27. prefect/cache_policies.py +3 -2
  28. prefect/client/orchestration/__init__.py +1957 -0
  29. prefect/client/orchestration/_artifacts/__init__.py +0 -0
  30. prefect/client/orchestration/_artifacts/client.py +239 -0
  31. prefect/client/orchestration/_automations/__init__.py +0 -0
  32. prefect/client/orchestration/_automations/client.py +329 -0
  33. prefect/client/orchestration/_blocks_documents/__init__.py +0 -0
  34. prefect/client/orchestration/_blocks_documents/client.py +334 -0
  35. prefect/client/orchestration/_blocks_schemas/__init__.py +0 -0
  36. prefect/client/orchestration/_blocks_schemas/client.py +200 -0
  37. prefect/client/orchestration/_blocks_types/__init__.py +0 -0
  38. prefect/client/orchestration/_blocks_types/client.py +380 -0
  39. prefect/client/orchestration/_concurrency_limits/__init__.py +0 -0
  40. prefect/client/orchestration/_concurrency_limits/client.py +762 -0
  41. prefect/client/orchestration/_deployments/__init__.py +0 -0
  42. prefect/client/orchestration/_deployments/client.py +1128 -0
  43. prefect/client/orchestration/_flow_runs/__init__.py +0 -0
  44. prefect/client/orchestration/_flow_runs/client.py +903 -0
  45. prefect/client/orchestration/_flows/__init__.py +0 -0
  46. prefect/client/orchestration/_flows/client.py +343 -0
  47. prefect/client/orchestration/_logs/__init__.py +0 -0
  48. prefect/client/orchestration/_logs/client.py +97 -0
  49. prefect/client/orchestration/_variables/__init__.py +0 -0
  50. prefect/client/orchestration/_variables/client.py +157 -0
  51. prefect/client/orchestration/base.py +46 -0
  52. prefect/client/orchestration/routes.py +145 -0
  53. prefect/client/schemas/__init__.py +68 -28
  54. prefect/client/schemas/actions.py +2 -2
  55. prefect/client/schemas/filters.py +5 -0
  56. prefect/client/schemas/objects.py +8 -15
  57. prefect/client/schemas/schedules.py +22 -10
  58. prefect/concurrency/_asyncio.py +87 -0
  59. prefect/concurrency/{events.py → _events.py} +10 -10
  60. prefect/concurrency/asyncio.py +20 -104
  61. prefect/concurrency/context.py +6 -4
  62. prefect/concurrency/services.py +26 -74
  63. prefect/concurrency/sync.py +23 -44
  64. prefect/concurrency/v1/_asyncio.py +63 -0
  65. prefect/concurrency/v1/{events.py → _events.py} +13 -15
  66. prefect/concurrency/v1/asyncio.py +27 -80
  67. prefect/concurrency/v1/context.py +6 -4
  68. prefect/concurrency/v1/services.py +33 -79
  69. prefect/concurrency/v1/sync.py +18 -37
  70. prefect/context.py +66 -45
  71. prefect/deployments/base.py +10 -144
  72. prefect/deployments/flow_runs.py +12 -2
  73. prefect/deployments/runner.py +53 -4
  74. prefect/deployments/steps/pull.py +13 -0
  75. prefect/engine.py +17 -4
  76. prefect/events/clients.py +7 -1
  77. prefect/events/schemas/events.py +3 -2
  78. prefect/filesystems.py +6 -2
  79. prefect/flow_engine.py +101 -85
  80. prefect/flows.py +10 -1
  81. prefect/input/run_input.py +2 -1
  82. prefect/logging/logging.yml +1 -1
  83. prefect/main.py +1 -3
  84. prefect/results.py +2 -307
  85. prefect/runner/runner.py +4 -2
  86. prefect/runner/storage.py +87 -21
  87. prefect/serializers.py +32 -25
  88. prefect/settings/legacy.py +4 -4
  89. prefect/settings/models/api.py +3 -3
  90. prefect/settings/models/cli.py +3 -3
  91. prefect/settings/models/client.py +5 -3
  92. prefect/settings/models/cloud.py +8 -3
  93. prefect/settings/models/deployments.py +3 -3
  94. prefect/settings/models/experiments.py +4 -7
  95. prefect/settings/models/flows.py +3 -3
  96. prefect/settings/models/internal.py +4 -2
  97. prefect/settings/models/logging.py +4 -3
  98. prefect/settings/models/results.py +3 -3
  99. prefect/settings/models/root.py +3 -2
  100. prefect/settings/models/runner.py +4 -4
  101. prefect/settings/models/server/api.py +3 -3
  102. prefect/settings/models/server/database.py +11 -4
  103. prefect/settings/models/server/deployments.py +6 -2
  104. prefect/settings/models/server/ephemeral.py +4 -2
  105. prefect/settings/models/server/events.py +3 -2
  106. prefect/settings/models/server/flow_run_graph.py +6 -2
  107. prefect/settings/models/server/root.py +3 -3
  108. prefect/settings/models/server/services.py +26 -11
  109. prefect/settings/models/server/tasks.py +6 -3
  110. prefect/settings/models/server/ui.py +3 -3
  111. prefect/settings/models/tasks.py +5 -5
  112. prefect/settings/models/testing.py +3 -3
  113. prefect/settings/models/worker.py +5 -3
  114. prefect/settings/profiles.py +15 -2
  115. prefect/states.py +61 -45
  116. prefect/task_engine.py +54 -75
  117. prefect/task_runners.py +56 -55
  118. prefect/task_worker.py +2 -2
  119. prefect/tasks.py +90 -36
  120. prefect/telemetry/bootstrap.py +10 -9
  121. prefect/telemetry/run_telemetry.py +13 -8
  122. prefect/telemetry/services.py +4 -0
  123. prefect/transactions.py +4 -15
  124. prefect/utilities/_git.py +34 -0
  125. prefect/utilities/asyncutils.py +1 -1
  126. prefect/utilities/engine.py +3 -19
  127. prefect/utilities/generics.py +18 -0
  128. prefect/utilities/templating.py +25 -1
  129. prefect/workers/base.py +6 -3
  130. prefect/workers/process.py +1 -1
  131. {prefect_client-3.1.10.dist-info → prefect_client-3.1.12.dist-info}/METADATA +2 -2
  132. {prefect_client-3.1.10.dist-info → prefect_client-3.1.12.dist-info}/RECORD +135 -109
  133. prefect/client/orchestration.py +0 -4523
  134. prefect/records/__init__.py +0 -1
  135. prefect/records/base.py +0 -235
  136. prefect/records/filesystem.py +0 -213
  137. prefect/records/memory.py +0 -184
  138. prefect/records/result_store.py +0 -70
  139. {prefect_client-3.1.10.dist-info → prefect_client-3.1.12.dist-info}/LICENSE +0 -0
  140. {prefect_client-3.1.10.dist-info → prefect_client-3.1.12.dist-info}/WHEEL +0 -0
  141. {prefect_client-3.1.10.dist-info → prefect_client-3.1.12.dist-info}/top_level.txt +0 -0
@@ -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())
@@ -0,0 +1,200 @@
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 BlockSchemaCreate
14
+ from prefect.client.schemas.objects import BlockSchema
15
+
16
+
17
+ class BlocksSchemaClient(BaseClient):
18
+ def create_block_schema(self, block_schema: "BlockSchemaCreate") -> "BlockSchema":
19
+ """
20
+ Create a block schema in the Prefect API.
21
+ """
22
+ try:
23
+ response = self.request(
24
+ "POST",
25
+ "/block_schemas/",
26
+ json=block_schema.model_dump(
27
+ mode="json",
28
+ exclude_unset=True,
29
+ exclude={"id", "block_type", "checksum"},
30
+ ),
31
+ )
32
+ except HTTPStatusError as e:
33
+ if e.response.status_code == 409:
34
+ raise ObjectAlreadyExists(http_exc=e) from e
35
+ else:
36
+ raise
37
+ from prefect.client.schemas.objects import BlockSchema
38
+
39
+ return BlockSchema.model_validate(response.json())
40
+
41
+ def read_block_schema_by_checksum(
42
+ self, checksum: str, version: str | None = None
43
+ ) -> "BlockSchema":
44
+ """
45
+ Look up a block schema checksum
46
+ """
47
+ try:
48
+ response = self.request(
49
+ "GET",
50
+ "/block_schemas/checksum/{checksum}",
51
+ path_params={"checksum": checksum},
52
+ **({"params": {"version": version}} if version else {}),
53
+ )
54
+ except HTTPStatusError as e:
55
+ if e.response.status_code == 404:
56
+ raise ObjectNotFound(http_exc=e) from e
57
+ else:
58
+ raise
59
+ from prefect.client.schemas.objects import BlockSchema
60
+
61
+ return BlockSchema.model_validate(response.json())
62
+
63
+ def read_block_schemas(self) -> "list[BlockSchema]":
64
+ """
65
+ Read all block schemas
66
+ Raises:
67
+ httpx.RequestError: if a valid block schema was not found
68
+
69
+ Returns:
70
+ A BlockSchema.
71
+ """
72
+ response = self.request("POST", "/block_schemas/filter", json={})
73
+ from prefect.client.schemas.objects import BlockSchema
74
+
75
+ return BlockSchema.model_validate_list(response.json())
76
+
77
+ def get_most_recent_block_schema_for_block_type(
78
+ self,
79
+ block_type_id: "UUID",
80
+ ) -> "BlockSchema | None":
81
+ """
82
+ Fetches the most recent block schema for a specified block type ID.
83
+
84
+ Args:
85
+ block_type_id: The ID of the block type.
86
+
87
+ Raises:
88
+ httpx.RequestError: If the request fails for any reason.
89
+
90
+ Returns:
91
+ The most recent block schema or None.
92
+ """
93
+ try:
94
+ response = self.request(
95
+ "POST",
96
+ "/block_schemas/filter",
97
+ json={
98
+ "block_schemas": {"block_type_id": {"any_": [str(block_type_id)]}},
99
+ "limit": 1,
100
+ },
101
+ )
102
+ except HTTPStatusError:
103
+ raise
104
+ from prefect.client.schemas.objects import BlockSchema
105
+
106
+ return next(iter(BlockSchema.model_validate_list(response.json())), None)
107
+
108
+
109
+ class BlocksSchemaAsyncClient(BaseAsyncClient):
110
+ async def create_block_schema(
111
+ self, block_schema: "BlockSchemaCreate"
112
+ ) -> "BlockSchema":
113
+ """
114
+ Create a block schema in the Prefect API.
115
+ """
116
+ try:
117
+ response = await self.request(
118
+ "POST",
119
+ "/block_schemas/",
120
+ json=block_schema.model_dump(
121
+ mode="json",
122
+ exclude_unset=True,
123
+ exclude={"id", "block_type", "checksum"},
124
+ ),
125
+ )
126
+ except HTTPStatusError as e:
127
+ if e.response.status_code == 409:
128
+ raise ObjectAlreadyExists(http_exc=e) from e
129
+ else:
130
+ raise
131
+ from prefect.client.schemas.objects import BlockSchema
132
+
133
+ return BlockSchema.model_validate(response.json())
134
+
135
+ async def read_block_schema_by_checksum(
136
+ self, checksum: str, version: str | None = None
137
+ ) -> "BlockSchema":
138
+ """
139
+ Look up a block schema checksum
140
+ """
141
+ try:
142
+ response = await self.request(
143
+ "GET",
144
+ "/block_schemas/checksum/{checksum}",
145
+ path_params={"checksum": checksum},
146
+ **({"params": {"version": version}} if version else {}),
147
+ )
148
+ except HTTPStatusError as e:
149
+ if e.response.status_code == 404:
150
+ raise ObjectNotFound(http_exc=e) from e
151
+ else:
152
+ raise
153
+ from prefect.client.schemas.objects import BlockSchema
154
+
155
+ return BlockSchema.model_validate(response.json())
156
+
157
+ async def read_block_schemas(self) -> "list[BlockSchema]":
158
+ """
159
+ Read all block schemas
160
+ Raises:
161
+ httpx.RequestError: if a valid block schema was not found
162
+
163
+ Returns:
164
+ A BlockSchema.
165
+ """
166
+ response = await self.request("POST", "/block_schemas/filter", json={})
167
+ from prefect.client.schemas.objects import BlockSchema
168
+
169
+ return BlockSchema.model_validate_list(response.json())
170
+
171
+ async def get_most_recent_block_schema_for_block_type(
172
+ self,
173
+ block_type_id: "UUID",
174
+ ) -> "BlockSchema | None":
175
+ """
176
+ Fetches the most recent block schema for a specified block type ID.
177
+
178
+ Args:
179
+ block_type_id: The ID of the block type.
180
+
181
+ Raises:
182
+ httpx.RequestError: If the request fails for any reason.
183
+
184
+ Returns:
185
+ The most recent block schema or None.
186
+ """
187
+ try:
188
+ response = await self.request(
189
+ "POST",
190
+ "/block_schemas/filter",
191
+ json={
192
+ "block_schemas": {"block_type_id": {"any_": [str(block_type_id)]}},
193
+ "limit": 1,
194
+ },
195
+ )
196
+ except HTTPStatusError:
197
+ raise
198
+ from prefect.client.schemas.objects import BlockSchema
199
+
200
+ return next(iter(BlockSchema.model_validate_list(response.json())), None)
File without changes