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
prefect/_version.py CHANGED
@@ -8,11 +8,11 @@ import json
8
8
 
9
9
  version_json = '''
10
10
  {
11
- "date": "2024-12-24T22:58:40-0800",
11
+ "date": "2025-01-09T10:09:15-0800",
12
12
  "dirty": true,
13
13
  "error": null,
14
- "full-revisionid": "b11b56fc6143df2bd4c7018f7a974dc656fe9aa3",
15
- "version": "3.1.10"
14
+ "full-revisionid": "e299e5a781867735d62685e7c190b5d100a28b62",
15
+ "version": "3.1.12"
16
16
  }
17
17
  ''' # END VERSION_JSON
18
18
 
prefect/automations.py CHANGED
@@ -4,6 +4,7 @@ from uuid import UUID
4
4
  from pydantic import Field
5
5
  from typing_extensions import Self
6
6
 
7
+ from prefect._internal.compatibility.async_dispatch import async_dispatch
7
8
  from prefect.client.orchestration import get_client
8
9
  from prefect.events.actions import (
9
10
  CallWebhook,
@@ -39,7 +40,6 @@ from prefect.events.schemas.automations import (
39
40
  Trigger,
40
41
  )
41
42
  from prefect.exceptions import PrefectHTTPStatusError
42
- from prefect.utilities.asyncutils import sync_compatible
43
43
 
44
44
  __all__ = [
45
45
  "AutomationCore",
@@ -78,11 +78,13 @@ __all__ = [
78
78
  class Automation(AutomationCore):
79
79
  id: Optional[UUID] = Field(default=None, description="The ID of this automation")
80
80
 
81
- @sync_compatible
82
- async def create(self: Self) -> Self:
81
+ async def acreate(self: Self) -> Self:
83
82
  """
84
- Create a new automation.
83
+ Asynchronously create a new automation.
84
+
85
+ Examples:
85
86
 
87
+ ```python
86
88
  auto_to_create = Automation(
87
89
  name="woodchonk",
88
90
  trigger=EventTrigger(
@@ -97,20 +99,55 @@ class Automation(AutomationCore):
97
99
  ),
98
100
  actions=[CancelFlowRun()]
99
101
  )
100
- created_automation = auto_to_create.create()
102
+ created_automation = await auto_to_create.acreate()
103
+ ```
101
104
  """
102
105
  async with get_client() as client:
103
106
  automation = AutomationCore(**self.model_dump(exclude={"id"}))
104
107
  self.id = await client.create_automation(automation=automation)
105
108
  return self
106
109
 
107
- @sync_compatible
108
- async def update(self: Self):
110
+ @async_dispatch(acreate)
111
+ def create(self: Self) -> Self:
112
+ """
113
+ Create a new automation.
114
+
115
+ Examples:
116
+
117
+ ```python
118
+ auto_to_create = Automation(
119
+ name="woodchonk",
120
+ trigger=EventTrigger(
121
+ expect={"animal.walked"},
122
+ match={
123
+ "genus": "Marmota",
124
+ "species": "monax",
125
+ },
126
+ posture="Reactive",
127
+ threshold=3,
128
+ within=timedelta(seconds=10),
129
+ ),
130
+ actions=[CancelFlowRun()]
131
+ )
132
+ created_automation = auto_to_create.create()
133
+ ```
134
+ """
135
+ with get_client(sync_client=True) as client:
136
+ automation = AutomationCore(**self.model_dump(exclude={"id"}))
137
+ self.id = client.create_automation(automation=automation)
138
+ return self
139
+
140
+ async def aupdate(self: Self):
109
141
  """
110
142
  Updates an existing automation.
143
+
144
+ Examples:
145
+
146
+ ```python
111
147
  auto = Automation.read(id=123)
112
148
  auto.name = "new name"
113
149
  auto.update()
150
+ ```
114
151
  """
115
152
  assert self.id is not None
116
153
  async with get_client() as client:
@@ -119,28 +156,51 @@ class Automation(AutomationCore):
119
156
  )
120
157
  await client.update_automation(automation_id=self.id, automation=automation)
121
158
 
159
+ @async_dispatch(aupdate)
160
+ def update(self: Self):
161
+ """
162
+ Updates an existing automation.
163
+
164
+ Examples:
165
+
166
+
167
+ ```python
168
+ auto = Automation.read(id=123)
169
+ auto.name = "new name"
170
+ auto.update()
171
+ ```
172
+ """
173
+ assert self.id is not None
174
+ with get_client(sync_client=True) as client:
175
+ automation = AutomationCore(
176
+ **self.model_dump(exclude={"id", "owner_resource"})
177
+ )
178
+ client.update_automation(automation_id=self.id, automation=automation)
179
+
122
180
  @overload
123
181
  @classmethod
124
- async def read(cls, id: UUID, name: Optional[str] = ...) -> Self:
182
+ async def aread(cls, id: UUID, name: Optional[str] = ...) -> Self:
125
183
  ...
126
184
 
127
185
  @overload
128
186
  @classmethod
129
- async def read(cls, id: None = None, name: str = ...) -> Optional[Self]:
187
+ async def aread(cls, id: None = None, name: str = ...) -> Self:
130
188
  ...
131
189
 
132
190
  @classmethod
133
- @sync_compatible
134
- async def read(
135
- cls, id: Optional[UUID] = None, name: Optional[str] = None
136
- ) -> Optional[Self]:
191
+ async def aread(cls, id: Optional[UUID] = None, name: Optional[str] = None) -> Self:
137
192
  """
138
- Read an automation by ID or name.
139
- automation = Automation.read(name="woodchonk")
193
+ Asynchronously read an automation by ID or name.
140
194
 
141
- or
195
+ Examples:
142
196
 
143
- automation = Automation.read(id=UUID("b3514963-02b1-47a5-93d1-6eeb131041cb"))
197
+ ```python
198
+ automation = await Automation.aread(name="woodchonk")
199
+ ```
200
+
201
+ ```python
202
+ automation = await Automation.aread(id=UUID("b3514963-02b1-47a5-93d1-6eeb131041cb"))
203
+ ```
144
204
  """
145
205
  if id and name:
146
206
  raise ValueError("Only one of id or name can be provided")
@@ -162,15 +222,68 @@ class Automation(AutomationCore):
162
222
  assert name is not None
163
223
  automation = await client.read_automations_by_name(name=name)
164
224
  if len(automation) > 0:
165
- return cls(**automation[0].model_dump()) if automation else None
166
- else:
167
- raise ValueError(f"Automation with name {name!r} not found")
225
+ return cls(**automation[0].model_dump())
226
+ raise ValueError(f"Automation with name {name!r} not found")
168
227
 
169
- @sync_compatible
170
- async def delete(self: Self) -> bool:
228
+ @overload
229
+ @classmethod
230
+ async def read(cls, id: UUID, name: Optional[str] = ...) -> Self:
231
+ ...
232
+
233
+ @overload
234
+ @classmethod
235
+ async def read(cls, id: None = None, name: str = ...) -> Self:
236
+ ...
237
+
238
+ @classmethod
239
+ @async_dispatch(aread)
240
+ def read(cls, id: Optional[UUID] = None, name: Optional[str] = None) -> Self:
171
241
  """
242
+ Read an automation by ID or name.
243
+
244
+ Examples:
245
+
246
+ ```python
247
+ automation = Automation.read(name="woodchonk")
248
+ ```
249
+
250
+ ```python
251
+ automation = Automation.read(id=UUID("b3514963-02b1-47a5-93d1-6eeb131041cb"))
252
+ ```
253
+ """
254
+ if id and name:
255
+ raise ValueError("Only one of id or name can be provided")
256
+ if not id and not name:
257
+ raise ValueError("One of id or name must be provided")
258
+ with get_client(sync_client=True) as client:
259
+ if id:
260
+ try:
261
+ automation = client.read_automation(automation_id=id)
262
+ except PrefectHTTPStatusError as exc:
263
+ if exc.response.status_code == 404:
264
+ raise ValueError(f"Automation with ID {id!r} not found")
265
+ raise
266
+ if automation is None:
267
+ raise ValueError(f"Automation with ID {id!r} not found")
268
+ return cls(**automation.model_dump())
269
+ else:
270
+ if TYPE_CHECKING:
271
+ assert name is not None
272
+ automation = client.read_automations_by_name(name=name)
273
+ if len(automation) > 0:
274
+ return cls(**automation[0].model_dump())
275
+ raise ValueError(f"Automation with name {name!r} not found")
276
+
277
+ async def adelete(self: Self) -> bool:
278
+ """
279
+ Asynchronously delete an automation.
280
+
281
+ Examples:
282
+
283
+ ```python
172
284
  auto = Automation.read(id = 123)
173
- auto.delete()
285
+ await auto.adelete()
286
+ ```
174
287
  """
175
288
  if self.id is None:
176
289
  raise ValueError("Can't delete an automation without an id")
@@ -184,38 +297,131 @@ class Automation(AutomationCore):
184
297
  return False
185
298
  raise
186
299
 
187
- @sync_compatible
188
- async def disable(self: Self) -> bool:
300
+ @async_dispatch(adelete)
301
+ def delete(self: Self) -> bool:
302
+ """
303
+ Delete an automation.
304
+
305
+ Examples:
306
+
307
+ ```python
308
+ auto = Automation.read(id = 123)
309
+ auto.delete()
310
+ ```
311
+ """
312
+ if self.id is None:
313
+ raise ValueError("Can't delete an automation without an id")
314
+
315
+ with get_client(sync_client=True) as client:
316
+ try:
317
+ client.delete_automation(self.id)
318
+ return True
319
+ except PrefectHTTPStatusError as exc:
320
+ if exc.response.status_code == 404:
321
+ return False
322
+ raise
323
+
324
+ async def adisable(self: Self) -> bool:
325
+ """
326
+ Asynchronously disable an automation.
327
+
328
+ Raises:
329
+ ValueError: If the automation does not have an id
330
+ PrefectHTTPStatusError: If the automation cannot be disabled
331
+
332
+ Example:
333
+ ```python
334
+ auto = await Automation.aread(id = 123)
335
+ await auto.adisable()
336
+ ```
337
+ """
338
+ if self.id is None:
339
+ raise ValueError("Can't disable an automation without an id")
340
+
341
+ async with get_client() as client:
342
+ try:
343
+ await client.pause_automation(self.id)
344
+ return True
345
+ except PrefectHTTPStatusError as exc:
346
+ if exc.response.status_code == 404:
347
+ return False
348
+ raise
349
+
350
+ @async_dispatch(adisable)
351
+ def disable(self: Self) -> bool:
189
352
  """
190
353
  Disable an automation.
354
+
355
+
356
+ Raises:
357
+ ValueError: If the automation does not have an id
358
+ PrefectHTTPStatusError: If the automation cannot be disabled
359
+
360
+ Example:
361
+ ```python
191
362
  auto = Automation.read(id = 123)
192
363
  auto.disable()
364
+ ```
193
365
  """
194
366
  if self.id is None:
195
367
  raise ValueError("Can't disable an automation without an id")
196
368
 
369
+ with get_client(sync_client=True) as client:
370
+ try:
371
+ client.pause_automation(self.id)
372
+ return True
373
+ except PrefectHTTPStatusError as exc:
374
+ if exc.response.status_code == 404:
375
+ return False
376
+ raise
377
+
378
+ async def aenable(self: Self) -> bool:
379
+ """
380
+ Asynchronously enable an automation.
381
+
382
+ Raises:
383
+ ValueError: If the automation does not have an id
384
+ PrefectHTTPStatusError: If the automation cannot be enabled
385
+
386
+ Example:
387
+ ```python
388
+ auto = await Automation.aread(id = 123)
389
+ await auto.aenable()
390
+ ```
391
+ """
392
+ if self.id is None:
393
+ raise ValueError("Can't enable an automation without an id")
394
+
197
395
  async with get_client() as client:
198
396
  try:
199
- await client.pause_automation(self.id)
397
+ await client.resume_automation(self.id)
200
398
  return True
201
399
  except PrefectHTTPStatusError as exc:
202
400
  if exc.response.status_code == 404:
203
401
  return False
204
402
  raise
205
403
 
206
- @sync_compatible
207
- async def enable(self: Self) -> bool:
404
+ @async_dispatch(aenable)
405
+ def enable(self: Self) -> bool:
208
406
  """
209
407
  Enable an automation.
408
+
409
+ Raises:
410
+ ValueError: If the automation does not have an id
411
+ PrefectHTTPStatusError: If the automation cannot be enabled
412
+
413
+ Example:
414
+ ```python
210
415
  auto = Automation.read(id = 123)
211
416
  auto.enable()
417
+ ```
212
418
  """
213
419
  if self.id is None:
214
420
  raise ValueError("Can't enable an automation without an id")
215
421
 
216
- async with get_client() as client:
422
+ with get_client(sync_client=True) as client:
217
423
  try:
218
- await client.resume_automation(self.id)
424
+ client.resume_automation(self.id)
219
425
  return True
220
426
  except PrefectHTTPStatusError as exc:
221
427
  if exc.response.status_code == 404:
@@ -1,7 +1,7 @@
1
1
  # ensure core blocks are registered
2
2
 
3
- import prefect.blocks.notifications
4
- import prefect.blocks.system
5
- import prefect.blocks.webhook
3
+ import prefect.blocks.notifications as notifications
4
+ import prefect.blocks.system as system
5
+ import prefect.blocks.webhook as webhook
6
6
 
7
7
  __all__ = ["notifications", "system", "webhook"]
@@ -1,16 +1,16 @@
1
+ from __future__ import annotations
2
+
3
+ import logging
4
+ import sys
1
5
  from abc import ABC, abstractmethod
2
6
  from contextlib import contextmanager
3
- from logging import Logger, LoggerAdapter
7
+ from logging import Logger
4
8
  from pathlib import Path
5
9
  from typing import (
6
10
  Any,
7
11
  BinaryIO,
8
- Dict,
9
12
  Generator,
10
13
  Generic,
11
- List,
12
- Optional,
13
- Tuple,
14
14
  TypeVar,
15
15
  Union,
16
16
  )
@@ -23,7 +23,12 @@ from prefect.logging.loggers import get_logger, get_run_logger
23
23
 
24
24
  T = TypeVar("T")
25
25
 
26
- LoggerOrAdapter: TypeAlias = Union[Logger, LoggerAdapter]
26
+ if sys.version_info >= (3, 12):
27
+ LoggingAdapter = logging.LoggerAdapter[logging.Logger]
28
+ else:
29
+ LoggingAdapter = logging.LoggerAdapter
30
+
31
+ LoggerOrAdapter: TypeAlias = Union[Logger, LoggingAdapter]
27
32
 
28
33
 
29
34
  class CredentialsBlock(Block, ABC):
@@ -52,7 +57,7 @@ class CredentialsBlock(Block, ABC):
52
57
  return get_logger(self.__class__.__name__)
53
58
 
54
59
  @abstractmethod
55
- def get_client(self, *args, **kwargs):
60
+ def get_client(self, *args: Any, **kwargs: Any) -> Any:
56
61
  """
57
62
  Returns a client for interacting with the external system.
58
63
 
@@ -94,7 +99,7 @@ class NotificationBlock(Block, ABC):
94
99
  return get_logger(self.__class__.__name__)
95
100
 
96
101
  @abstractmethod
97
- async def notify(self, body: str, subject: Optional[str] = None) -> None:
102
+ async def notify(self, body: str, subject: str | None = None) -> None:
98
103
  """
99
104
  Send a notification.
100
105
 
@@ -153,7 +158,7 @@ class JobRun(ABC, Generic[T]): # not a block
153
158
  """
154
159
 
155
160
 
156
- class JobBlock(Block, ABC):
161
+ class JobBlock(Block, ABC, Generic[T]):
157
162
  """
158
163
  Block that represents an entity in an external service
159
164
  that can trigger a long running execution.
@@ -176,7 +181,7 @@ class JobBlock(Block, ABC):
176
181
  return get_logger(self.__class__.__name__)
177
182
 
178
183
  @abstractmethod
179
- async def trigger(self) -> JobRun:
184
+ async def trigger(self) -> JobRun[T]:
180
185
  """
181
186
  Triggers a job run in an external service and returns a JobRun object
182
187
  to track the execution of the run.
@@ -221,8 +226,11 @@ class DatabaseBlock(Block, ABC):
221
226
 
222
227
  @abstractmethod
223
228
  async def fetch_one(
224
- self, operation, parameters=None, **execution_kwargs
225
- ) -> Tuple[Any]:
229
+ self,
230
+ operation: str,
231
+ parameters: dict[str, Any] | None = None,
232
+ **execution_kwargs: Any,
233
+ ) -> tuple[Any, ...]:
226
234
  """
227
235
  Fetch a single result from the database.
228
236
 
@@ -238,8 +246,12 @@ class DatabaseBlock(Block, ABC):
238
246
 
239
247
  @abstractmethod
240
248
  async def fetch_many(
241
- self, operation, parameters=None, size=None, **execution_kwargs
242
- ) -> List[Tuple[Any]]:
249
+ self,
250
+ operation: str,
251
+ parameters: dict[str, Any] | None = None,
252
+ size: int | None = None,
253
+ **execution_kwargs: Any,
254
+ ) -> list[tuple[Any, ...]]:
243
255
  """
244
256
  Fetch a limited number of results from the database.
245
257
 
@@ -256,8 +268,11 @@ class DatabaseBlock(Block, ABC):
256
268
 
257
269
  @abstractmethod
258
270
  async def fetch_all(
259
- self, operation, parameters=None, **execution_kwargs
260
- ) -> List[Tuple[Any]]:
271
+ self,
272
+ operation: str,
273
+ parameters: dict[str, Any] | None = None,
274
+ **execution_kwargs: Any,
275
+ ) -> list[tuple[Any, ...]]:
261
276
  """
262
277
  Fetch all results from the database.
263
278
 
@@ -272,7 +287,12 @@ class DatabaseBlock(Block, ABC):
272
287
  """
273
288
 
274
289
  @abstractmethod
275
- async def execute(self, operation, parameters=None, **execution_kwargs) -> None:
290
+ async def execute(
291
+ self,
292
+ operation: str,
293
+ parameters: dict[str, Any] | None = None,
294
+ **execution_kwargs: Any,
295
+ ) -> None:
276
296
  """
277
297
  Executes an operation on the database. This method is intended to be used
278
298
  for operations that do not return data, such as INSERT, UPDATE, or DELETE.
@@ -285,7 +305,10 @@ class DatabaseBlock(Block, ABC):
285
305
 
286
306
  @abstractmethod
287
307
  async def execute_many(
288
- self, operation, seq_of_parameters, **execution_kwargs
308
+ self,
309
+ operation: str,
310
+ seq_of_parameters: list[dict[str, Any]],
311
+ **execution_kwargs: Any,
289
312
  ) -> None:
290
313
  """
291
314
  Executes multiple operations on the database. This method is intended to be used
@@ -307,7 +330,7 @@ class DatabaseBlock(Block, ABC):
307
330
  f"{self.__class__.__name__} does not support async context management."
308
331
  )
309
332
 
310
- async def __aexit__(self, *args) -> None:
333
+ async def __aexit__(self, *args: Any) -> None:
311
334
  """
312
335
  Context management method for async databases.
313
336
  """
@@ -323,7 +346,7 @@ class DatabaseBlock(Block, ABC):
323
346
  f"{self.__class__.__name__} does not support context management."
324
347
  )
325
348
 
326
- def __exit__(self, *args) -> None:
349
+ def __exit__(self, *args: Any) -> None:
327
350
  """
328
351
  Context management method for databases.
329
352
  """
@@ -358,8 +381,8 @@ class ObjectStorageBlock(Block, ABC):
358
381
  async def download_object_to_path(
359
382
  self,
360
383
  from_path: str,
361
- to_path: Union[str, Path],
362
- **download_kwargs: Dict[str, Any],
384
+ to_path: str | Path,
385
+ **download_kwargs: Any,
363
386
  ) -> Path:
364
387
  """
365
388
  Downloads an object from the object storage service to a path.
@@ -378,7 +401,7 @@ class ObjectStorageBlock(Block, ABC):
378
401
  self,
379
402
  from_path: str,
380
403
  to_file_object: BinaryIO,
381
- **download_kwargs: Dict[str, Any],
404
+ **download_kwargs: Any,
382
405
  ) -> BinaryIO:
383
406
  """
384
407
  Downloads an object from the object storage service to a file-like object,
@@ -397,8 +420,8 @@ class ObjectStorageBlock(Block, ABC):
397
420
  async def download_folder_to_path(
398
421
  self,
399
422
  from_folder: str,
400
- to_folder: Union[str, Path],
401
- **download_kwargs: Dict[str, Any],
423
+ to_folder: str | Path,
424
+ **download_kwargs: Any,
402
425
  ) -> Path:
403
426
  """
404
427
  Downloads a folder from the object storage service to a path.
@@ -414,7 +437,7 @@ class ObjectStorageBlock(Block, ABC):
414
437
 
415
438
  @abstractmethod
416
439
  async def upload_from_path(
417
- self, from_path: Union[str, Path], to_path: str, **upload_kwargs: Dict[str, Any]
440
+ self, from_path: str | Path, to_path: str, **upload_kwargs: Any
418
441
  ) -> str:
419
442
  """
420
443
  Uploads an object from a path to the object storage service.
@@ -430,7 +453,7 @@ class ObjectStorageBlock(Block, ABC):
430
453
 
431
454
  @abstractmethod
432
455
  async def upload_from_file_object(
433
- self, from_file_object: BinaryIO, to_path: str, **upload_kwargs: Dict[str, Any]
456
+ self, from_file_object: BinaryIO, to_path: str, **upload_kwargs: Any
434
457
  ) -> str:
435
458
  """
436
459
  Uploads an object to the object storage service from a file-like object,
@@ -448,9 +471,9 @@ class ObjectStorageBlock(Block, ABC):
448
471
  @abstractmethod
449
472
  async def upload_from_folder(
450
473
  self,
451
- from_folder: Union[str, Path],
474
+ from_folder: str | Path,
452
475
  to_folder: str,
453
- **upload_kwargs: Dict[str, Any],
476
+ **upload_kwargs: Any,
454
477
  ) -> str:
455
478
  """
456
479
  Uploads a folder to the object storage service from a path.
@@ -496,7 +519,7 @@ class SecretBlock(Block, ABC):
496
519
  """
497
520
 
498
521
  @abstractmethod
499
- async def write_secret(self, secret_data) -> str:
522
+ async def write_secret(self, secret_data: bytes) -> str:
500
523
  """
501
524
  Writes secret data to the configured secret in the secret storage service.
502
525