prefect-client 3.0.0rc2__py3-none-any.whl → 3.0.0rc4__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- prefect/__init__.py +0 -1
- prefect/_internal/compatibility/migration.py +124 -0
- prefect/_internal/concurrency/__init__.py +2 -2
- prefect/_internal/concurrency/primitives.py +1 -0
- prefect/_internal/pydantic/annotations/pendulum.py +2 -2
- prefect/_internal/pytz.py +1 -1
- prefect/blocks/core.py +1 -1
- prefect/client/orchestration.py +96 -22
- prefect/client/schemas/actions.py +1 -1
- prefect/client/schemas/filters.py +6 -0
- prefect/client/schemas/objects.py +10 -3
- prefect/client/subscriptions.py +6 -5
- prefect/context.py +1 -27
- prefect/deployments/__init__.py +3 -0
- prefect/deployments/base.py +4 -2
- prefect/deployments/deployments.py +3 -0
- prefect/deployments/steps/pull.py +1 -0
- prefect/deployments/steps/utility.py +2 -1
- prefect/engine.py +3 -0
- prefect/events/cli/automations.py +1 -1
- prefect/events/clients.py +7 -1
- prefect/exceptions.py +9 -0
- prefect/filesystems.py +22 -11
- prefect/flow_engine.py +195 -153
- prefect/flows.py +95 -36
- prefect/futures.py +9 -1
- prefect/infrastructure/provisioners/container_instance.py +1 -0
- prefect/infrastructure/provisioners/ecs.py +2 -2
- prefect/input/__init__.py +4 -0
- prefect/logging/formatters.py +2 -2
- prefect/logging/handlers.py +2 -2
- prefect/logging/loggers.py +1 -1
- prefect/plugins.py +1 -0
- prefect/records/cache_policies.py +3 -3
- prefect/records/result_store.py +10 -3
- prefect/results.py +47 -73
- prefect/runner/runner.py +1 -1
- prefect/runner/server.py +1 -1
- prefect/runtime/__init__.py +1 -0
- prefect/runtime/deployment.py +1 -0
- prefect/runtime/flow_run.py +1 -0
- prefect/runtime/task_run.py +1 -0
- prefect/settings.py +16 -3
- prefect/states.py +15 -4
- prefect/task_engine.py +195 -39
- prefect/task_runners.py +9 -3
- prefect/task_runs.py +26 -12
- prefect/task_worker.py +149 -20
- prefect/tasks.py +153 -71
- prefect/transactions.py +85 -15
- prefect/types/__init__.py +10 -3
- prefect/utilities/asyncutils.py +3 -3
- prefect/utilities/callables.py +16 -4
- prefect/utilities/collections.py +120 -57
- prefect/utilities/dockerutils.py +5 -3
- prefect/utilities/engine.py +11 -0
- prefect/utilities/filesystem.py +4 -5
- prefect/utilities/importtools.py +29 -0
- prefect/utilities/services.py +2 -2
- prefect/utilities/urls.py +195 -0
- prefect/utilities/visualization.py +1 -0
- prefect/variables.py +4 -0
- prefect/workers/base.py +35 -0
- {prefect_client-3.0.0rc2.dist-info → prefect_client-3.0.0rc4.dist-info}/METADATA +2 -2
- {prefect_client-3.0.0rc2.dist-info → prefect_client-3.0.0rc4.dist-info}/RECORD +68 -66
- prefect/blocks/kubernetes.py +0 -115
- {prefect_client-3.0.0rc2.dist-info → prefect_client-3.0.0rc4.dist-info}/LICENSE +0 -0
- {prefect_client-3.0.0rc2.dist-info → prefect_client-3.0.0rc4.dist-info}/WHEEL +0 -0
- {prefect_client-3.0.0rc2.dist-info → prefect_client-3.0.0rc4.dist-info}/top_level.txt +0 -0
prefect/__init__.py
CHANGED
@@ -0,0 +1,124 @@
|
|
1
|
+
"""
|
2
|
+
This module provides a function to handle imports for moved or removed objects in Prefect 3.0 upgrade.
|
3
|
+
|
4
|
+
The `getattr_migration` function is used to handle imports for moved or removed objects in Prefect 3.0 upgrade.
|
5
|
+
It is used in the `__getattr__` attribute of modules that have moved or removed objects.
|
6
|
+
|
7
|
+
Usage:
|
8
|
+
```python
|
9
|
+
from prefect._internal.compatibility.migration import getattr_migration
|
10
|
+
|
11
|
+
__getattr__ = getattr_migration(__name__)
|
12
|
+
```
|
13
|
+
"""
|
14
|
+
|
15
|
+
import sys
|
16
|
+
from typing import Any, Callable, Dict
|
17
|
+
|
18
|
+
from pydantic_core import PydanticCustomError
|
19
|
+
|
20
|
+
from prefect.exceptions import PrefectImportError
|
21
|
+
|
22
|
+
MOVED_IN_V3 = {
|
23
|
+
"prefect.deployments.deployments:load_flow_from_flow_run": "prefect.flows:load_flow_from_flow_run",
|
24
|
+
"prefect.deployments:load_flow_from_flow_run": "prefect.flows:load_flow_from_flow_run",
|
25
|
+
"prefect.variables:get": "prefect.variables:Variable.get",
|
26
|
+
"prefect.engine:pause_flow_run": "prefect.flow_runs:pause_flow_run",
|
27
|
+
"prefect.engine:resume_flow_run": "prefect.flow_runs:resume_flow_run",
|
28
|
+
"prefect.engine:suspend_flow_run": "prefect.flow_runs:suspend_flow_run",
|
29
|
+
"prefect.engine:_in_process_pause": "prefect.flow_runs:_in_process_pause",
|
30
|
+
}
|
31
|
+
|
32
|
+
REMOVED_IN_V3 = {
|
33
|
+
"prefect.deployments.deployments:Deployment": "Use 'flow.serve()' or `prefect deploy` instead.",
|
34
|
+
"prefect.deployments:Deployment": "Use 'flow.serve()' or `prefect deploy` instead.",
|
35
|
+
"prefect.filesystems:GCS": "Use 'prefect_gcp' instead.",
|
36
|
+
"prefect.filesystems:Azure": "Use 'prefect_azure' instead.",
|
37
|
+
"prefect.filesystems:S3": "Use 'prefect_aws' instead.",
|
38
|
+
"prefect.engine:_out_of_process_pause": "Use 'prefect.flow_runs.pause_flow_run' instead.",
|
39
|
+
}
|
40
|
+
|
41
|
+
# IMPORTANT FOR USAGE: When adding new modules to MOVED_IN_V3 or REMOVED_IN_V3, include the following lines at the bottom of that module:
|
42
|
+
# from prefect._internal.compatibility.migration import getattr_migration
|
43
|
+
# __getattr__ = getattr_migration(__name__)
|
44
|
+
# See src/prefect/filesystems.py for an example
|
45
|
+
|
46
|
+
|
47
|
+
def import_string_class_method(new_location: str) -> Callable:
|
48
|
+
"""
|
49
|
+
Handle moved class methods.
|
50
|
+
|
51
|
+
`import_string` does not account for moved class methods. This function handles cases where a method has been
|
52
|
+
moved to a class. For example, if `new_location` is 'prefect.variables:Variable.get', `import_string(new_location)`
|
53
|
+
will raise an error because it does not handle class methods. This function will import the class and get the
|
54
|
+
method from the class.
|
55
|
+
|
56
|
+
Args:
|
57
|
+
new_location (str): The new location of the method.
|
58
|
+
|
59
|
+
Returns:
|
60
|
+
method: The resolved method from the class.
|
61
|
+
|
62
|
+
Raises:
|
63
|
+
PrefectImportError: If the method is not found in the class.
|
64
|
+
"""
|
65
|
+
from pydantic._internal._validators import import_string
|
66
|
+
|
67
|
+
class_name, method_name = new_location.rsplit(".", 1)
|
68
|
+
|
69
|
+
cls = import_string(class_name)
|
70
|
+
method = getattr(cls, method_name, None)
|
71
|
+
|
72
|
+
if method is not None and callable(method):
|
73
|
+
return method
|
74
|
+
|
75
|
+
raise PrefectImportError(f"Unable to import {new_location!r}")
|
76
|
+
|
77
|
+
|
78
|
+
def getattr_migration(module_name: str) -> Callable[[str], Any]:
|
79
|
+
"""
|
80
|
+
Handle imports for moved or removed objects in Prefect 3.0 upgrade
|
81
|
+
|
82
|
+
Args:
|
83
|
+
module_name (str): The name of the module to handle imports for.
|
84
|
+
"""
|
85
|
+
|
86
|
+
def wrapper(name: str) -> object:
|
87
|
+
"""
|
88
|
+
Raise a PrefectImportError if the object is not found, moved, or removed.
|
89
|
+
"""
|
90
|
+
|
91
|
+
if name == "__path__":
|
92
|
+
raise AttributeError(f"{module_name!r} object has no attribute {name!r}")
|
93
|
+
import warnings
|
94
|
+
|
95
|
+
from pydantic._internal._validators import import_string
|
96
|
+
|
97
|
+
import_path = f"{module_name}:{name}"
|
98
|
+
|
99
|
+
# Check if the attribute name corresponds to a moved or removed class or module
|
100
|
+
if import_path in MOVED_IN_V3.keys():
|
101
|
+
new_location = MOVED_IN_V3[import_path]
|
102
|
+
warnings.warn(
|
103
|
+
f"{import_path!r} has been moved to {new_location!r}. Importing from {new_location!r} instead. This warning will raise an error in a future release.",
|
104
|
+
DeprecationWarning,
|
105
|
+
stacklevel=2,
|
106
|
+
)
|
107
|
+
try:
|
108
|
+
return import_string(new_location)
|
109
|
+
except PydanticCustomError:
|
110
|
+
return import_string_class_method(new_location)
|
111
|
+
|
112
|
+
if import_path in REMOVED_IN_V3.keys():
|
113
|
+
error_message = REMOVED_IN_V3[import_path]
|
114
|
+
raise PrefectImportError(
|
115
|
+
f"{import_path!r} has been removed. {error_message}"
|
116
|
+
)
|
117
|
+
|
118
|
+
globals: Dict[str, Any] = sys.modules[module_name].__dict__
|
119
|
+
if name in globals:
|
120
|
+
return globals[name]
|
121
|
+
|
122
|
+
raise AttributeError(f"module {module_name!r} has no attribute {name!r}")
|
123
|
+
|
124
|
+
return wrapper
|
@@ -5,7 +5,7 @@ both asynchronous and synchronous calls.
|
|
5
5
|
Much of the complexity managed here arises from ensuring that a thread of execution is
|
6
6
|
not blocked.
|
7
7
|
|
8
|
-
The main data structure is a `Call` which is created from a function call capturing
|
8
|
+
The main data structure is a `Call` which is created from a function call capturing
|
9
9
|
local context variables. The call is then submitted to run somewhere via a `Portal`.
|
10
10
|
The primary portal used is the `WorkerThread`, which executes work on a thread running
|
11
11
|
concurrently to the one that created the call. A singleton `EventLoopThread` portal
|
@@ -13,7 +13,7 @@ is also used to schedule work on a dedicated event loop.
|
|
13
13
|
|
14
14
|
The result of the call can be retrieved asynchronously using `Call.result()`. Behind
|
15
15
|
the scenes, a `Future` is used to report the result of the call. Retrieving the result
|
16
|
-
of a call is a blocking operation.
|
16
|
+
of a call is a blocking operation.
|
17
17
|
|
18
18
|
Sometimes, it is important not to block the current thread while retrieving the result
|
19
19
|
of a call. For this purpose, there is the `Waiter`. Waiters attach to a call and provide
|
prefect/_internal/pytz.py
CHANGED
prefect/blocks/core.py
CHANGED
@@ -1122,7 +1122,7 @@ class Block(BaseModel, ABC):
|
|
1122
1122
|
cls,
|
1123
1123
|
by_alias: bool = True,
|
1124
1124
|
ref_template: str = "#/definitions/{model}",
|
1125
|
-
schema_generator:
|
1125
|
+
schema_generator: Type[GenerateJsonSchema] = GenerateJsonSchema,
|
1126
1126
|
mode: Literal["validation", "serialization"] = "validation",
|
1127
1127
|
) -> Dict[str, Any]:
|
1128
1128
|
"""TODO: stop overriding this method - use GenerateSchema in ConfigDict instead?"""
|
prefect/client/orchestration.py
CHANGED
@@ -270,8 +270,8 @@ class PrefectClient:
|
|
270
270
|
self,
|
271
271
|
api: Union[str, ASGIApp],
|
272
272
|
*,
|
273
|
-
api_key: str = None,
|
274
|
-
api_version: str = None,
|
273
|
+
api_key: Optional[str] = None,
|
274
|
+
api_version: Optional[str] = None,
|
275
275
|
httpx_settings: Optional[Dict[str, Any]] = None,
|
276
276
|
) -> None:
|
277
277
|
httpx_settings = httpx_settings.copy() if httpx_settings else {}
|
@@ -506,7 +506,7 @@ class PrefectClient:
|
|
506
506
|
work_pool_filter: WorkPoolFilter = None,
|
507
507
|
work_queue_filter: WorkQueueFilter = None,
|
508
508
|
sort: FlowSort = None,
|
509
|
-
limit: int = None,
|
509
|
+
limit: Optional[int] = None,
|
510
510
|
offset: int = 0,
|
511
511
|
) -> List[Flow]:
|
512
512
|
"""
|
@@ -576,12 +576,12 @@ class PrefectClient:
|
|
576
576
|
*,
|
577
577
|
parameters: Optional[Dict[str, Any]] = None,
|
578
578
|
context: Optional[Dict[str, Any]] = None,
|
579
|
-
state: prefect.states.State = None,
|
580
|
-
name: str = None,
|
581
|
-
tags: Iterable[str] = None,
|
582
|
-
idempotency_key: str = None,
|
583
|
-
parent_task_run_id: UUID = None,
|
584
|
-
work_queue_name: str = None,
|
579
|
+
state: Optional[prefect.states.State] = None,
|
580
|
+
name: Optional[str] = None,
|
581
|
+
tags: Optional[Iterable[str]] = None,
|
582
|
+
idempotency_key: Optional[str] = None,
|
583
|
+
parent_task_run_id: Optional[UUID] = None,
|
584
|
+
work_queue_name: Optional[str] = None,
|
585
585
|
job_variables: Optional[Dict[str, Any]] = None,
|
586
586
|
) -> FlowRun:
|
587
587
|
"""
|
@@ -1710,7 +1710,7 @@ class PrefectClient:
|
|
1710
1710
|
self,
|
1711
1711
|
deployment: Deployment,
|
1712
1712
|
schedule: SCHEDULE_TYPES = None,
|
1713
|
-
is_schedule_active: bool = None,
|
1713
|
+
is_schedule_active: Optional[bool] = None,
|
1714
1714
|
):
|
1715
1715
|
deployment_update = DeploymentUpdate(
|
1716
1716
|
version=deployment.version,
|
@@ -2060,7 +2060,7 @@ class PrefectClient:
|
|
2060
2060
|
work_pool_filter: WorkPoolFilter = None,
|
2061
2061
|
work_queue_filter: WorkQueueFilter = None,
|
2062
2062
|
sort: FlowRunSort = None,
|
2063
|
-
limit: int = None,
|
2063
|
+
limit: Optional[int] = None,
|
2064
2064
|
offset: int = 0,
|
2065
2065
|
) -> List[FlowRun]:
|
2066
2066
|
"""
|
@@ -2133,7 +2133,6 @@ class PrefectClient:
|
|
2133
2133
|
state_create = state.to_state_create()
|
2134
2134
|
state_create.state_details.flow_run_id = flow_run_id
|
2135
2135
|
state_create.state_details.transition_id = uuid4()
|
2136
|
-
print(repr(state_create))
|
2137
2136
|
try:
|
2138
2137
|
response = await self._client.post(
|
2139
2138
|
f"/flow_runs/{flow_run_id}/set_state",
|
@@ -2268,7 +2267,7 @@ class PrefectClient:
|
|
2268
2267
|
task_run_filter: TaskRunFilter = None,
|
2269
2268
|
deployment_filter: DeploymentFilter = None,
|
2270
2269
|
sort: TaskRunSort = None,
|
2271
|
-
limit: int = None,
|
2270
|
+
limit: Optional[int] = None,
|
2272
2271
|
offset: int = 0,
|
2273
2272
|
) -> List[TaskRun]:
|
2274
2273
|
"""
|
@@ -2532,8 +2531,8 @@ class PrefectClient:
|
|
2532
2531
|
async def read_logs(
|
2533
2532
|
self,
|
2534
2533
|
log_filter: LogFilter = None,
|
2535
|
-
limit: int = None,
|
2536
|
-
offset: int = None,
|
2534
|
+
limit: Optional[int] = None,
|
2535
|
+
offset: Optional[int] = None,
|
2537
2536
|
sort: LogSort = LogSort.TIMESTAMP_ASC,
|
2538
2537
|
) -> List[Log]:
|
2539
2538
|
"""
|
@@ -2864,7 +2863,7 @@ class PrefectClient:
|
|
2864
2863
|
flow_run_filter: FlowRunFilter = None,
|
2865
2864
|
task_run_filter: TaskRunFilter = None,
|
2866
2865
|
sort: ArtifactSort = None,
|
2867
|
-
limit: int = None,
|
2866
|
+
limit: Optional[int] = None,
|
2868
2867
|
offset: int = 0,
|
2869
2868
|
) -> List[Artifact]:
|
2870
2869
|
"""
|
@@ -2904,7 +2903,7 @@ class PrefectClient:
|
|
2904
2903
|
flow_run_filter: FlowRunFilter = None,
|
2905
2904
|
task_run_filter: TaskRunFilter = None,
|
2906
2905
|
sort: ArtifactCollectionSort = None,
|
2907
|
-
limit: int = None,
|
2906
|
+
limit: Optional[int] = None,
|
2908
2907
|
offset: int = 0,
|
2909
2908
|
) -> List[ArtifactCollection]:
|
2910
2909
|
"""
|
@@ -3004,7 +3003,7 @@ class PrefectClient:
|
|
3004
3003
|
else:
|
3005
3004
|
raise
|
3006
3005
|
|
3007
|
-
async def read_variables(self, limit: int = None) -> List[Variable]:
|
3006
|
+
async def read_variables(self, limit: Optional[int] = None) -> List[Variable]:
|
3008
3007
|
"""Reads all variables."""
|
3009
3008
|
response = await self._client.post("/variables/filter", json={"limit": limit})
|
3010
3009
|
return pydantic.TypeAdapter(List[Variable]).validate_python(response.json())
|
@@ -3371,8 +3370,8 @@ class SyncPrefectClient:
|
|
3371
3370
|
self,
|
3372
3371
|
api: Union[str, ASGIApp],
|
3373
3372
|
*,
|
3374
|
-
api_key: str = None,
|
3375
|
-
api_version: str = None,
|
3373
|
+
api_key: Optional[str] = None,
|
3374
|
+
api_version: Optional[str] = None,
|
3376
3375
|
httpx_settings: Optional[Dict[str, Any]] = None,
|
3377
3376
|
) -> None:
|
3378
3377
|
httpx_settings = httpx_settings.copy() if httpx_settings else {}
|
@@ -3669,6 +3668,61 @@ class SyncPrefectClient:
|
|
3669
3668
|
|
3670
3669
|
return flow_run
|
3671
3670
|
|
3671
|
+
def update_flow_run(
|
3672
|
+
self,
|
3673
|
+
flow_run_id: UUID,
|
3674
|
+
flow_version: Optional[str] = None,
|
3675
|
+
parameters: Optional[dict] = None,
|
3676
|
+
name: Optional[str] = None,
|
3677
|
+
tags: Optional[Iterable[str]] = None,
|
3678
|
+
empirical_policy: Optional[FlowRunPolicy] = None,
|
3679
|
+
infrastructure_pid: Optional[str] = None,
|
3680
|
+
job_variables: Optional[dict] = None,
|
3681
|
+
) -> httpx.Response:
|
3682
|
+
"""
|
3683
|
+
Update a flow run's details.
|
3684
|
+
|
3685
|
+
Args:
|
3686
|
+
flow_run_id: The identifier for the flow run to update.
|
3687
|
+
flow_version: A new version string for the flow run.
|
3688
|
+
parameters: A dictionary of parameter values for the flow run. This will not
|
3689
|
+
be merged with any existing parameters.
|
3690
|
+
name: A new name for the flow run.
|
3691
|
+
empirical_policy: A new flow run orchestration policy. This will not be
|
3692
|
+
merged with any existing policy.
|
3693
|
+
tags: An iterable of new tags for the flow run. These will not be merged with
|
3694
|
+
any existing tags.
|
3695
|
+
infrastructure_pid: The id of flow run as returned by an
|
3696
|
+
infrastructure block.
|
3697
|
+
|
3698
|
+
Returns:
|
3699
|
+
an `httpx.Response` object from the PATCH request
|
3700
|
+
"""
|
3701
|
+
params = {}
|
3702
|
+
if flow_version is not None:
|
3703
|
+
params["flow_version"] = flow_version
|
3704
|
+
if parameters is not None:
|
3705
|
+
params["parameters"] = parameters
|
3706
|
+
if name is not None:
|
3707
|
+
params["name"] = name
|
3708
|
+
if tags is not None:
|
3709
|
+
params["tags"] = tags
|
3710
|
+
if empirical_policy is not None:
|
3711
|
+
params["empirical_policy"] = empirical_policy.model_dump(
|
3712
|
+
mode="json", exclude_unset=True
|
3713
|
+
)
|
3714
|
+
if infrastructure_pid:
|
3715
|
+
params["infrastructure_pid"] = infrastructure_pid
|
3716
|
+
if job_variables is not None:
|
3717
|
+
params["job_variables"] = job_variables
|
3718
|
+
|
3719
|
+
flow_run_data = FlowRunUpdate(**params)
|
3720
|
+
|
3721
|
+
return self._client.patch(
|
3722
|
+
f"/flow_runs/{flow_run_id}",
|
3723
|
+
json=flow_run_data.model_dump(mode="json", exclude_unset=True),
|
3724
|
+
)
|
3725
|
+
|
3672
3726
|
def read_flow_run(self, flow_run_id: UUID) -> FlowRun:
|
3673
3727
|
"""
|
3674
3728
|
Query the Prefect API for a flow run by id.
|
@@ -3698,7 +3752,7 @@ class SyncPrefectClient:
|
|
3698
3752
|
work_pool_filter: WorkPoolFilter = None,
|
3699
3753
|
work_queue_filter: WorkQueueFilter = None,
|
3700
3754
|
sort: FlowRunSort = None,
|
3701
|
-
limit: int = None,
|
3755
|
+
limit: Optional[int] = None,
|
3702
3756
|
offset: int = 0,
|
3703
3757
|
) -> List[FlowRun]:
|
3704
3758
|
"""
|
@@ -3890,7 +3944,7 @@ class SyncPrefectClient:
|
|
3890
3944
|
task_run_filter: TaskRunFilter = None,
|
3891
3945
|
deployment_filter: DeploymentFilter = None,
|
3892
3946
|
sort: TaskRunSort = None,
|
3893
|
-
limit: int = None,
|
3947
|
+
limit: Optional[int] = None,
|
3894
3948
|
offset: int = 0,
|
3895
3949
|
) -> List[TaskRun]:
|
3896
3950
|
"""
|
@@ -3994,3 +4048,23 @@ class SyncPrefectClient:
|
|
3994
4048
|
else:
|
3995
4049
|
raise
|
3996
4050
|
return DeploymentResponse.model_validate(response.json())
|
4051
|
+
|
4052
|
+
def create_artifact(
|
4053
|
+
self,
|
4054
|
+
artifact: ArtifactCreate,
|
4055
|
+
) -> Artifact:
|
4056
|
+
"""
|
4057
|
+
Creates an artifact with the provided configuration.
|
4058
|
+
|
4059
|
+
Args:
|
4060
|
+
artifact: Desired configuration for the new artifact.
|
4061
|
+
Returns:
|
4062
|
+
Information about the newly created artifact.
|
4063
|
+
"""
|
4064
|
+
|
4065
|
+
response = self._client.post(
|
4066
|
+
"/artifacts/",
|
4067
|
+
json=artifact.model_dump_json(exclude_unset=True),
|
4068
|
+
)
|
4069
|
+
|
4070
|
+
return Artifact.model_validate(response.json())
|
@@ -788,6 +788,6 @@ class GlobalConcurrencyLimitUpdate(ActionBaseModel):
|
|
788
788
|
|
789
789
|
name: Optional[Name] = Field(None)
|
790
790
|
limit: Optional[NonNegativeInteger] = Field(None)
|
791
|
-
active: Optional[
|
791
|
+
active: Optional[bool] = Field(None)
|
792
792
|
active_slots: Optional[NonNegativeInteger] = Field(None)
|
793
793
|
slot_decay_per_second: Optional[NonNegativeFloat] = Field(None)
|
@@ -166,12 +166,18 @@ class FlowRunFilterStateType(PrefectBaseModel):
|
|
166
166
|
any_: Optional[List[StateType]] = Field(
|
167
167
|
default=None, description="A list of flow run state types to include"
|
168
168
|
)
|
169
|
+
not_any_: Optional[List[StateType]] = Field(
|
170
|
+
default=None, description="A list of flow run state types to exclude"
|
171
|
+
)
|
169
172
|
|
170
173
|
|
171
174
|
class FlowRunFilterStateName(PrefectBaseModel):
|
172
175
|
any_: Optional[List[str]] = Field(
|
173
176
|
default=None, description="A list of flow run state names to include"
|
174
177
|
)
|
178
|
+
not_any_: Optional[List[str]] = Field(
|
179
|
+
default=None, description="A list of flow run state names to exclude"
|
180
|
+
)
|
175
181
|
|
176
182
|
|
177
183
|
class FlowRunFilterState(PrefectBaseModel, OperatorMixin):
|
@@ -422,8 +422,11 @@ class FlowRunPolicy(PrefectBaseModel):
|
|
422
422
|
)
|
423
423
|
|
424
424
|
@model_validator(mode="before")
|
425
|
-
|
426
|
-
|
425
|
+
@classmethod
|
426
|
+
def populate_deprecated_fields(cls, values: Any):
|
427
|
+
if isinstance(values, dict):
|
428
|
+
return set_run_policy_deprecated_fields(values)
|
429
|
+
return values
|
427
430
|
|
428
431
|
|
429
432
|
class FlowRun(ObjectBaseModel):
|
@@ -915,6 +918,7 @@ class BlockDocument(ObjectBaseModel):
|
|
915
918
|
_validate_name_format = field_validator("name")(validate_block_document_name)
|
916
919
|
|
917
920
|
@model_validator(mode="before")
|
921
|
+
@classmethod
|
918
922
|
def validate_name_is_present_if_not_anonymous(cls, values):
|
919
923
|
return validate_name_present_on_nonanonymous_blocks(values)
|
920
924
|
|
@@ -1146,8 +1150,11 @@ class BlockDocumentReference(ObjectBaseModel):
|
|
1146
1150
|
)
|
1147
1151
|
|
1148
1152
|
@model_validator(mode="before")
|
1153
|
+
@classmethod
|
1149
1154
|
def validate_parent_and_ref_are_different(cls, values):
|
1150
|
-
|
1155
|
+
if isinstance(values, dict):
|
1156
|
+
return validate_parent_and_ref_diff(values)
|
1157
|
+
return values
|
1151
1158
|
|
1152
1159
|
|
1153
1160
|
class Configuration(ObjectBaseModel):
|
prefect/client/subscriptions.py
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
import asyncio
|
2
|
-
from typing import Any, Dict, Generic,
|
2
|
+
from typing import Any, Dict, Generic, Iterable, Optional, Type, TypeVar
|
3
3
|
|
4
4
|
import orjson
|
5
5
|
import websockets
|
@@ -9,7 +9,7 @@ from typing_extensions import Self
|
|
9
9
|
|
10
10
|
from prefect._internal.schemas.bases import IDBaseModel
|
11
11
|
from prefect.logging import get_logger
|
12
|
-
from prefect.settings import PREFECT_API_KEY
|
12
|
+
from prefect.settings import PREFECT_API_KEY
|
13
13
|
|
14
14
|
logger = get_logger(__name__)
|
15
15
|
|
@@ -21,15 +21,16 @@ class Subscription(Generic[S]):
|
|
21
21
|
self,
|
22
22
|
model: Type[S],
|
23
23
|
path: str,
|
24
|
-
keys:
|
24
|
+
keys: Iterable[str],
|
25
25
|
client_id: Optional[str] = None,
|
26
|
+
base_url: Optional[str] = None,
|
26
27
|
):
|
27
28
|
self.model = model
|
28
29
|
self.client_id = client_id
|
29
|
-
base_url =
|
30
|
+
base_url = base_url.replace("http", "ws", 1)
|
30
31
|
self.subscription_url = f"{base_url}{path}"
|
31
32
|
|
32
|
-
self.keys = keys
|
33
|
+
self.keys = list(keys)
|
33
34
|
|
34
35
|
self._connect = websockets.connect(
|
35
36
|
self.subscription_url,
|
prefect/context.py
CHANGED
@@ -29,13 +29,9 @@ from typing import (
|
|
29
29
|
Union,
|
30
30
|
)
|
31
31
|
|
32
|
-
import anyio
|
33
|
-
import anyio._backends._asyncio
|
34
|
-
import anyio.abc
|
35
32
|
import pendulum
|
36
33
|
from pydantic import BaseModel, ConfigDict, Field, PrivateAttr
|
37
34
|
from pydantic_extra_types.pendulum_dt import DateTime
|
38
|
-
from sniffio import AsyncLibraryNotFoundError
|
39
35
|
from typing_extensions import Self
|
40
36
|
|
41
37
|
import prefect.logging
|
@@ -45,7 +41,6 @@ from prefect.client.orchestration import PrefectClient, SyncPrefectClient, get_c
|
|
45
41
|
from prefect.client.schemas import FlowRun, TaskRun
|
46
42
|
from prefect.events.worker import EventsWorker
|
47
43
|
from prefect.exceptions import MissingContextError
|
48
|
-
from prefect.futures import PrefectFuture
|
49
44
|
from prefect.results import ResultFactory
|
50
45
|
from prefect.settings import PREFECT_HOME, Profile, Settings
|
51
46
|
from prefect.states import State
|
@@ -94,19 +89,12 @@ def hydrated_context(
|
|
94
89
|
if settings_context := serialized_context.get("settings_context"):
|
95
90
|
stack.enter_context(SettingsContext(**settings_context))
|
96
91
|
# Set up parent flow run context
|
97
|
-
# TODO: This task group isn't necessary in the new engine. Remove the background tasks
|
98
|
-
# attribute from FlowRunContext.
|
99
92
|
client = client or get_client(sync_client=True)
|
100
93
|
if flow_run_context := serialized_context.get("flow_run_context"):
|
101
|
-
try:
|
102
|
-
task_group = anyio.create_task_group()
|
103
|
-
except AsyncLibraryNotFoundError:
|
104
|
-
task_group = anyio._backends._asyncio.TaskGroup()
|
105
94
|
flow = flow_run_context["flow"]
|
106
95
|
flow_run_context = FlowRunContext(
|
107
96
|
**flow_run_context,
|
108
97
|
client=client,
|
109
|
-
background_tasks=task_group,
|
110
98
|
result_factory=run_coro_as_sync(ResultFactory.from_flow(flow)),
|
111
99
|
task_runner=flow.task_runner.duplicate(),
|
112
100
|
detached=True,
|
@@ -367,13 +355,10 @@ class EngineContext(RunContext):
|
|
367
355
|
task_run_states: A list of states for task runs created within this flow run
|
368
356
|
task_run_results: A mapping of result ids to task run states for this flow run
|
369
357
|
flow_run_states: A list of states for flow runs created within this flow run
|
370
|
-
sync_portal: A blocking portal for sync task/flow runs in an async flow
|
371
|
-
timeout_scope: The cancellation scope for flow level timeouts
|
372
358
|
"""
|
373
359
|
|
374
360
|
flow: Optional["Flow"] = None
|
375
361
|
flow_run: Optional[FlowRun] = None
|
376
|
-
autonomous_task_run: Optional[TaskRun] = None
|
377
362
|
task_runner: TaskRunner
|
378
363
|
log_prints: bool = False
|
379
364
|
parameters: Optional[Dict[str, Any]] = None
|
@@ -391,19 +376,8 @@ class EngineContext(RunContext):
|
|
391
376
|
# Counter for flow pauses
|
392
377
|
observed_flow_pauses: Dict[str, int] = Field(default_factory=dict)
|
393
378
|
|
394
|
-
# Tracking for
|
395
|
-
task_run_futures: List[PrefectFuture] = Field(default_factory=list)
|
396
|
-
task_run_states: List[State] = Field(default_factory=list)
|
379
|
+
# Tracking for result from task runs in this flow run
|
397
380
|
task_run_results: Dict[int, State] = Field(default_factory=dict)
|
398
|
-
flow_run_states: List[State] = Field(default_factory=list)
|
399
|
-
|
400
|
-
# The synchronous portal is only created for async flows for creating engine calls
|
401
|
-
# from synchronous task and subflow calls
|
402
|
-
sync_portal: Optional[anyio.abc.BlockingPortal] = None
|
403
|
-
timeout_scope: Optional[anyio.abc.CancelScope] = None
|
404
|
-
|
405
|
-
# Task group that can be used for background tasks during the flow run
|
406
|
-
background_tasks: anyio.abc.TaskGroup
|
407
381
|
|
408
382
|
# Events worker to emit events to Prefect Cloud
|
409
383
|
events: Optional[EventsWorker] = None
|
prefect/deployments/__init__.py
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
from prefect._internal.compatibility.migration import getattr_migration
|
1
2
|
import prefect.deployments.base
|
2
3
|
import prefect.deployments.steps
|
3
4
|
from prefect.deployments.base import (
|
@@ -15,3 +16,5 @@ from prefect.deployments.runner import (
|
|
15
16
|
from prefect.deployments.flow_runs import (
|
16
17
|
run_deployment,
|
17
18
|
)
|
19
|
+
|
20
|
+
__getattr__ = getattr_migration(__name__)
|
prefect/deployments/base.py
CHANGED
@@ -29,7 +29,7 @@ from prefect.utilities.templating import apply_values
|
|
29
29
|
|
30
30
|
|
31
31
|
def create_default_prefect_yaml(
|
32
|
-
path: str, name: str = None, contents: Optional[Dict[str, Any]] = None
|
32
|
+
path: str, name: Optional[str] = None, contents: Optional[Dict[str, Any]] = None
|
33
33
|
) -> bool:
|
34
34
|
"""
|
35
35
|
Creates default `prefect.yaml` file in the provided path if one does not already exist;
|
@@ -176,7 +176,9 @@ def _get_git_branch() -> Optional[str]:
|
|
176
176
|
|
177
177
|
|
178
178
|
def initialize_project(
|
179
|
-
name:
|
179
|
+
name: Optional[str] = None,
|
180
|
+
recipe: Optional[str] = None,
|
181
|
+
inputs: Optional[Dict[str, Any]] = None,
|
180
182
|
) -> List[str]:
|
181
183
|
"""
|
182
184
|
Initializes a basic project structure with base files. If no name is provided, the name
|
@@ -4,7 +4,7 @@ Utility project steps that are useful for managing a project's deployment lifecy
|
|
4
4
|
Steps within this module can be used within a `build`, `push`, or `pull` deployment action.
|
5
5
|
|
6
6
|
Example:
|
7
|
-
Use the `run_shell_script` setp to retrieve the short Git commit hash of the current
|
7
|
+
Use the `run_shell_script` setp to retrieve the short Git commit hash of the current
|
8
8
|
repository and use it as a Docker image tag:
|
9
9
|
```yaml
|
10
10
|
build:
|
@@ -19,6 +19,7 @@ Example:
|
|
19
19
|
dockerfile: auto
|
20
20
|
```
|
21
21
|
"""
|
22
|
+
|
22
23
|
import io
|
23
24
|
import os
|
24
25
|
import shlex
|
prefect/engine.py
CHANGED
@@ -2,6 +2,7 @@ import os
|
|
2
2
|
import sys
|
3
3
|
from uuid import UUID
|
4
4
|
|
5
|
+
from prefect._internal.compatibility.migration import getattr_migration
|
5
6
|
from prefect.exceptions import (
|
6
7
|
Abort,
|
7
8
|
Pause,
|
@@ -70,3 +71,5 @@ if __name__ == "__main__":
|
|
70
71
|
)
|
71
72
|
# Let the exit code be determined by the base exception type
|
72
73
|
raise
|
74
|
+
|
75
|
+
__getattr__ = getattr_migration(__name__)
|