prefect-client 2.16.3__py3-none-any.whl → 2.16.5__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 (48) hide show
  1. prefect/__init__.py +4 -1
  2. prefect/_internal/compatibility/deprecated.py +28 -0
  3. prefect/_internal/concurrency/calls.py +3 -2
  4. prefect/_internal/pydantic/__init__.py +2 -0
  5. prefect/_internal/pydantic/_compat.py +180 -0
  6. prefect/agent.py +14 -6
  7. prefect/artifacts.py +185 -0
  8. prefect/client/base.py +80 -10
  9. prefect/client/cloud.py +1 -1
  10. prefect/client/orchestration.py +62 -1
  11. prefect/client/schemas/actions.py +2 -0
  12. prefect/client/schemas/objects.py +16 -0
  13. prefect/client/schemas/responses.py +1 -0
  14. prefect/client/subscriptions.py +13 -7
  15. prefect/client/utilities.py +55 -28
  16. prefect/deployments/deployments.py +49 -23
  17. prefect/deployments/schedules.py +13 -0
  18. prefect/deprecated/data_documents.py +2 -2
  19. prefect/deprecated/packaging/__init__.py +12 -0
  20. prefect/{packaging → deprecated/packaging}/base.py +21 -0
  21. prefect/{packaging → deprecated/packaging}/docker.py +18 -2
  22. prefect/{packaging → deprecated/packaging}/file.py +21 -3
  23. prefect/{packaging → deprecated/packaging}/orion.py +21 -3
  24. prefect/{packaging → deprecated/packaging}/serializers.py +22 -1
  25. prefect/engine.py +10 -6
  26. prefect/events/clients.py +9 -3
  27. prefect/events/related.py +1 -1
  28. prefect/events/schemas.py +45 -1
  29. prefect/filesystems.py +39 -1
  30. prefect/flows.py +12 -4
  31. prefect/infrastructure/base.py +15 -0
  32. prefect/infrastructure/container.py +23 -0
  33. prefect/infrastructure/kubernetes.py +17 -0
  34. prefect/infrastructure/process.py +16 -0
  35. prefect/server/api/collections_data/views/aggregate-worker-metadata.json +14 -2
  36. prefect/settings.py +62 -8
  37. prefect/task_server.py +28 -5
  38. prefect/tasks.py +44 -3
  39. prefect/utilities/callables.py +3 -1
  40. prefect/utilities/schema_tools/__init__.py +11 -0
  41. prefect/variables.py +4 -4
  42. prefect/workers/base.py +6 -1
  43. {prefect_client-2.16.3.dist-info → prefect_client-2.16.5.dist-info}/METADATA +2 -1
  44. {prefect_client-2.16.3.dist-info → prefect_client-2.16.5.dist-info}/RECORD +47 -45
  45. {prefect_client-2.16.3.dist-info → prefect_client-2.16.5.dist-info}/WHEEL +1 -1
  46. prefect/packaging/__init__.py +0 -8
  47. {prefect_client-2.16.3.dist-info → prefect_client-2.16.5.dist-info}/LICENSE +0 -0
  48. {prefect_client-2.16.3.dist-info → prefect_client-2.16.5.dist-info}/top_level.txt +0 -0
@@ -15,11 +15,21 @@ from typing import (
15
15
  )
16
16
  from uuid import UUID, uuid4
17
17
 
18
+ import certifi
18
19
  import httpcore
19
20
  import httpx
20
21
  import pendulum
21
22
 
23
+ from prefect._internal.compatibility.experimental import (
24
+ EXPERIMENTAL_WARNING,
25
+ ExperimentalFeature,
26
+ experiment_enabled,
27
+ )
22
28
  from prefect._internal.pydantic import HAS_PYDANTIC_V2
29
+ from prefect.settings import (
30
+ PREFECT_EXPERIMENTAL_WARN,
31
+ PREFECT_EXPERIMENTAL_WARN_FLOW_RUN_INFRA_OVERRIDES,
32
+ )
23
33
 
24
34
  if HAS_PYDANTIC_V2:
25
35
  import pydantic.v1 as pydantic
@@ -125,8 +135,10 @@ from prefect.settings import (
125
135
  PREFECT_API_ENABLE_HTTP2,
126
136
  PREFECT_API_KEY,
127
137
  PREFECT_API_REQUEST_TIMEOUT,
138
+ PREFECT_API_SSL_CERT_FILE,
128
139
  PREFECT_API_TLS_INSECURE_SKIP_VERIFY,
129
140
  PREFECT_API_URL,
141
+ PREFECT_CLIENT_CSRF_SUPPORT_ENABLED,
130
142
  PREFECT_CLOUD_API_URL,
131
143
  PREFECT_UNIT_TEST_MODE,
132
144
  )
@@ -211,6 +223,11 @@ class PrefectClient:
211
223
 
212
224
  if PREFECT_API_TLS_INSECURE_SKIP_VERIFY:
213
225
  httpx_settings.setdefault("verify", False)
226
+ else:
227
+ cert_file = PREFECT_API_SSL_CERT_FILE.value()
228
+ if not cert_file:
229
+ cert_file = certifi.where()
230
+ httpx_settings.setdefault("verify", cert_file)
214
231
 
215
232
  if api_version is None:
216
233
  api_version = SERVER_API_VERSION
@@ -307,7 +324,15 @@ class PrefectClient:
307
324
 
308
325
  if not PREFECT_UNIT_TEST_MODE:
309
326
  httpx_settings.setdefault("follow_redirects", True)
310
- self._client = PrefectHttpxClient(**httpx_settings)
327
+
328
+ enable_csrf_support = (
329
+ self.server_type != ServerType.CLOUD
330
+ and PREFECT_CLIENT_CSRF_SUPPORT_ENABLED.value()
331
+ )
332
+
333
+ self._client = PrefectHttpxClient(
334
+ **httpx_settings, enable_csrf_support=enable_csrf_support
335
+ )
311
336
  self._loop = None
312
337
 
313
338
  # See https://www.python-httpx.org/advanced/#custom-transports
@@ -506,6 +531,7 @@ class PrefectClient:
506
531
  idempotency_key: str = None,
507
532
  parent_task_run_id: UUID = None,
508
533
  work_queue_name: str = None,
534
+ job_variables: Optional[Dict[str, Any]] = None,
509
535
  ) -> FlowRun:
510
536
  """
511
537
  Create a flow run for a deployment.
@@ -529,6 +555,7 @@ class PrefectClient:
529
555
  work_queue_name: An optional work queue name to add this run to. If not provided,
530
556
  will default to the deployment's set work queue. If one is provided that does not
531
557
  exist, a new work queue will be created within the deployment's work pool.
558
+ job_variables: Optional variables that will be supplied to the flow run job.
532
559
 
533
560
  Raises:
534
561
  httpx.RequestError: if the Prefect API does not successfully create a run for any reason
@@ -536,6 +563,21 @@ class PrefectClient:
536
563
  Returns:
537
564
  The flow run model
538
565
  """
566
+ if job_variables is not None and experiment_enabled("flow_run_infra_overrides"):
567
+ if (
568
+ PREFECT_EXPERIMENTAL_WARN
569
+ and PREFECT_EXPERIMENTAL_WARN_FLOW_RUN_INFRA_OVERRIDES
570
+ ):
571
+ warnings.warn(
572
+ EXPERIMENTAL_WARNING.format(
573
+ feature="Flow run job variables",
574
+ group="flow_run_infra_overrides",
575
+ help="To use this feature, update your workers to Prefect 2.16.4 or later. ",
576
+ ),
577
+ ExperimentalFeature,
578
+ stacklevel=3,
579
+ )
580
+
539
581
  parameters = parameters or {}
540
582
  context = context or {}
541
583
  state = state or prefect.states.Scheduled()
@@ -549,6 +591,7 @@ class PrefectClient:
549
591
  name=name,
550
592
  idempotency_key=idempotency_key,
551
593
  parent_task_run_id=parent_task_run_id,
594
+ job_variables=job_variables,
552
595
  )
553
596
 
554
597
  # done separately to avoid including this field in payloads sent to older API versions
@@ -634,6 +677,7 @@ class PrefectClient:
634
677
  tags: Optional[Iterable[str]] = None,
635
678
  empirical_policy: Optional[FlowRunPolicy] = None,
636
679
  infrastructure_pid: Optional[str] = None,
680
+ job_variables: Optional[dict] = None,
637
681
  ) -> httpx.Response:
638
682
  """
639
683
  Update a flow run's details.
@@ -654,6 +698,21 @@ class PrefectClient:
654
698
  Returns:
655
699
  an `httpx.Response` object from the PATCH request
656
700
  """
701
+ if job_variables is not None and experiment_enabled("flow_run_infra_overrides"):
702
+ if (
703
+ PREFECT_EXPERIMENTAL_WARN
704
+ and PREFECT_EXPERIMENTAL_WARN_FLOW_RUN_INFRA_OVERRIDES
705
+ ):
706
+ warnings.warn(
707
+ EXPERIMENTAL_WARNING.format(
708
+ feature="Flow run job variables",
709
+ group="flow_run_infra_overrides",
710
+ help="To use this feature, update your workers to Prefect 2.16.4 or later. ",
711
+ ),
712
+ ExperimentalFeature,
713
+ stacklevel=3,
714
+ )
715
+
657
716
  params = {}
658
717
  if flow_version is not None:
659
718
  params["flow_version"] = flow_version
@@ -667,6 +726,8 @@ class PrefectClient:
667
726
  params["empirical_policy"] = empirical_policy
668
727
  if infrastructure_pid:
669
728
  params["infrastructure_pid"] = infrastructure_pid
729
+ if job_variables is not None:
730
+ params["job_variables"] = job_variables
670
731
 
671
732
  flow_run_data = FlowRunUpdate(**params)
672
733
 
@@ -298,6 +298,7 @@ class FlowRunUpdate(ActionBaseModel):
298
298
  empirical_policy: objects.FlowRunPolicy = FieldFrom(objects.FlowRun)
299
299
  tags: List[str] = FieldFrom(objects.FlowRun)
300
300
  infrastructure_pid: Optional[str] = FieldFrom(objects.FlowRun)
301
+ job_variables: Optional[dict] = FieldFrom(objects.FlowRun)
301
302
 
302
303
 
303
304
  @copy_model_fields
@@ -380,6 +381,7 @@ class DeploymentFlowRunCreate(ActionBaseModel):
380
381
  idempotency_key: Optional[str] = FieldFrom(objects.FlowRun)
381
382
  parent_task_run_id: Optional[UUID] = FieldFrom(objects.FlowRun)
382
383
  work_queue_name: Optional[str] = FieldFrom(objects.FlowRun)
384
+ job_variables: Optional[dict] = FieldFrom(objects.FlowRun)
383
385
 
384
386
 
385
387
  @copy_model_fields
@@ -526,6 +526,9 @@ class FlowRun(ObjectBaseModel):
526
526
  description="The state of the flow run.",
527
527
  example=State(type=StateType.COMPLETED),
528
528
  )
529
+ job_variables: Optional[dict] = Field(
530
+ default=None, description="Job variables for the flow run."
531
+ )
529
532
 
530
533
  def __eq__(self, other: Any) -> bool:
531
534
  """
@@ -1629,3 +1632,16 @@ class GlobalConcurrencyLimit(ObjectBaseModel):
1629
1632
  " is used as a rate limit."
1630
1633
  ),
1631
1634
  )
1635
+
1636
+
1637
+ class CsrfToken(ObjectBaseModel):
1638
+ token: str = Field(
1639
+ default=...,
1640
+ description="The CSRF token",
1641
+ )
1642
+ client: str = Field(
1643
+ default=..., description="The client id associated with the CSRF token"
1644
+ )
1645
+ expiration: DateTimeTZ = Field(
1646
+ default=..., description="The expiration time of the CSRF token"
1647
+ )
@@ -190,6 +190,7 @@ class FlowRunResponse(ObjectBaseModel):
190
190
  example="my-work-pool",
191
191
  )
192
192
  state: Optional[objects.State] = FieldFrom(objects.FlowRun)
193
+ job_variables: Optional[dict] = FieldFrom(objects.FlowRun)
193
194
 
194
195
  def __eq__(self, other: Any) -> bool:
195
196
  """
@@ -1,5 +1,5 @@
1
1
  import asyncio
2
- from typing import Generic, List, Optional, Type, TypeVar
2
+ from typing import Any, Dict, Generic, List, Optional, Type, TypeVar
3
3
 
4
4
  import orjson
5
5
  import websockets
@@ -71,23 +71,29 @@ class Subscription(Generic[S]):
71
71
  ).decode()
72
72
  )
73
73
 
74
- auth = orjson.loads(await websocket.recv())
75
- assert auth["type"] == "auth_success"
74
+ auth: Dict[str, Any] = orjson.loads(await websocket.recv())
75
+ assert auth["type"] == "auth_success", auth.get("message")
76
76
 
77
- message = {"type": "subscribe", "keys": self.keys} | {
78
- **(dict(client_id=self.client_id) if self.client_id else {})
79
- }
77
+ message = {"type": "subscribe", "keys": self.keys}
78
+ if self.client_id:
79
+ message.update({"client_id": self.client_id})
80
80
 
81
81
  await websocket.send(orjson.dumps(message).decode())
82
82
  except (
83
83
  AssertionError,
84
84
  websockets.exceptions.ConnectionClosedError,
85
85
  ) as e:
86
+ if isinstance(e, AssertionError) or e.code == WS_1008_POLICY_VIOLATION:
87
+ if isinstance(e, AssertionError):
88
+ reason = e.args[0]
89
+ elif isinstance(e, websockets.exceptions.ConnectionClosedError):
90
+ reason = e.reason
91
+
86
92
  if isinstance(e, AssertionError) or e.code == WS_1008_POLICY_VIOLATION:
87
93
  raise Exception(
88
94
  "Unable to authenticate to the subscription. Please "
89
95
  "ensure the provided `PREFECT_API_KEY` you are using is "
90
- "valid for this environment."
96
+ f"valid for this environment. Reason: {reason}"
91
97
  ) from e
92
98
  raise
93
99
  else:
@@ -1,16 +1,60 @@
1
1
  """
2
2
  Utilities for working with clients.
3
3
  """
4
+
4
5
  # This module must not import from `prefect.client` when it is imported to avoid
5
6
  # circular imports for decorators such as `inject_client` which are widely used.
6
7
 
7
8
  from functools import wraps
9
+ from typing import TYPE_CHECKING, Any, Callable, Coroutine, Optional, Tuple, cast
10
+
11
+ from typing_extensions import ParamSpec
12
+
13
+ if TYPE_CHECKING:
14
+ from prefect.client.orchestration import PrefectClient
15
+
16
+ P = ParamSpec("P")
17
+
18
+
19
+ def get_or_create_client(
20
+ client: Optional["PrefectClient"] = None,
21
+ ) -> Tuple["PrefectClient", bool]:
22
+ """
23
+ Returns provided client, infers a client from context if available, or creates a new client.
8
24
 
9
- from prefect._internal.concurrency.event_loop import get_running_loop
10
- from prefect.utilities.asyncutils import asyncnullcontext
25
+ Args:
26
+ - client (PrefectClient, optional): an optional client to use
11
27
 
28
+ Returns:
29
+ - tuple: a tuple of the client and a boolean indicating if the client was inferred from context
30
+ """
31
+ if client is not None:
32
+ return client, True
33
+ from prefect._internal.concurrency.event_loop import get_running_loop
34
+ from prefect.context import FlowRunContext, TaskRunContext
35
+
36
+ flow_run_context = FlowRunContext.get()
37
+ task_run_context = TaskRunContext.get()
38
+
39
+ if (
40
+ flow_run_context
41
+ and getattr(flow_run_context.client, "_loop") == get_running_loop()
42
+ ):
43
+ return flow_run_context.client, True
44
+ elif (
45
+ task_run_context
46
+ and getattr(task_run_context.client, "_loop") == get_running_loop()
47
+ ):
48
+ return task_run_context.client, True
49
+ else:
50
+ from prefect.client.orchestration import get_client as get_httpx_client
51
+
52
+ return get_httpx_client(), False
12
53
 
13
- def inject_client(fn):
54
+
55
+ def inject_client(
56
+ fn: Callable[P, Coroutine[Any, Any, Any]],
57
+ ) -> Callable[P, Coroutine[Any, Any, Any]]:
14
58
  """
15
59
  Simple helper to provide a context managed client to a asynchronous function.
16
60
 
@@ -20,33 +64,16 @@ def inject_client(fn):
20
64
  """
21
65
 
22
66
  @wraps(fn)
23
- async def with_injected_client(*args, **kwargs):
24
- from prefect.client.orchestration import get_client
25
- from prefect.context import FlowRunContext, TaskRunContext
26
-
27
- flow_run_context = FlowRunContext.get()
28
- task_run_context = TaskRunContext.get()
29
- client = None
30
- client_context = asyncnullcontext()
31
-
32
- if "client" in kwargs and kwargs["client"] is not None:
33
- # Client provided in kwargs
34
- client = kwargs["client"]
35
- elif flow_run_context and flow_run_context.client._loop == get_running_loop():
36
- # Client available from flow run context
37
- client = flow_run_context.client
38
- elif task_run_context and task_run_context.client._loop == get_running_loop():
39
- # Client available from task run context
40
- client = task_run_context.client
41
-
67
+ async def with_injected_client(*args: P.args, **kwargs: P.kwargs) -> Any:
68
+ client = cast(Optional["PrefectClient"], kwargs.pop("client", None))
69
+ client, inferred = get_or_create_client(client)
70
+ if not inferred:
71
+ context = client
42
72
  else:
43
- # A new client is needed
44
- client_context = get_client()
45
-
46
- # Removes existing client to allow it to be set by setdefault below
47
- kwargs.pop("client", None)
73
+ from prefect.utilities.asyncutils import asyncnullcontext
48
74
 
49
- async with client_context as new_client:
75
+ context = asyncnullcontext()
76
+ async with context as new_client:
50
77
  kwargs.setdefault("client", new_client or client)
51
78
  return await fn(*args, **kwargs)
52
79
 
@@ -16,6 +16,10 @@ import anyio
16
16
  import pendulum
17
17
  import yaml
18
18
 
19
+ from prefect._internal.compatibility.deprecated import (
20
+ deprecated_callable,
21
+ deprecated_class,
22
+ )
19
23
  from prefect._internal.pydantic import HAS_PYDANTIC_V2
20
24
  from prefect.client.schemas.actions import DeploymentScheduleCreate
21
25
 
@@ -24,12 +28,10 @@ if HAS_PYDANTIC_V2:
24
28
  else:
25
29
  from pydantic import BaseModel, Field, parse_obj_as, root_validator, validator
26
30
 
27
- from prefect._internal.compatibility.experimental import experimental_field
28
31
  from prefect.blocks.core import Block
29
32
  from prefect.blocks.fields import SecretDict
30
33
  from prefect.client.orchestration import PrefectClient, ServerType, get_client
31
34
  from prefect.client.schemas.objects import (
32
- DEFAULT_AGENT_WORK_POOL_NAME,
33
35
  FlowRun,
34
36
  MinimalDeploymentSchedule,
35
37
  )
@@ -38,6 +40,7 @@ from prefect.client.utilities import inject_client
38
40
  from prefect.context import FlowRunContext, PrefectObjectRegistry, TaskRunContext
39
41
  from prefect.deployments.schedules import (
40
42
  FlexibleScheduleList,
43
+ create_minimal_deployment_schedule,
41
44
  normalize_to_minimal_deployment_schedules,
42
45
  )
43
46
  from prefect.deployments.steps.core import run_steps
@@ -53,6 +56,7 @@ from prefect.infrastructure import Infrastructure, Process
53
56
  from prefect.logging.loggers import flow_run_logger, get_logger
54
57
  from prefect.states import Scheduled
55
58
  from prefect.tasks import Task
59
+ from prefect.utilities.annotations import NotSet
56
60
  from prefect.utilities.asyncutils import run_sync_in_worker_thread, sync_compatible
57
61
  from prefect.utilities.callables import ParameterSchema, parameter_schema
58
62
  from prefect.utilities.filesystem import relative_path_to_current_platform, tmpchdir
@@ -75,6 +79,7 @@ async def run_deployment(
75
79
  idempotency_key: Optional[str] = None,
76
80
  work_queue_name: Optional[str] = None,
77
81
  as_subflow: Optional[bool] = True,
82
+ job_variables: Optional[dict] = None,
78
83
  ) -> FlowRun:
79
84
  """
80
85
  Create a flow run for a deployment and return it after completion or a timeout.
@@ -194,6 +199,7 @@ async def run_deployment(
194
199
  idempotency_key=idempotency_key,
195
200
  parent_task_run_id=parent_task_run_id,
196
201
  work_queue_name=work_queue_name,
202
+ job_variables=job_variables,
197
203
  )
198
204
 
199
205
  flow_run_id = flow_run.id
@@ -293,6 +299,7 @@ async def load_flow_from_flow_run(
293
299
  return flow
294
300
 
295
301
 
302
+ @deprecated_callable(start_date="Mar 2024")
296
303
  def load_deployments_from_yaml(
297
304
  path: str,
298
305
  ) -> PrefectObjectRegistry:
@@ -316,13 +323,20 @@ def load_deployments_from_yaml(
316
323
  return registry
317
324
 
318
325
 
319
- @experimental_field(
320
- "work_pool_name",
321
- group="work_pools",
322
- when=lambda x: x is not None and x != DEFAULT_AGENT_WORK_POOL_NAME,
326
+ @deprecated_class(
327
+ start_date="Mar 2024",
328
+ help="Use `flow.deploy` to deploy your flows instead."
329
+ " Refer to the upgrade guide for more information:"
330
+ " https://docs.prefect.io/latest/guides/upgrade-guide-agents-to-workers/.",
323
331
  )
324
332
  class Deployment(BaseModel):
325
333
  """
334
+ DEPRECATION WARNING:
335
+
336
+ This class is deprecated as of March 2024 and will not be available after September 2024.
337
+ It has been replaced by `flow.deploy`, which offers enhanced functionality and better a better user experience.
338
+ For upgrade instructions, see https://docs.prefect.io/latest/guides/upgrade-guide-agents-to-workers/.
339
+
326
340
  A Prefect Deployment definition, used for specifying and building deployments.
327
341
 
328
342
  Args:
@@ -647,21 +661,27 @@ class Deployment(BaseModel):
647
661
  )
648
662
  return values
649
663
 
650
- @validator("schedule")
651
- def validate_schedule(cls, value):
652
- if value:
653
- cls._validate_schedule(value)
654
- return value
655
-
656
664
  @root_validator(pre=True)
657
- def validate_schedules(cls, values):
658
- if "schedules" in values:
659
- values["schedules"] = normalize_to_minimal_deployment_schedules(
660
- values["schedules"]
661
- )
665
+ def reconcile_schedules(cls, values):
666
+ schedule = values.get("schedule", NotSet)
667
+ schedules = values.get("schedules", NotSet)
662
668
 
663
- for schedule in values["schedules"]:
664
- cls._validate_schedule(schedule.schedule)
669
+ if schedules is not NotSet:
670
+ values["schedules"] = normalize_to_minimal_deployment_schedules(schedules)
671
+ elif schedule is not NotSet:
672
+ values["schedule"] = None
673
+
674
+ if schedule is None:
675
+ values["schedules"] = []
676
+ else:
677
+ values["schedules"] = [
678
+ create_minimal_deployment_schedule(
679
+ schedule=schedule, active=values.get("is_schedule_active")
680
+ )
681
+ ]
682
+
683
+ for schedule in values.get("schedules", []):
684
+ cls._validate_schedule(schedule.schedule)
665
685
 
666
686
  return values
667
687
 
@@ -982,11 +1002,17 @@ class Deployment(BaseModel):
982
1002
 
983
1003
  # note that `deployment.load` only updates settings that were *not*
984
1004
  # provided at initialization
985
- deployment = cls(
986
- name=name,
987
- schedules=schedules,
1005
+
1006
+ deployment_args = {
1007
+ "name": name,
1008
+ "flow_name": flow.name,
988
1009
  **kwargs,
989
- )
1010
+ }
1011
+
1012
+ if schedules is not None:
1013
+ deployment_args["schedules"] = schedules
1014
+
1015
+ deployment = cls(**deployment_args)
990
1016
  deployment.flow_name = flow.name
991
1017
  if not deployment.entrypoint:
992
1018
  ## first see if an entrypoint can be determined
@@ -3,6 +3,14 @@ from typing import List, Optional, Sequence, Union, get_args
3
3
  from prefect.client.schemas.objects import MinimalDeploymentSchedule
4
4
  from prefect.client.schemas.schedules import SCHEDULE_TYPES
5
5
 
6
+ try:
7
+ from prefect.server.schemas.schedules import SCHEDULE_TYPES as SERVER_SCHEDULE_TYPES
8
+
9
+ SERVER_SCHEDULE_TYPES = get_args(SERVER_SCHEDULE_TYPES)
10
+ except ImportError:
11
+ # `prefect-client` does not have access to the server schemas.
12
+ SERVER_SCHEDULE_TYPES = ()
13
+
6
14
  FlexibleScheduleList = Sequence[Union[MinimalDeploymentSchedule, dict, SCHEDULE_TYPES]]
7
15
 
8
16
 
@@ -28,6 +36,11 @@ def normalize_to_minimal_deployment_schedules(
28
36
  normalized.append(create_minimal_deployment_schedule(**obj))
29
37
  elif isinstance(obj, MinimalDeploymentSchedule):
30
38
  normalized.append(obj)
39
+ elif isinstance(obj, SERVER_SCHEDULE_TYPES):
40
+ raise ValueError(
41
+ "Server schema schedules are not supported. Please use "
42
+ "the schedule objects from `prefect.client.schemas.schedules`"
43
+ )
31
44
  else:
32
45
  raise ValueError(
33
46
  "Invalid schedule provided. Must be a schedule object, a dict,"
@@ -32,7 +32,7 @@ from prefect._internal.compatibility.deprecated import (
32
32
  from prefect._internal.schemas.bases import PrefectBaseModel
33
33
 
34
34
  if TYPE_CHECKING:
35
- from prefect.packaging.base import PackageManifest
35
+ from prefect.deprecated.packaging.base import PackageManifest
36
36
 
37
37
  T = TypeVar("T", bound="DataDocument") # Generic for DataDocument class types
38
38
  D = TypeVar("D", bound=Any) # Generic for DataDocument data types
@@ -243,7 +243,7 @@ class PackageManifestSerializer:
243
243
 
244
244
  @staticmethod
245
245
  def loads(blob: bytes) -> "PackageManifest":
246
- from prefect.packaging.base import PackageManifest
246
+ from prefect.deprecated.packaging.base import PackageManifest
247
247
 
248
248
  return PackageManifest.parse_raw(blob)
249
249
 
@@ -0,0 +1,12 @@
1
+ """
2
+ DEPRECATION WARNING:
3
+ This module is deprecated as of March 2024 and will not be available after September 2024.
4
+ """
5
+ from prefect.deprecated.packaging.docker import DockerPackager
6
+ from prefect.deprecated.packaging.file import FilePackager
7
+ from prefect.deprecated.packaging.orion import OrionPackager
8
+
9
+ # isort: split
10
+
11
+ # Register any packaging serializers
12
+ import prefect.deprecated.packaging.serializers
@@ -1,6 +1,12 @@
1
+ """
2
+ DEPRECATION WARNING:
3
+ This module is deprecated as of March 2024 and will not be available after September 2024.
4
+ """
5
+
1
6
  import abc
2
7
  from typing import Generic, TypeVar
3
8
 
9
+ from prefect._internal.compatibility.deprecated import deprecated_class
4
10
  from prefect._internal.pydantic import HAS_PYDANTIC_V2
5
11
 
6
12
  if HAS_PYDANTIC_V2:
@@ -16,9 +22,14 @@ from prefect.utilities.pydantic import PartialModel, add_type_dispatch
16
22
  D = TypeVar("D")
17
23
 
18
24
 
25
+ @deprecated_class(start_date="Mar 2024")
19
26
  @add_type_dispatch
20
27
  class Serializer(BaseModel, Generic[D], abc.ABC):
21
28
  """
29
+ DEPRECATION WARNING:
30
+
31
+ This class is deprecated as of version March 2024 and will not be available after September 2024.
32
+
22
33
  A serializer that can encode objects of type 'D' into bytes.
23
34
  """
24
35
 
@@ -31,9 +42,14 @@ class Serializer(BaseModel, Generic[D], abc.ABC):
31
42
  """Decode the blob of bytes into an object."""
32
43
 
33
44
 
45
+ @deprecated_class(start_date="Mar 2024")
34
46
  @add_type_dispatch
35
47
  class PackageManifest(BaseModel, abc.ABC):
36
48
  """
49
+ DEPRECATION WARNING:
50
+
51
+ This class is deprecated as of version March 2024 and will not be available after September 2024.
52
+
37
53
  Describes a package.
38
54
  """
39
55
 
@@ -48,9 +64,14 @@ class PackageManifest(BaseModel, abc.ABC):
48
64
  """
49
65
 
50
66
 
67
+ @deprecated_class(start_date="Mar 2024")
51
68
  @add_type_dispatch
52
69
  class Packager(BaseModel, abc.ABC):
53
70
  """
71
+ DEPRECATION WARNING:
72
+
73
+ This class is deprecated as of version March 2024 and will not be available after September 2024.
74
+
54
75
  Creates a package for a flow.
55
76
 
56
77
  A package contains the flow and is typically stored outside of Prefect. To
@@ -1,8 +1,14 @@
1
+ """
2
+ DEPRECATION WARNING:
3
+ This module is deprecated as of March 2024 and will not be available after September 2024.
4
+ """
5
+
1
6
  import json
2
7
  import sys
3
8
  from pathlib import Path
4
9
  from typing import Any, Mapping, Optional, Union
5
10
 
11
+ from prefect._internal.compatibility.deprecated import deprecated_class
6
12
  from prefect._internal.pydantic import HAS_PYDANTIC_V2
7
13
 
8
14
  if HAS_PYDANTIC_V2:
@@ -11,9 +17,9 @@ else:
11
17
  from pydantic import AnyHttpUrl, root_validator, validator
12
18
  from typing_extensions import Literal
13
19
 
20
+ from prefect.deprecated.packaging.base import PackageManifest, Packager
21
+ from prefect.deprecated.packaging.serializers import SourceSerializer
14
22
  from prefect.flows import Flow, load_flow_from_script
15
- from prefect.packaging.base import PackageManifest, Packager
16
- from prefect.packaging.serializers import SourceSerializer
17
23
  from prefect.software import CondaEnvironment, PythonEnvironment
18
24
  from prefect.utilities.asyncutils import run_sync_in_worker_thread
19
25
  from prefect.utilities.dockerutils import (
@@ -26,8 +32,13 @@ from prefect.utilities.dockerutils import (
26
32
  from prefect.utilities.slugify import slugify
27
33
 
28
34
 
35
+ @deprecated_class(start_date="Mar 2024")
29
36
  class DockerPackageManifest(PackageManifest):
30
37
  """
38
+ DEPRECATION WARNING:
39
+
40
+ This class is deprecated as of version March 2024 and will not be available after September 2024.
41
+
31
42
  Represents a flow packaged in a Docker image
32
43
  """
33
44
 
@@ -40,8 +51,13 @@ class DockerPackageManifest(PackageManifest):
40
51
  return load_flow_from_script(self.image_flow_location, self.flow_name)
41
52
 
42
53
 
54
+ @deprecated_class(start_date="Mar 2024")
43
55
  class DockerPackager(Packager):
44
56
  """
57
+ DEPRECATION WARNING:
58
+
59
+ This class is deprecated as of version March 2024 and will not be available after September 2024.
60
+
45
61
  This packager builds a Docker image containing the flow and the runtime environment
46
62
  necessary to run the flow. The resulting image is optionally pushed to a container
47
63
  registry, given by `registry_url`.