prefect-client 3.0.0rc20__py3-none-any.whl → 3.0.1__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/_internal/compatibility/migration.py +1 -1
- prefect/artifacts.py +1 -1
- prefect/blocks/core.py +3 -4
- prefect/blocks/notifications.py +10 -10
- prefect/blocks/system.py +4 -4
- prefect/blocks/webhook.py +3 -1
- prefect/client/cloud.py +2 -1
- prefect/client/orchestration.py +54 -1
- prefect/context.py +7 -9
- prefect/deployments/runner.py +3 -3
- prefect/exceptions.py +6 -0
- prefect/filesystems.py +5 -3
- prefect/flow_engine.py +13 -10
- prefect/flows.py +0 -2
- prefect/futures.py +2 -1
- prefect/locking/__init__.py +0 -0
- prefect/locking/memory.py +213 -0
- prefect/locking/protocol.py +122 -0
- prefect/records/filesystem.py +4 -2
- prefect/records/result_store.py +12 -6
- prefect/results.py +559 -206
- prefect/settings.py +10 -3
- prefect/states.py +12 -12
- prefect/task_engine.py +28 -20
- prefect/task_worker.py +6 -4
- prefect/tasks.py +24 -6
- prefect/transactions.py +35 -28
- prefect/utilities/callables.py +1 -3
- prefect/variables.py +34 -24
- prefect/workers/process.py +1 -3
- {prefect_client-3.0.0rc20.dist-info → prefect_client-3.0.1.dist-info}/METADATA +2 -2
- {prefect_client-3.0.0rc20.dist-info → prefect_client-3.0.1.dist-info}/RECORD +35 -32
- {prefect_client-3.0.0rc20.dist-info → prefect_client-3.0.1.dist-info}/LICENSE +0 -0
- {prefect_client-3.0.0rc20.dist-info → prefect_client-3.0.1.dist-info}/WHEEL +0 -0
- {prefect_client-3.0.0rc20.dist-info → prefect_client-3.0.1.dist-info}/top_level.txt +0 -0
prefect/settings.py
CHANGED
@@ -2191,13 +2191,20 @@ def _write_profiles_to(path: Path, profiles: ProfilesCollection) -> None:
|
|
2191
2191
|
return path.write_text(toml.dumps(profiles.to_dict()))
|
2192
2192
|
|
2193
2193
|
|
2194
|
-
def load_profiles() -> ProfilesCollection:
|
2194
|
+
def load_profiles(include_defaults: bool = True) -> ProfilesCollection:
|
2195
2195
|
"""
|
2196
|
-
Load
|
2196
|
+
Load profiles from the current profile path. Optionally include profiles from the
|
2197
|
+
default profile path.
|
2197
2198
|
"""
|
2198
|
-
|
2199
|
+
default_profiles = _read_profiles_from(DEFAULT_PROFILES_PATH)
|
2200
|
+
|
2201
|
+
if not include_defaults:
|
2202
|
+
if not PREFECT_PROFILES_PATH.value().exists():
|
2203
|
+
return ProfilesCollection([])
|
2204
|
+
return _read_profiles_from(PREFECT_PROFILES_PATH.value())
|
2199
2205
|
|
2200
2206
|
user_profiles_path = PREFECT_PROFILES_PATH.value()
|
2207
|
+
profiles = default_profiles
|
2201
2208
|
if user_profiles_path.exists():
|
2202
2209
|
user_profiles = _read_profiles_from(user_profiles_path)
|
2203
2210
|
|
prefect/states.py
CHANGED
@@ -25,7 +25,7 @@ from prefect.exceptions import (
|
|
25
25
|
UnfinishedRun,
|
26
26
|
)
|
27
27
|
from prefect.logging.loggers import get_logger, get_run_logger
|
28
|
-
from prefect.results import BaseResult, R,
|
28
|
+
from prefect.results import BaseResult, R, ResultStore
|
29
29
|
from prefect.settings import PREFECT_ASYNC_FETCH_STATE_RESULT
|
30
30
|
from prefect.utilities.annotations import BaseAnnotation
|
31
31
|
from prefect.utilities.asyncutils import in_async_main_thread, sync_compatible
|
@@ -167,7 +167,7 @@ def format_exception(exc: BaseException, tb: TracebackType = None) -> str:
|
|
167
167
|
|
168
168
|
async def exception_to_crashed_state(
|
169
169
|
exc: BaseException,
|
170
|
-
|
170
|
+
result_store: Optional[ResultStore] = None,
|
171
171
|
) -> State:
|
172
172
|
"""
|
173
173
|
Takes an exception that occurs _outside_ of user code and converts it to a
|
@@ -206,8 +206,8 @@ async def exception_to_crashed_state(
|
|
206
206
|
f" {format_exception(exc)}"
|
207
207
|
)
|
208
208
|
|
209
|
-
if
|
210
|
-
data = await
|
209
|
+
if result_store:
|
210
|
+
data = await result_store.create_result(exc)
|
211
211
|
else:
|
212
212
|
# Attach the exception for local usage, will not be available when retrieved
|
213
213
|
# from the API
|
@@ -218,7 +218,7 @@ async def exception_to_crashed_state(
|
|
218
218
|
|
219
219
|
async def exception_to_failed_state(
|
220
220
|
exc: Optional[BaseException] = None,
|
221
|
-
|
221
|
+
result_store: Optional[ResultStore] = None,
|
222
222
|
write_result: bool = False,
|
223
223
|
**kwargs,
|
224
224
|
) -> State:
|
@@ -239,8 +239,8 @@ async def exception_to_failed_state(
|
|
239
239
|
else:
|
240
240
|
pass
|
241
241
|
|
242
|
-
if
|
243
|
-
data = await
|
242
|
+
if result_store:
|
243
|
+
data = await result_store.create_result(exc)
|
244
244
|
if write_result:
|
245
245
|
try:
|
246
246
|
await data.write()
|
@@ -270,7 +270,7 @@ async def exception_to_failed_state(
|
|
270
270
|
|
271
271
|
async def return_value_to_state(
|
272
272
|
retval: R,
|
273
|
-
|
273
|
+
result_store: ResultStore,
|
274
274
|
key: Optional[str] = None,
|
275
275
|
expiration: Optional[datetime.datetime] = None,
|
276
276
|
write_result: bool = False,
|
@@ -307,10 +307,10 @@ async def return_value_to_state(
|
|
307
307
|
and not retval.state_details.task_run_id
|
308
308
|
):
|
309
309
|
state = retval
|
310
|
-
# Unless the user has already constructed a result explicitly, use the
|
310
|
+
# Unless the user has already constructed a result explicitly, use the store
|
311
311
|
# to update the data to the correct type
|
312
312
|
if not isinstance(state.data, BaseResult):
|
313
|
-
result = await
|
313
|
+
result = await result_store.create_result(
|
314
314
|
state.data,
|
315
315
|
key=key,
|
316
316
|
expiration=expiration,
|
@@ -359,7 +359,7 @@ async def return_value_to_state(
|
|
359
359
|
# TODO: We may actually want to set the data to a `StateGroup` object and just
|
360
360
|
# allow it to be unpacked into a tuple and such so users can interact with
|
361
361
|
# it
|
362
|
-
result = await
|
362
|
+
result = await result_store.create_result(
|
363
363
|
retval,
|
364
364
|
key=key,
|
365
365
|
expiration=expiration,
|
@@ -388,7 +388,7 @@ async def return_value_to_state(
|
|
388
388
|
if isinstance(data, BaseResult):
|
389
389
|
return Completed(data=data)
|
390
390
|
else:
|
391
|
-
result = await
|
391
|
+
result = await result_store.create_result(
|
392
392
|
data,
|
393
393
|
key=key,
|
394
394
|
expiration=expiration,
|
prefect/task_engine.py
CHANGED
@@ -55,8 +55,12 @@ from prefect.exceptions import (
|
|
55
55
|
)
|
56
56
|
from prefect.futures import PrefectFuture
|
57
57
|
from prefect.logging.loggers import get_logger, patch_print, task_run_logger
|
58
|
-
from prefect.records.result_store import
|
59
|
-
from prefect.results import
|
58
|
+
from prefect.records.result_store import ResultRecordStore
|
59
|
+
from prefect.results import (
|
60
|
+
BaseResult,
|
61
|
+
_format_user_supplied_storage_key,
|
62
|
+
get_current_result_store,
|
63
|
+
)
|
60
64
|
from prefect.settings import (
|
61
65
|
PREFECT_DEBUG_MODE,
|
62
66
|
PREFECT_TASKS_REFRESH_CACHE,
|
@@ -450,9 +454,9 @@ class SyncTaskRunEngine(BaseTaskRunEngine[P, R]):
|
|
450
454
|
return self._raised
|
451
455
|
|
452
456
|
def handle_success(self, result: R, transaction: Transaction) -> R:
|
453
|
-
|
454
|
-
if
|
455
|
-
raise ValueError("Result
|
457
|
+
result_store = getattr(TaskRunContext.get(), "result_store", None)
|
458
|
+
if result_store is None:
|
459
|
+
raise ValueError("Result store is not set")
|
456
460
|
|
457
461
|
if self.task.cache_expiration is not None:
|
458
462
|
expiration = pendulum.now("utc") + self.task.cache_expiration
|
@@ -462,7 +466,7 @@ class SyncTaskRunEngine(BaseTaskRunEngine[P, R]):
|
|
462
466
|
terminal_state = run_coro_as_sync(
|
463
467
|
return_value_to_state(
|
464
468
|
result,
|
465
|
-
|
469
|
+
result_store=result_store,
|
466
470
|
key=transaction.key,
|
467
471
|
expiration=expiration,
|
468
472
|
)
|
@@ -539,7 +543,7 @@ class SyncTaskRunEngine(BaseTaskRunEngine[P, R]):
|
|
539
543
|
exception_to_failed_state(
|
540
544
|
exc,
|
541
545
|
message="Task run encountered an exception",
|
542
|
-
|
546
|
+
result_store=getattr(context, "result_store", None),
|
543
547
|
write_result=True,
|
544
548
|
)
|
545
549
|
)
|
@@ -591,7 +595,9 @@ class SyncTaskRunEngine(BaseTaskRunEngine[P, R]):
|
|
591
595
|
log_prints=log_prints,
|
592
596
|
task_run=self.task_run,
|
593
597
|
parameters=self.parameters,
|
594
|
-
|
598
|
+
result_store=get_current_result_store().update_for_task(
|
599
|
+
self.task, _sync=True
|
600
|
+
),
|
595
601
|
client=client,
|
596
602
|
)
|
597
603
|
)
|
@@ -717,9 +723,9 @@ class SyncTaskRunEngine(BaseTaskRunEngine[P, R]):
|
|
717
723
|
else PREFECT_TASKS_REFRESH_CACHE.value()
|
718
724
|
)
|
719
725
|
|
720
|
-
|
721
|
-
if
|
722
|
-
store =
|
726
|
+
result_store = getattr(TaskRunContext.get(), "result_store", None)
|
727
|
+
if result_store and result_store.persist_result:
|
728
|
+
store = ResultRecordStore(result_store=result_store)
|
723
729
|
else:
|
724
730
|
store = None
|
725
731
|
|
@@ -960,9 +966,9 @@ class AsyncTaskRunEngine(BaseTaskRunEngine[P, R]):
|
|
960
966
|
return self._raised
|
961
967
|
|
962
968
|
async def handle_success(self, result: R, transaction: Transaction) -> R:
|
963
|
-
|
964
|
-
if
|
965
|
-
raise ValueError("Result
|
969
|
+
result_store = getattr(TaskRunContext.get(), "result_store", None)
|
970
|
+
if result_store is None:
|
971
|
+
raise ValueError("Result store is not set")
|
966
972
|
|
967
973
|
if self.task.cache_expiration is not None:
|
968
974
|
expiration = pendulum.now("utc") + self.task.cache_expiration
|
@@ -971,7 +977,7 @@ class AsyncTaskRunEngine(BaseTaskRunEngine[P, R]):
|
|
971
977
|
|
972
978
|
terminal_state = await return_value_to_state(
|
973
979
|
result,
|
974
|
-
|
980
|
+
result_store=result_store,
|
975
981
|
key=transaction.key,
|
976
982
|
expiration=expiration,
|
977
983
|
)
|
@@ -1046,7 +1052,7 @@ class AsyncTaskRunEngine(BaseTaskRunEngine[P, R]):
|
|
1046
1052
|
state = await exception_to_failed_state(
|
1047
1053
|
exc,
|
1048
1054
|
message="Task run encountered an exception",
|
1049
|
-
|
1055
|
+
result_store=getattr(context, "result_store", None),
|
1050
1056
|
)
|
1051
1057
|
self.record_terminal_state_timing(state)
|
1052
1058
|
await self.set_state(state)
|
@@ -1096,7 +1102,9 @@ class AsyncTaskRunEngine(BaseTaskRunEngine[P, R]):
|
|
1096
1102
|
log_prints=log_prints,
|
1097
1103
|
task_run=self.task_run,
|
1098
1104
|
parameters=self.parameters,
|
1099
|
-
|
1105
|
+
result_store=await get_current_result_store().update_for_task(
|
1106
|
+
self.task, _sync=False
|
1107
|
+
),
|
1100
1108
|
client=client,
|
1101
1109
|
)
|
1102
1110
|
)
|
@@ -1218,9 +1226,9 @@ class AsyncTaskRunEngine(BaseTaskRunEngine[P, R]):
|
|
1218
1226
|
if self.task.refresh_cache is not None
|
1219
1227
|
else PREFECT_TASKS_REFRESH_CACHE.value()
|
1220
1228
|
)
|
1221
|
-
|
1222
|
-
if
|
1223
|
-
store =
|
1229
|
+
result_store = getattr(TaskRunContext.get(), "result_store", None)
|
1230
|
+
if result_store and result_store.persist_result:
|
1231
|
+
store = ResultRecordStore(result_store=result_store)
|
1224
1232
|
else:
|
1225
1233
|
store = None
|
1226
1234
|
|
prefect/task_worker.py
CHANGED
@@ -25,7 +25,7 @@ from prefect.client.orchestration import get_client
|
|
25
25
|
from prefect.client.schemas.objects import TaskRun
|
26
26
|
from prefect.client.subscriptions import Subscription
|
27
27
|
from prefect.logging.loggers import get_logger
|
28
|
-
from prefect.results import
|
28
|
+
from prefect.results import ResultStore, get_or_create_default_task_scheduling_storage
|
29
29
|
from prefect.settings import (
|
30
30
|
PREFECT_API_URL,
|
31
31
|
PREFECT_TASK_SCHEDULING_DELETE_FAILED_SUBMISSIONS,
|
@@ -49,7 +49,7 @@ class StopTaskWorker(Exception):
|
|
49
49
|
|
50
50
|
|
51
51
|
def should_try_to_read_parameters(task: Task, task_run: TaskRun) -> bool:
|
52
|
-
"""Determines whether a task run should read parameters from the result
|
52
|
+
"""Determines whether a task run should read parameters from the result store."""
|
53
53
|
new_enough_state_details = hasattr(
|
54
54
|
task_run.state.state_details, "task_parameters_id"
|
55
55
|
)
|
@@ -273,9 +273,11 @@ class TaskWorker:
|
|
273
273
|
if should_try_to_read_parameters(task, task_run):
|
274
274
|
parameters_id = task_run.state.state_details.task_parameters_id
|
275
275
|
task.persist_result = True
|
276
|
-
|
276
|
+
store = await ResultStore(
|
277
|
+
result_storage=await get_or_create_default_task_scheduling_storage()
|
278
|
+
).update_for_task(task)
|
277
279
|
try:
|
278
|
-
run_data = await
|
280
|
+
run_data = await store.read_parameters(parameters_id)
|
279
281
|
parameters = run_data.get("parameters", {})
|
280
282
|
wait_for = run_data.get("wait_for", [])
|
281
283
|
run_context = run_data.get("context", None)
|
prefect/tasks.py
CHANGED
@@ -50,7 +50,12 @@ from prefect.context import (
|
|
50
50
|
)
|
51
51
|
from prefect.futures import PrefectDistributedFuture, PrefectFuture, PrefectFutureList
|
52
52
|
from prefect.logging.loggers import get_logger
|
53
|
-
from prefect.results import
|
53
|
+
from prefect.results import (
|
54
|
+
ResultSerializer,
|
55
|
+
ResultStorage,
|
56
|
+
ResultStore,
|
57
|
+
get_or_create_default_task_scheduling_storage,
|
58
|
+
)
|
54
59
|
from prefect.settings import (
|
55
60
|
PREFECT_TASK_DEFAULT_RETRIES,
|
56
61
|
PREFECT_TASK_DEFAULT_RETRY_DELAY_SECONDS,
|
@@ -201,8 +206,17 @@ def _generate_task_key(fn: Callable[..., Any]) -> str:
|
|
201
206
|
|
202
207
|
qualname = fn.__qualname__.split(".")[-1]
|
203
208
|
|
209
|
+
try:
|
210
|
+
code_obj = getattr(fn, "__code__", None)
|
211
|
+
if code_obj is None:
|
212
|
+
code_obj = fn.__call__.__code__
|
213
|
+
except AttributeError:
|
214
|
+
raise AttributeError(
|
215
|
+
f"{fn} is not a standard Python function object and could not be converted to a task."
|
216
|
+
) from None
|
217
|
+
|
204
218
|
code_hash = (
|
205
|
-
h[:NUM_CHARS_DYNAMIC_KEY] if (h := hash_objects(
|
219
|
+
h[:NUM_CHARS_DYNAMIC_KEY] if (h := hash_objects(code_obj)) else "unknown"
|
206
220
|
)
|
207
221
|
|
208
222
|
return f"{qualname}-{code_hash}"
|
@@ -752,14 +766,16 @@ class Task(Generic[P, R]):
|
|
752
766
|
# TODO: Improve use of result storage for parameter storage / reference
|
753
767
|
self.persist_result = True
|
754
768
|
|
755
|
-
|
769
|
+
store = await ResultStore(
|
770
|
+
result_storage=await get_or_create_default_task_scheduling_storage()
|
771
|
+
).update_for_task(self)
|
756
772
|
context = serialize_context()
|
757
773
|
data: Dict[str, Any] = {"context": context}
|
758
774
|
if parameters:
|
759
775
|
data["parameters"] = parameters
|
760
776
|
if wait_for:
|
761
777
|
data["wait_for"] = wait_for
|
762
|
-
await
|
778
|
+
await store.store_parameters(parameters_id, data)
|
763
779
|
|
764
780
|
# collect task inputs
|
765
781
|
task_inputs = {
|
@@ -853,14 +869,16 @@ class Task(Generic[P, R]):
|
|
853
869
|
# TODO: Improve use of result storage for parameter storage / reference
|
854
870
|
self.persist_result = True
|
855
871
|
|
856
|
-
|
872
|
+
store = await ResultStore(
|
873
|
+
result_storage=await get_or_create_default_task_scheduling_storage()
|
874
|
+
).update_for_task(task)
|
857
875
|
context = serialize_context()
|
858
876
|
data: Dict[str, Any] = {"context": context}
|
859
877
|
if parameters:
|
860
878
|
data["parameters"] = parameters
|
861
879
|
if wait_for:
|
862
880
|
data["wait_for"] = wait_for
|
863
|
-
await
|
881
|
+
await store.store_parameters(parameters_id, data)
|
864
882
|
|
865
883
|
# collect task inputs
|
866
884
|
task_inputs = {
|
prefect/transactions.py
CHANGED
@@ -17,17 +17,13 @@ from typing import (
|
|
17
17
|
from pydantic import Field, PrivateAttr
|
18
18
|
from typing_extensions import Self
|
19
19
|
|
20
|
-
from prefect.context import ContextModel
|
20
|
+
from prefect.context import ContextModel
|
21
21
|
from prefect.exceptions import MissingContextError, SerializationError
|
22
22
|
from prefect.logging.loggers import get_logger, get_run_logger
|
23
23
|
from prefect.records import RecordStore
|
24
|
-
from prefect.
|
25
|
-
|
26
|
-
ResultFactory,
|
27
|
-
get_default_result_storage,
|
28
|
-
)
|
24
|
+
from prefect.records.base import TransactionRecord
|
25
|
+
from prefect.results import BaseResult, ResultRecord, ResultStore
|
29
26
|
from prefect.utilities.annotations import NotSet
|
30
|
-
from prefect.utilities.asyncutils import run_coro_as_sync
|
31
27
|
from prefect.utilities.collections import AutoEnum
|
32
28
|
from prefect.utilities.engine import _get_hook_name
|
33
29
|
|
@@ -56,7 +52,7 @@ class Transaction(ContextModel):
|
|
56
52
|
A base model for transaction state.
|
57
53
|
"""
|
58
54
|
|
59
|
-
store:
|
55
|
+
store: Union[RecordStore, ResultStore, None] = None
|
60
56
|
key: Optional[str] = None
|
61
57
|
children: List["Transaction"] = Field(default_factory=list)
|
62
58
|
commit_mode: Optional[CommitMode] = None
|
@@ -177,10 +173,14 @@ class Transaction(ContextModel):
|
|
177
173
|
):
|
178
174
|
self.state = TransactionState.COMMITTED
|
179
175
|
|
180
|
-
def read(self) ->
|
176
|
+
def read(self) -> Union["BaseResult", ResultRecord, None]:
|
181
177
|
if self.store and self.key:
|
182
178
|
record = self.store.read(key=self.key)
|
183
|
-
if record
|
179
|
+
if isinstance(record, ResultRecord):
|
180
|
+
return record
|
181
|
+
# for backwards compatibility, if we encounter a transaction record, return the result
|
182
|
+
# This happens when the transaction is using a `ResultStore`
|
183
|
+
if isinstance(record, TransactionRecord):
|
184
184
|
return record.result
|
185
185
|
return None
|
186
186
|
|
@@ -230,7 +230,13 @@ class Transaction(ContextModel):
|
|
230
230
|
self.run_hook(hook, "commit")
|
231
231
|
|
232
232
|
if self.store and self.key:
|
233
|
-
self.store
|
233
|
+
if isinstance(self.store, ResultStore):
|
234
|
+
if isinstance(self._staged_value, BaseResult):
|
235
|
+
self.store.write(self.key, self._staged_value.get(_sync=True))
|
236
|
+
else:
|
237
|
+
self.store.write(self.key, self._staged_value)
|
238
|
+
else:
|
239
|
+
self.store.write(self.key, self._staged_value)
|
234
240
|
self.state = TransactionState.COMMITTED
|
235
241
|
if (
|
236
242
|
self.store
|
@@ -281,7 +287,7 @@ class Transaction(ContextModel):
|
|
281
287
|
|
282
288
|
def stage(
|
283
289
|
self,
|
284
|
-
value: BaseResult,
|
290
|
+
value: Union["BaseResult", Any],
|
285
291
|
on_rollback_hooks: Optional[List] = None,
|
286
292
|
on_commit_hooks: Optional[List] = None,
|
287
293
|
) -> None:
|
@@ -339,7 +345,7 @@ def get_transaction() -> Optional[Transaction]:
|
|
339
345
|
@contextmanager
|
340
346
|
def transaction(
|
341
347
|
key: Optional[str] = None,
|
342
|
-
store:
|
348
|
+
store: Union[RecordStore, ResultStore, None] = None,
|
343
349
|
commit_mode: Optional[CommitMode] = None,
|
344
350
|
isolation_level: Optional[IsolationLevel] = None,
|
345
351
|
overwrite: bool = False,
|
@@ -361,23 +367,26 @@ def transaction(
|
|
361
367
|
"""
|
362
368
|
# if there is no key, we won't persist a record
|
363
369
|
if key and not store:
|
370
|
+
from prefect.context import FlowRunContext, TaskRunContext
|
371
|
+
from prefect.results import ResultStore, get_default_result_storage
|
372
|
+
|
364
373
|
flow_run_context = FlowRunContext.get()
|
365
374
|
task_run_context = TaskRunContext.get()
|
366
|
-
|
367
|
-
flow_run_context, "
|
375
|
+
existing_store = getattr(task_run_context, "result_store", None) or getattr(
|
376
|
+
flow_run_context, "result_store", None
|
368
377
|
)
|
369
378
|
|
370
|
-
|
371
|
-
if
|
372
|
-
|
379
|
+
new_store: ResultStore
|
380
|
+
if existing_store and existing_store.result_storage_block_id:
|
381
|
+
new_store = existing_store.model_copy(
|
373
382
|
update={
|
374
383
|
"persist_result": True,
|
375
384
|
}
|
376
385
|
)
|
377
386
|
else:
|
378
387
|
default_storage = get_default_result_storage(_sync=True)
|
379
|
-
if
|
380
|
-
|
388
|
+
if existing_store:
|
389
|
+
new_store = existing_store.model_copy(
|
381
390
|
update={
|
382
391
|
"persist_result": True,
|
383
392
|
"storage_block": default_storage,
|
@@ -385,16 +394,14 @@ def transaction(
|
|
385
394
|
}
|
386
395
|
)
|
387
396
|
else:
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
result_storage=default_storage,
|
392
|
-
)
|
397
|
+
new_store = ResultStore(
|
398
|
+
persist_result=True,
|
399
|
+
result_storage=default_storage,
|
393
400
|
)
|
394
|
-
from prefect.records.result_store import
|
401
|
+
from prefect.records.result_store import ResultRecordStore
|
395
402
|
|
396
|
-
store =
|
397
|
-
|
403
|
+
store = ResultRecordStore(
|
404
|
+
result_store=new_store,
|
398
405
|
)
|
399
406
|
|
400
407
|
try:
|
prefect/utilities/callables.py
CHANGED
@@ -263,9 +263,7 @@ def parameter_docstrings(docstring: Optional[str]) -> Dict[str, str]:
|
|
263
263
|
if not docstring:
|
264
264
|
return param_docstrings
|
265
265
|
|
266
|
-
with disable_logger("griffe
|
267
|
-
"griffe.agents.nodes"
|
268
|
-
):
|
266
|
+
with disable_logger("griffe"):
|
269
267
|
parsed = parse(Docstring(docstring), Parser.google)
|
270
268
|
for section in parsed:
|
271
269
|
if section.kind != DocstringSectionKind.parameters:
|
prefect/variables.py
CHANGED
@@ -1,19 +1,18 @@
|
|
1
|
-
from typing import List, Optional
|
1
|
+
from typing import List, Optional
|
2
|
+
|
3
|
+
from pydantic import BaseModel, Field
|
2
4
|
|
3
5
|
from prefect._internal.compatibility.migration import getattr_migration
|
4
|
-
from prefect.client.schemas.actions import VariableCreate
|
5
|
-
from prefect.client.schemas.actions import VariableUpdate as VariableUpdateRequest
|
6
|
-
from prefect.client.schemas.objects import Variable as VariableResponse
|
6
|
+
from prefect.client.schemas.actions import VariableCreate, VariableUpdate
|
7
7
|
from prefect.client.utilities import get_or_create_client
|
8
8
|
from prefect.exceptions import ObjectNotFound
|
9
|
-
from prefect.types import StrictVariableValue
|
9
|
+
from prefect.types import MAX_VARIABLE_NAME_LENGTH, StrictVariableValue
|
10
10
|
from prefect.utilities.asyncutils import sync_compatible
|
11
11
|
|
12
12
|
|
13
|
-
class Variable(
|
13
|
+
class Variable(BaseModel):
|
14
14
|
"""
|
15
|
-
Variables are named, mutable
|
16
|
-
https://docs.prefect.io/latest/concepts/variables/
|
15
|
+
Variables are named, mutable JSON values that can be shared across tasks and flows.
|
17
16
|
|
18
17
|
Arguments:
|
19
18
|
name: A string identifying the variable.
|
@@ -21,6 +20,19 @@ class Variable(VariableRequest):
|
|
21
20
|
tags: An optional list of strings to associate with the variable.
|
22
21
|
"""
|
23
22
|
|
23
|
+
name: str = Field(
|
24
|
+
default=...,
|
25
|
+
description="The name of the variable",
|
26
|
+
examples=["my_variable"],
|
27
|
+
max_length=MAX_VARIABLE_NAME_LENGTH,
|
28
|
+
)
|
29
|
+
value: StrictVariableValue = Field(
|
30
|
+
default=...,
|
31
|
+
description="The value of the variable",
|
32
|
+
examples=["my-value"],
|
33
|
+
)
|
34
|
+
tags: Optional[List[str]] = Field(default=None)
|
35
|
+
|
24
36
|
@classmethod
|
25
37
|
@sync_compatible
|
26
38
|
async def set(
|
@@ -29,22 +41,21 @@ class Variable(VariableRequest):
|
|
29
41
|
value: StrictVariableValue,
|
30
42
|
tags: Optional[List[str]] = None,
|
31
43
|
overwrite: bool = False,
|
32
|
-
|
33
|
-
):
|
44
|
+
) -> "Variable":
|
34
45
|
"""
|
35
46
|
Sets a new variable. If one exists with the same name, must pass `overwrite=True`
|
36
47
|
|
37
|
-
Returns the newly set
|
48
|
+
Returns the newly set variable object.
|
38
49
|
|
39
50
|
Args:
|
40
51
|
- name: The name of the variable to set.
|
41
52
|
- value: The value of the variable to set.
|
42
53
|
- tags: An optional list of strings to associate with the variable.
|
43
54
|
- overwrite: Whether to overwrite the variable if it already exists.
|
44
|
-
- as_object: Whether to return the full Variable object.
|
45
55
|
|
46
56
|
Example:
|
47
57
|
Set a new variable and overwrite it if it already exists.
|
58
|
+
|
48
59
|
```
|
49
60
|
from prefect.variables import Variable
|
50
61
|
|
@@ -62,14 +73,17 @@ class Variable(VariableRequest):
|
|
62
73
|
raise ValueError(
|
63
74
|
f"Variable {name!r} already exists. Use `overwrite=True` to update it."
|
64
75
|
)
|
65
|
-
await client.update_variable(variable=
|
76
|
+
await client.update_variable(variable=VariableUpdate(**var_dict))
|
66
77
|
variable = await client.read_variable_by_name(name)
|
78
|
+
var_dict = {
|
79
|
+
"name": variable.name,
|
80
|
+
"value": variable.value,
|
81
|
+
"tags": variable.tags or [],
|
82
|
+
}
|
67
83
|
else:
|
68
|
-
|
69
|
-
variable=VariableRequest(**var_dict)
|
70
|
-
)
|
84
|
+
await client.create_variable(variable=VariableCreate(**var_dict))
|
71
85
|
|
72
|
-
return
|
86
|
+
return cls(**var_dict)
|
73
87
|
|
74
88
|
@classmethod
|
75
89
|
@sync_compatible
|
@@ -77,19 +91,15 @@ class Variable(VariableRequest):
|
|
77
91
|
cls,
|
78
92
|
name: str,
|
79
93
|
default: StrictVariableValue = None,
|
80
|
-
|
81
|
-
) -> Union[StrictVariableValue, VariableResponse]:
|
94
|
+
) -> StrictVariableValue:
|
82
95
|
"""
|
83
96
|
Get a variable's value by name.
|
84
97
|
|
85
98
|
If the variable does not exist, return the default value.
|
86
99
|
|
87
|
-
If `as_object=True`, return the full variable object. `default` is ignored in this case.
|
88
|
-
|
89
100
|
Args:
|
90
|
-
- name: The name of the variable to get.
|
101
|
+
- name: The name of the variable value to get.
|
91
102
|
- default: The default value to return if the variable does not exist.
|
92
|
-
- as_object: Whether to return the full variable object.
|
93
103
|
|
94
104
|
Example:
|
95
105
|
Get a variable's value by name.
|
@@ -105,7 +115,7 @@ class Variable(VariableRequest):
|
|
105
115
|
client, _ = get_or_create_client()
|
106
116
|
variable = await client.read_variable_by_name(name)
|
107
117
|
|
108
|
-
return variable
|
118
|
+
return variable.value if variable else default
|
109
119
|
|
110
120
|
@classmethod
|
111
121
|
@sync_compatible
|
prefect/workers/process.py
CHANGED
@@ -144,9 +144,7 @@ class ProcessWorker(BaseWorker):
|
|
144
144
|
" when first getting started."
|
145
145
|
)
|
146
146
|
_display_name = "Process"
|
147
|
-
_documentation_url =
|
148
|
-
"https://docs.prefect.io/latest/api-ref/prefect/workers/process/"
|
149
|
-
)
|
147
|
+
_documentation_url = "https://docs.prefect.io/latest/get-started/quickstart"
|
150
148
|
_logo_url = "https://cdn.sanity.io/images/3ugk85nk/production/356e6766a91baf20e1d08bbe16e8b5aaef4d8643-48x48.png"
|
151
149
|
|
152
150
|
async def start(
|
@@ -1,12 +1,12 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: prefect-client
|
3
|
-
Version: 3.0.
|
3
|
+
Version: 3.0.1
|
4
4
|
Summary: Workflow orchestration and management.
|
5
5
|
Home-page: https://www.prefect.io
|
6
6
|
Author: Prefect Technologies, Inc.
|
7
7
|
Author-email: help@prefect.io
|
8
8
|
License: UNKNOWN
|
9
|
-
Project-URL: Changelog, https://github.com/PrefectHQ/prefect/
|
9
|
+
Project-URL: Changelog, https://github.com/PrefectHQ/prefect/releases
|
10
10
|
Project-URL: Documentation, https://docs.prefect.io
|
11
11
|
Project-URL: Source, https://github.com/PrefectHQ/prefect
|
12
12
|
Project-URL: Tracker, https://github.com/PrefectHQ/prefect/issues
|