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.
Files changed (69) hide show
  1. prefect/__init__.py +0 -1
  2. prefect/_internal/compatibility/migration.py +124 -0
  3. prefect/_internal/concurrency/__init__.py +2 -2
  4. prefect/_internal/concurrency/primitives.py +1 -0
  5. prefect/_internal/pydantic/annotations/pendulum.py +2 -2
  6. prefect/_internal/pytz.py +1 -1
  7. prefect/blocks/core.py +1 -1
  8. prefect/client/orchestration.py +96 -22
  9. prefect/client/schemas/actions.py +1 -1
  10. prefect/client/schemas/filters.py +6 -0
  11. prefect/client/schemas/objects.py +10 -3
  12. prefect/client/subscriptions.py +6 -5
  13. prefect/context.py +1 -27
  14. prefect/deployments/__init__.py +3 -0
  15. prefect/deployments/base.py +4 -2
  16. prefect/deployments/deployments.py +3 -0
  17. prefect/deployments/steps/pull.py +1 -0
  18. prefect/deployments/steps/utility.py +2 -1
  19. prefect/engine.py +3 -0
  20. prefect/events/cli/automations.py +1 -1
  21. prefect/events/clients.py +7 -1
  22. prefect/exceptions.py +9 -0
  23. prefect/filesystems.py +22 -11
  24. prefect/flow_engine.py +195 -153
  25. prefect/flows.py +95 -36
  26. prefect/futures.py +9 -1
  27. prefect/infrastructure/provisioners/container_instance.py +1 -0
  28. prefect/infrastructure/provisioners/ecs.py +2 -2
  29. prefect/input/__init__.py +4 -0
  30. prefect/logging/formatters.py +2 -2
  31. prefect/logging/handlers.py +2 -2
  32. prefect/logging/loggers.py +1 -1
  33. prefect/plugins.py +1 -0
  34. prefect/records/cache_policies.py +3 -3
  35. prefect/records/result_store.py +10 -3
  36. prefect/results.py +47 -73
  37. prefect/runner/runner.py +1 -1
  38. prefect/runner/server.py +1 -1
  39. prefect/runtime/__init__.py +1 -0
  40. prefect/runtime/deployment.py +1 -0
  41. prefect/runtime/flow_run.py +1 -0
  42. prefect/runtime/task_run.py +1 -0
  43. prefect/settings.py +16 -3
  44. prefect/states.py +15 -4
  45. prefect/task_engine.py +195 -39
  46. prefect/task_runners.py +9 -3
  47. prefect/task_runs.py +26 -12
  48. prefect/task_worker.py +149 -20
  49. prefect/tasks.py +153 -71
  50. prefect/transactions.py +85 -15
  51. prefect/types/__init__.py +10 -3
  52. prefect/utilities/asyncutils.py +3 -3
  53. prefect/utilities/callables.py +16 -4
  54. prefect/utilities/collections.py +120 -57
  55. prefect/utilities/dockerutils.py +5 -3
  56. prefect/utilities/engine.py +11 -0
  57. prefect/utilities/filesystem.py +4 -5
  58. prefect/utilities/importtools.py +29 -0
  59. prefect/utilities/services.py +2 -2
  60. prefect/utilities/urls.py +195 -0
  61. prefect/utilities/visualization.py +1 -0
  62. prefect/variables.py +4 -0
  63. prefect/workers/base.py +35 -0
  64. {prefect_client-3.0.0rc2.dist-info → prefect_client-3.0.0rc4.dist-info}/METADATA +2 -2
  65. {prefect_client-3.0.0rc2.dist-info → prefect_client-3.0.0rc4.dist-info}/RECORD +68 -66
  66. prefect/blocks/kubernetes.py +0 -115
  67. {prefect_client-3.0.0rc2.dist-info → prefect_client-3.0.0rc4.dist-info}/LICENSE +0 -0
  68. {prefect_client-3.0.0rc2.dist-info → prefect_client-3.0.0rc4.dist-info}/WHEEL +0 -0
  69. {prefect_client-3.0.0rc2.dist-info → prefect_client-3.0.0rc4.dist-info}/top_level.txt +0 -0
prefect/__init__.py CHANGED
@@ -43,7 +43,6 @@ import prefect.runtime
43
43
 
44
44
  # Import modules that register types
45
45
  import prefect.serializers
46
- import prefect.blocks.kubernetes
47
46
  import prefect.blocks.notifications
48
47
  import prefect.blocks.system
49
48
 
@@ -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
@@ -1,6 +1,7 @@
1
1
  """
2
2
  Thread-safe async synchronization primitives.
3
3
  """
4
+
4
5
  import asyncio
5
6
  import collections
6
7
  import threading
@@ -1,6 +1,6 @@
1
1
  """
2
- This file contains compat code to handle pendulum.DateTime objects during jsonschema
3
- generation and validation.
2
+ This file contains compat code to handle pendulum.DateTime objects during jsonschema
3
+ generation and validation.
4
4
  """
5
5
 
6
6
  import typing as t
prefect/_internal/pytz.py CHANGED
@@ -1,5 +1,5 @@
1
1
  """
2
- This is a compatibility module that allows us to drop our dependency on pytz in the minimal prefect-client.
2
+ This is a compatibility module that allows us to drop our dependency on pytz in the minimal prefect-client.
3
3
 
4
4
  All values here are taken from:
5
5
 
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: type[GenerateJsonSchema] = GenerateJsonSchema,
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?"""
@@ -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[NonNegativeInteger] = Field(None)
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
- def populate_deprecated_fields(cls, values):
426
- return set_run_policy_deprecated_fields(values)
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
- return validate_parent_and_ref_diff(values)
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):
@@ -1,5 +1,5 @@
1
1
  import asyncio
2
- from typing import Any, Dict, Generic, List, Optional, Type, TypeVar
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, PREFECT_API_URL
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: List[str],
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 = PREFECT_API_URL.value().replace("http", "ws", 1)
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 objects created by this flow run
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
@@ -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__)
@@ -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: str = None, recipe: str = None, inputs: Optional[Dict[str, Any]] = None
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
@@ -0,0 +1,3 @@
1
+ from .._internal.compatibility.migration import getattr_migration
2
+
3
+ __getattr__ = getattr_migration(__name__)
@@ -1,6 +1,7 @@
1
1
  """
2
2
  Core set of steps for specifying a Prefect project pull step.
3
3
  """
4
+
4
5
  import os
5
6
  from pathlib import Path
6
7
  from typing import TYPE_CHECKING, Any, Optional
@@ -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__)
@@ -23,7 +23,7 @@ from prefect.exceptions import PrefectHTTPStatusError
23
23
 
24
24
  automations_app = PrefectTyper(
25
25
  name="automation",
26
- help="Commands for managing automations.",
26
+ help="Manage automations.",
27
27
  )
28
28
  app.add_typer(automations_app, aliases=["automations"])
29
29