prefect-client 2.17.1__py3-none-any.whl → 2.18.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.
Files changed (71) hide show
  1. prefect/_internal/compatibility/deprecated.py +2 -0
  2. prefect/_internal/pydantic/_compat.py +1 -0
  3. prefect/_internal/pydantic/utilities/field_validator.py +25 -10
  4. prefect/_internal/pydantic/utilities/model_dump.py +1 -1
  5. prefect/_internal/pydantic/utilities/model_validate.py +1 -1
  6. prefect/_internal/pydantic/utilities/model_validator.py +11 -3
  7. prefect/_internal/schemas/fields.py +31 -12
  8. prefect/_internal/schemas/validators.py +0 -6
  9. prefect/_version.py +97 -38
  10. prefect/blocks/abstract.py +34 -1
  11. prefect/blocks/core.py +1 -1
  12. prefect/blocks/notifications.py +16 -7
  13. prefect/blocks/system.py +2 -3
  14. prefect/client/base.py +10 -5
  15. prefect/client/orchestration.py +405 -85
  16. prefect/client/schemas/actions.py +4 -3
  17. prefect/client/schemas/objects.py +6 -5
  18. prefect/client/schemas/schedules.py +2 -6
  19. prefect/client/schemas/sorting.py +9 -0
  20. prefect/client/utilities.py +25 -3
  21. prefect/concurrency/asyncio.py +11 -5
  22. prefect/concurrency/events.py +3 -3
  23. prefect/concurrency/services.py +1 -1
  24. prefect/concurrency/sync.py +9 -5
  25. prefect/deployments/__init__.py +0 -2
  26. prefect/deployments/base.py +2 -144
  27. prefect/deployments/deployments.py +29 -20
  28. prefect/deployments/runner.py +36 -28
  29. prefect/deployments/steps/core.py +3 -3
  30. prefect/deprecated/packaging/serializers.py +5 -4
  31. prefect/engine.py +3 -1
  32. prefect/events/__init__.py +45 -0
  33. prefect/events/actions.py +250 -18
  34. prefect/events/cli/automations.py +201 -0
  35. prefect/events/clients.py +179 -21
  36. prefect/events/filters.py +30 -3
  37. prefect/events/instrument.py +40 -40
  38. prefect/events/related.py +2 -1
  39. prefect/events/schemas/automations.py +126 -8
  40. prefect/events/schemas/deployment_triggers.py +23 -277
  41. prefect/events/schemas/events.py +7 -7
  42. prefect/events/utilities.py +3 -1
  43. prefect/events/worker.py +21 -8
  44. prefect/exceptions.py +1 -1
  45. prefect/flows.py +33 -18
  46. prefect/input/actions.py +9 -9
  47. prefect/input/run_input.py +49 -37
  48. prefect/logging/__init__.py +2 -2
  49. prefect/logging/loggers.py +64 -1
  50. prefect/new_flow_engine.py +293 -0
  51. prefect/new_task_engine.py +374 -0
  52. prefect/results.py +32 -12
  53. prefect/runner/runner.py +3 -2
  54. prefect/serializers.py +62 -31
  55. prefect/server/api/collections_data/views/aggregate-worker-metadata.json +44 -3
  56. prefect/settings.py +32 -10
  57. prefect/states.py +25 -19
  58. prefect/tasks.py +17 -0
  59. prefect/types/__init__.py +90 -0
  60. prefect/utilities/asyncutils.py +37 -0
  61. prefect/utilities/engine.py +6 -4
  62. prefect/utilities/pydantic.py +34 -15
  63. prefect/utilities/schema_tools/hydration.py +88 -19
  64. prefect/utilities/schema_tools/validation.py +1 -1
  65. prefect/variables.py +4 -4
  66. {prefect_client-2.17.1.dist-info → prefect_client-2.18.1.dist-info}/METADATA +1 -1
  67. {prefect_client-2.17.1.dist-info → prefect_client-2.18.1.dist-info}/RECORD +71 -67
  68. /prefect/{concurrency/common.py → events/cli/__init__.py} +0 -0
  69. {prefect_client-2.17.1.dist-info → prefect_client-2.18.1.dist-info}/LICENSE +0 -0
  70. {prefect_client-2.17.1.dist-info → prefect_client-2.18.1.dist-info}/WHEEL +0 -0
  71. {prefect_client-2.17.1.dist-info → prefect_client-2.18.1.dist-info}/top_level.txt +0 -0
@@ -1,4 +1,5 @@
1
1
  import abc
2
+ import textwrap
2
3
  from datetime import timedelta
3
4
  from enum import Enum
4
5
  from typing import (
@@ -9,23 +10,24 @@ from typing import (
9
10
  Optional,
10
11
  Set,
11
12
  Union,
13
+ cast,
12
14
  )
13
15
  from uuid import UUID
14
16
 
15
17
  from typing_extensions import TypeAlias
16
18
 
17
19
  from prefect._internal.pydantic import HAS_PYDANTIC_V2
18
- from prefect._internal.schemas.validators import validate_trigger_within
19
20
 
20
21
  if HAS_PYDANTIC_V2:
21
- from pydantic.v1 import Field, root_validator, validator
22
+ from pydantic.v1 import Field, PrivateAttr, root_validator, validator
22
23
  from pydantic.v1.fields import ModelField
23
24
  else:
24
- from pydantic import Field, root_validator, validator
25
- from pydantic.fields import ModelField
25
+ from pydantic import Field, PrivateAttr, root_validator, validator # type: ignore
26
+ from pydantic.fields import ModelField # type: ignore
26
27
 
27
28
  from prefect._internal.schemas.bases import PrefectBaseModel
28
- from prefect.events.actions import ActionTypes
29
+ from prefect._internal.schemas.validators import validate_trigger_within
30
+ from prefect.events.actions import ActionTypes, RunDeployment
29
31
  from prefect.utilities.collections import AutoEnum
30
32
 
31
33
  from .events import ResourceSpecification
@@ -45,6 +47,54 @@ class Trigger(PrefectBaseModel, abc.ABC, extra="ignore"):
45
47
 
46
48
  type: str
47
49
 
50
+ @abc.abstractmethod
51
+ def describe_for_cli(self, indent: int = 0) -> str:
52
+ """Return a human-readable description of this trigger for the CLI"""
53
+
54
+ # The following allows the regular Trigger class to be used when serving or
55
+ # deploying flows, analogous to how the Deployment*Trigger classes work
56
+
57
+ _deployment_id: Optional[UUID] = PrivateAttr(default=None)
58
+
59
+ def set_deployment_id(self, deployment_id: UUID):
60
+ self._deployment_id = deployment_id
61
+
62
+ def owner_resource(self) -> Optional[str]:
63
+ return f"prefect.deployment.{self._deployment_id}"
64
+
65
+ def actions(self) -> List[ActionTypes]:
66
+ assert self._deployment_id
67
+ return [
68
+ RunDeployment(
69
+ source="selected",
70
+ deployment_id=self._deployment_id,
71
+ parameters=getattr(self, "parameters", None),
72
+ job_variables=getattr(self, "job_variables", None),
73
+ )
74
+ ]
75
+
76
+ def as_automation(self) -> "AutomationCore":
77
+ assert self._deployment_id
78
+
79
+ trigger: TriggerTypes = cast(TriggerTypes, self)
80
+
81
+ # This is one of the Deployment*Trigger classes, so translate it over to a
82
+ # plain Trigger
83
+ if hasattr(self, "trigger_type"):
84
+ trigger = self.trigger_type(**self.dict())
85
+
86
+ return AutomationCore(
87
+ name=(
88
+ getattr(self, "name", None)
89
+ or f"Automation for deployment {self._deployment_id}"
90
+ ),
91
+ description="",
92
+ enabled=getattr(self, "enabled", True),
93
+ trigger=trigger,
94
+ actions=self.actions(),
95
+ owner_resource=self.owner_resource(),
96
+ )
97
+
48
98
 
49
99
  class ResourceTrigger(Trigger, abc.ABC):
50
100
  """
@@ -101,7 +151,7 @@ class EventTrigger(ResourceTrigger):
101
151
  ),
102
152
  )
103
153
  posture: Literal[Posture.Reactive, Posture.Proactive] = Field( # type: ignore[valid-type]
104
- ...,
154
+ Posture.Reactive,
105
155
  description=(
106
156
  "The posture of this trigger, either Reactive or Proactive. Reactive "
107
157
  "triggers respond to the _presence_ of the expected events, while "
@@ -148,6 +198,28 @@ class EventTrigger(ResourceTrigger):
148
198
 
149
199
  return values
150
200
 
201
+ def describe_for_cli(self, indent: int = 0) -> str:
202
+ """Return a human-readable description of this trigger for the CLI"""
203
+ if self.posture == Posture.Reactive:
204
+ return textwrap.indent(
205
+ "\n".join(
206
+ [
207
+ f"Reactive: expecting {self.threshold} of {self.expect}",
208
+ ],
209
+ ),
210
+ prefix=" " * indent,
211
+ )
212
+ else:
213
+ return textwrap.indent(
214
+ "\n".join(
215
+ [
216
+ f"Proactive: expecting {self.threshold} {self.expect} event "
217
+ f"within {self.within}",
218
+ ],
219
+ ),
220
+ prefix=" " * indent,
221
+ )
222
+
151
223
 
152
224
  class MetricTriggerOperator(Enum):
153
225
  LT = "<"
@@ -224,6 +296,18 @@ class MetricTrigger(ResourceTrigger):
224
296
  description="The metric query to evaluate for this trigger. ",
225
297
  )
226
298
 
299
+ def describe_for_cli(self, indent: int = 0) -> str:
300
+ """Return a human-readable description of this trigger for the CLI"""
301
+ m = self.metric
302
+ return textwrap.indent(
303
+ "\n".join(
304
+ [
305
+ f"Metric: {m.name.value} {m.operator.value} {m.threshold} for {m.range}",
306
+ ]
307
+ ),
308
+ prefix=" " * indent,
309
+ )
310
+
227
311
 
228
312
  class CompositeTrigger(Trigger, abc.ABC):
229
313
  """
@@ -256,6 +340,23 @@ class CompoundTrigger(CompositeTrigger):
256
340
 
257
341
  return values
258
342
 
343
+ def describe_for_cli(self, indent: int = 0) -> str:
344
+ """Return a human-readable description of this trigger for the CLI"""
345
+ return textwrap.indent(
346
+ "\n".join(
347
+ [
348
+ f"{str(self.require).capitalize()} of:",
349
+ "\n".join(
350
+ [
351
+ trigger.describe_for_cli(indent=indent + 1)
352
+ for trigger in self.triggers
353
+ ]
354
+ ),
355
+ ]
356
+ ),
357
+ prefix=" " * indent,
358
+ )
359
+
259
360
 
260
361
  class SequenceTrigger(CompositeTrigger):
261
362
  """A composite trigger that requires some number of triggers to have fired
@@ -263,6 +364,23 @@ class SequenceTrigger(CompositeTrigger):
263
364
 
264
365
  type: Literal["sequence"] = "sequence"
265
366
 
367
+ def describe_for_cli(self, indent: int = 0) -> str:
368
+ """Return a human-readable description of this trigger for the CLI"""
369
+ return textwrap.indent(
370
+ "\n".join(
371
+ [
372
+ "In this order:",
373
+ "\n".join(
374
+ [
375
+ trigger.describe_for_cli(indent=indent + 1)
376
+ for trigger in self.triggers
377
+ ]
378
+ ),
379
+ ]
380
+ ),
381
+ prefix=" " * indent,
382
+ )
383
+
266
384
 
267
385
  TriggerTypes: TypeAlias = Union[
268
386
  EventTrigger, MetricTrigger, CompoundTrigger, SequenceTrigger
@@ -273,7 +391,7 @@ CompoundTrigger.update_forward_refs()
273
391
  SequenceTrigger.update_forward_refs()
274
392
 
275
393
 
276
- class Automation(PrefectBaseModel, extra="ignore"):
394
+ class AutomationCore(PrefectBaseModel, extra="ignore"):
277
395
  """Defines an action a user wants to take when a certain number of events
278
396
  do or don't happen to the matching resources"""
279
397
 
@@ -310,5 +428,5 @@ class Automation(PrefectBaseModel, extra="ignore"):
310
428
  )
311
429
 
312
430
 
313
- class ExistingAutomation(Automation):
431
+ class Automation(AutomationCore):
314
432
  id: UUID = Field(..., description="The ID of this automation")
@@ -11,13 +11,11 @@ create them from YAML.
11
11
 
12
12
  import abc
13
13
  import textwrap
14
- import warnings
15
14
  from datetime import timedelta
16
15
  from typing import (
17
16
  Any,
18
17
  Dict,
19
18
  List,
20
- Literal,
21
19
  Optional,
22
20
  Set,
23
21
  Union,
@@ -26,38 +24,25 @@ from uuid import UUID
26
24
 
27
25
  from typing_extensions import TypeAlias
28
26
 
29
- from prefect._internal.compatibility.deprecated import deprecated_class
30
27
  from prefect._internal.pydantic import HAS_PYDANTIC_V2
31
- from prefect._internal.schemas.validators import validate_trigger_within
32
28
 
33
29
  if HAS_PYDANTIC_V2:
34
- from pydantic.v1 import Field, PrivateAttr, root_validator, validator
35
- from pydantic.v1.fields import ModelField
30
+ from pydantic.v1 import Field, PrivateAttr
36
31
  else:
37
- from pydantic import Field, PrivateAttr, root_validator, validator
38
- from pydantic.fields import ModelField
39
-
40
- from prefect._internal.compatibility.experimental import (
41
- EXPERIMENTAL_WARNING,
42
- PREFECT_EXPERIMENTAL_WARN,
43
- ExperimentalFeature,
44
- experiment_enabled,
45
- )
32
+ from pydantic import Field, PrivateAttr # type: ignore
33
+
34
+ from prefect._internal.compatibility.deprecated import deprecated_class
46
35
  from prefect._internal.schemas.bases import PrefectBaseModel
47
- from prefect.events.actions import RunDeployment
48
- from prefect.settings import (
49
- PREFECT_EXPERIMENTAL_WARN_FLOW_RUN_INFRA_OVERRIDES,
50
- )
36
+ from prefect.events.actions import ActionTypes, RunDeployment
51
37
 
52
38
  from .automations import (
53
- Automation,
39
+ AutomationCore,
54
40
  CompoundTrigger,
55
41
  EventTrigger,
56
42
  MetricTrigger,
57
43
  MetricTriggerQuery,
58
44
  Posture,
59
45
  SequenceTrigger,
60
- Trigger,
61
46
  TriggerTypes,
62
47
  )
63
48
  from .events import ResourceSpecification
@@ -77,11 +62,7 @@ class BaseDeploymentTrigger(PrefectBaseModel, abc.ABC, extra="ignore"):
77
62
  description: str = Field("", description="A longer description of this automation")
78
63
  enabled: bool = Field(True, description="Whether this automation will be evaluated")
79
64
 
80
- # Fields from Trigger
81
-
82
- type: str
83
-
84
- # Fields from Deployment
65
+ # Fields from the RunDeployment action
85
66
 
86
67
  parameters: Optional[Dict[str, Any]] = Field(
87
68
  None,
@@ -97,256 +78,37 @@ class BaseDeploymentTrigger(PrefectBaseModel, abc.ABC, extra="ignore"):
97
78
  "deployment's default job variables"
98
79
  ),
99
80
  )
100
- _deployment_id: Optional[UUID] = PrivateAttr(default=None)
101
-
102
- def set_deployment_id(self, deployment_id: UUID):
103
- self._deployment_id = deployment_id
104
-
105
- def owner_resource(self) -> Optional[str]:
106
- return f"prefect.deployment.{self._deployment_id}"
107
-
108
- def actions(self) -> List[RunDeployment]:
109
- if self.job_variables is not None and experiment_enabled(
110
- "flow_run_infra_overrides"
111
- ):
112
- if (
113
- PREFECT_EXPERIMENTAL_WARN
114
- and PREFECT_EXPERIMENTAL_WARN_FLOW_RUN_INFRA_OVERRIDES
115
- ):
116
- warnings.warn(
117
- EXPERIMENTAL_WARNING.format(
118
- feature="Flow run job variables",
119
- group="flow_run_infra_overrides",
120
- help="To use this feature, update your workers to Prefect 2.16.4 or later. ",
121
- ),
122
- ExperimentalFeature,
123
- stacklevel=3,
124
- )
125
- if not experiment_enabled("flow_run_infra_overrides"):
126
- # nullify job_variables if the flag is disabled
127
- self.job_variables = None
128
-
129
- assert self._deployment_id
130
- return [
131
- RunDeployment(
132
- parameters=self.parameters,
133
- deployment_id=self._deployment_id,
134
- job_variables=self.job_variables,
135
- )
136
- ]
137
-
138
- def as_automation(self) -> Automation:
139
- if not self.name:
140
- raise ValueError("name is required")
141
-
142
- return Automation(
143
- name=self.name,
144
- description=self.description,
145
- enabled=self.enabled,
146
- trigger=self.as_trigger(),
147
- actions=self.actions(),
148
- owner_resource=self.owner_resource(),
149
- )
150
-
151
- @abc.abstractmethod
152
- def as_trigger(self) -> Trigger:
153
- ...
154
-
155
-
156
- class DeploymentResourceTrigger(BaseDeploymentTrigger, abc.ABC):
157
- """
158
- Base class for triggers that may filter by the labels of resources.
159
- """
160
-
161
- type: str
162
-
163
- match: ResourceSpecification = Field(
164
- default_factory=lambda: ResourceSpecification.parse_obj({}),
165
- description="Labels for resources which this trigger will match.",
166
- )
167
- match_related: ResourceSpecification = Field(
168
- default_factory=lambda: ResourceSpecification.parse_obj({}),
169
- description="Labels for related resources which this trigger will match.",
170
- )
171
81
 
172
82
 
173
- class DeploymentEventTrigger(DeploymentResourceTrigger):
83
+ class DeploymentEventTrigger(BaseDeploymentTrigger, EventTrigger):
174
84
  """
175
85
  A trigger that fires based on the presence or absence of events within a given
176
86
  period of time.
177
87
  """
178
88
 
179
- type: Literal["event"] = "event"
180
-
181
- after: Set[str] = Field(
182
- default_factory=set,
183
- description=(
184
- "The event(s) which must first been seen to fire this trigger. If "
185
- "empty, then fire this trigger immediately. Events may include "
186
- "trailing wildcards, like `prefect.flow-run.*`"
187
- ),
188
- )
189
- expect: Set[str] = Field(
190
- default_factory=set,
191
- description=(
192
- "The event(s) this trigger is expecting to see. If empty, this "
193
- "trigger will match any event. Events may include trailing wildcards, "
194
- "like `prefect.flow-run.*`"
195
- ),
196
- )
197
-
198
- for_each: Set[str] = Field(
199
- default_factory=set,
200
- description=(
201
- "Evaluate the trigger separately for each distinct value of these labels "
202
- "on the resource. By default, labels refer to the primary resource of the "
203
- "triggering event. You may also refer to labels from related "
204
- "resources by specifying `related:<role>:<label>`. This will use the "
205
- "value of that label for the first related resource in that role. For "
206
- 'example, `"for_each": ["related:flow:prefect.resource.id"]` would '
207
- "evaluate the trigger for each flow."
208
- ),
209
- )
210
- posture: Literal[Posture.Reactive, Posture.Proactive] = Field( # type: ignore[valid-type]
211
- Posture.Reactive,
212
- description=(
213
- "The posture of this trigger, either Reactive or Proactive. Reactive "
214
- "triggers respond to the _presence_ of the expected events, while "
215
- "Proactive triggers respond to the _absence_ of those expected events."
216
- ),
217
- )
218
- threshold: int = Field(
219
- 1,
220
- description=(
221
- "The number of events required for this trigger to fire (for "
222
- "Reactive triggers), or the number of events expected (for Proactive "
223
- "triggers)"
224
- ),
225
- )
226
- within: timedelta = Field(
227
- timedelta(0),
228
- minimum=0.0,
229
- exclusiveMinimum=False,
230
- description=(
231
- "The time period over which the events must occur. For Reactive triggers, "
232
- "this may be as low as 0 seconds, but must be at least 10 seconds for "
233
- "Proactive triggers"
234
- ),
235
- )
236
-
237
- @validator("within")
238
- def enforce_minimum_within(
239
- cls, value: timedelta, values, config, field: ModelField
240
- ):
241
- return validate_trigger_within(value, field)
242
-
243
- @root_validator(skip_on_failure=True)
244
- def enforce_minimum_within_for_proactive_triggers(cls, values: Dict[str, Any]):
245
- posture: Optional[Posture] = values.get("posture")
246
- within: Optional[timedelta] = values.get("within")
247
-
248
- if posture == Posture.Proactive:
249
- if not within or within == timedelta(0):
250
- values["within"] = timedelta(seconds=10.0)
251
- elif within < timedelta(seconds=10.0):
252
- raise ValueError(
253
- "The minimum within for Proactive triggers is 10 seconds"
254
- )
255
-
256
- return values
257
-
258
- def as_trigger(self) -> Trigger:
259
- return EventTrigger(
260
- match=self.match,
261
- match_related=self.match_related,
262
- after=self.after,
263
- expect=self.expect,
264
- for_each=self.for_each,
265
- posture=self.posture,
266
- threshold=self.threshold,
267
- within=self.within,
268
- )
89
+ trigger_type = EventTrigger
269
90
 
270
91
 
271
- class DeploymentMetricTrigger(DeploymentResourceTrigger):
92
+ class DeploymentMetricTrigger(BaseDeploymentTrigger, MetricTrigger):
272
93
  """
273
94
  A trigger that fires based on the results of a metric query.
274
95
  """
275
96
 
276
- type: Literal["metric"] = "metric"
277
-
278
- posture: Literal[Posture.Metric] = Field( # type: ignore[valid-type]
279
- Posture.Metric,
280
- description="Periodically evaluate the configured metric query.",
281
- )
282
-
283
- metric: MetricTriggerQuery = Field(
284
- ...,
285
- description="The metric query to evaluate for this trigger. ",
286
- )
287
-
288
- def as_trigger(self) -> Trigger:
289
- return MetricTrigger(
290
- match=self.match,
291
- match_related=self.match_related,
292
- posture=self.posture,
293
- metric=self.metric,
294
- job_variables=self.job_variables,
295
- )
296
-
297
-
298
- class DeploymentCompositeTrigger(BaseDeploymentTrigger, abc.ABC):
299
- """
300
- Requires some number of triggers to have fired within the given time period.
301
- """
302
-
303
- type: Literal["compound", "sequence"]
304
- triggers: List["TriggerTypes"]
305
- within: Optional[timedelta]
97
+ trigger_type = MetricTrigger
306
98
 
307
99
 
308
- class DeploymentCompoundTrigger(DeploymentCompositeTrigger):
100
+ class DeploymentCompoundTrigger(BaseDeploymentTrigger, CompoundTrigger):
309
101
  """A composite trigger that requires some number of triggers to have
310
102
  fired within the given time period"""
311
103
 
312
- type: Literal["compound"] = "compound"
313
- require: Union[int, Literal["any", "all"]]
314
-
315
- @root_validator
316
- def validate_require(cls, values: Dict[str, Any]) -> Dict[str, Any]:
317
- require = values.get("require")
318
-
319
- if isinstance(require, int):
320
- if require < 1:
321
- raise ValueError("required must be at least 1")
322
- if require > len(values["triggers"]):
323
- raise ValueError(
324
- "required must be less than or equal to the number of triggers"
325
- )
326
-
327
- return values
328
-
329
- def as_trigger(self) -> Trigger:
330
- return CompoundTrigger(
331
- require=self.require,
332
- triggers=self.triggers,
333
- within=self.within,
334
- job_variables=self.job_variables,
335
- )
104
+ trigger_type = CompoundTrigger
336
105
 
337
106
 
338
- class DeploymentSequenceTrigger(DeploymentCompositeTrigger):
107
+ class DeploymentSequenceTrigger(BaseDeploymentTrigger, SequenceTrigger):
339
108
  """A composite trigger that requires some number of triggers to have fired
340
109
  within the given time period in a specific order"""
341
110
 
342
- type: Literal["sequence"] = "sequence"
343
-
344
- def as_trigger(self) -> Trigger:
345
- return SequenceTrigger(
346
- triggers=self.triggers,
347
- within=self.within,
348
- job_variables=self.job_variables,
349
- )
111
+ trigger_type = SequenceTrigger
350
112
 
351
113
 
352
114
  # Concrete deployment trigger types
@@ -480,10 +242,13 @@ class DeploymentTrigger(PrefectBaseModel):
480
242
  ),
481
243
  )
482
244
 
483
- def as_automation(self) -> Automation:
245
+ def as_automation(self) -> AutomationCore:
484
246
  assert self.name
485
247
 
248
+ trigger: TriggerTypes
249
+
486
250
  if self.posture == Posture.Metric:
251
+ assert self.metric
487
252
  trigger = MetricTrigger(
488
253
  type="metric",
489
254
  match=self.match,
@@ -503,7 +268,7 @@ class DeploymentTrigger(PrefectBaseModel):
503
268
  within=self.within,
504
269
  )
505
270
 
506
- return Automation(
271
+ return AutomationCore(
507
272
  name=self.name,
508
273
  description=self.description,
509
274
  enabled=self.enabled,
@@ -518,32 +283,13 @@ class DeploymentTrigger(PrefectBaseModel):
518
283
  def owner_resource(self) -> Optional[str]:
519
284
  return f"prefect.deployment.{self._deployment_id}"
520
285
 
521
- def actions(self) -> List[RunDeployment]:
522
- if self.job_variables is not None and experiment_enabled(
523
- "flow_run_infra_overrides"
524
- ):
525
- if (
526
- PREFECT_EXPERIMENTAL_WARN
527
- and PREFECT_EXPERIMENTAL_WARN_FLOW_RUN_INFRA_OVERRIDES
528
- ):
529
- warnings.warn(
530
- EXPERIMENTAL_WARNING.format(
531
- feature="Flow run job variables",
532
- group="flow_run_infra_overrides",
533
- help="To use this feature, update your workers to Prefect 2.16.4 or later. ",
534
- ),
535
- ExperimentalFeature,
536
- stacklevel=3,
537
- )
538
- if not experiment_enabled("flow_run_infra_overrides"):
539
- # nullify job_variables if the flag is disabled
540
- self.job_variables = None
541
-
286
+ def actions(self) -> List[ActionTypes]:
542
287
  assert self._deployment_id
543
288
  return [
544
289
  RunDeployment(
545
- parameters=self.parameters,
290
+ source="selected",
546
291
  deployment_id=self._deployment_id,
292
+ parameters=self.parameters,
547
293
  job_variables=self.job_variables,
548
294
  )
549
295
  ]
@@ -15,9 +15,14 @@ from typing import (
15
15
  from uuid import UUID, uuid4
16
16
 
17
17
  import pendulum
18
- from pydantic import Field, root_validator, validator
19
18
 
20
19
  from prefect._internal.pydantic import HAS_PYDANTIC_V2
20
+
21
+ if HAS_PYDANTIC_V2:
22
+ from pydantic.v1 import Field, root_validator, validator
23
+ else:
24
+ from pydantic import Field, root_validator, validator # type: ignore
25
+
21
26
  from prefect._internal.schemas.bases import PrefectBaseModel
22
27
  from prefect._internal.schemas.fields import DateTimeTZ
23
28
  from prefect.logging import get_logger
@@ -26,11 +31,6 @@ from prefect.settings import (
26
31
  PREFECT_EVENTS_MAXIMUM_RELATED_RESOURCES,
27
32
  )
28
33
 
29
- if HAS_PYDANTIC_V2:
30
- from pydantic.v1 import Field, root_validator, validator
31
- else:
32
- from pydantic import Field, root_validator, validator
33
-
34
34
  from .labelling import Labelled
35
35
 
36
36
  logger = get_logger(__name__)
@@ -128,7 +128,7 @@ class Event(PrefectBaseModel):
128
128
  description="The client-provided identifier of this event",
129
129
  )
130
130
  follows: Optional[UUID] = Field(
131
- None,
131
+ default=None,
132
132
  description=(
133
133
  "The ID of an event that is known to have occurred prior to this one. "
134
134
  "If set, this may be used to establish a more precise ordering of causally-"
@@ -9,6 +9,7 @@ from prefect._internal.schemas.fields import DateTimeTZ
9
9
  from .clients import (
10
10
  AssertingEventsClient,
11
11
  PrefectCloudEventsClient,
12
+ PrefectEphemeralEventsClient,
12
13
  PrefectEventsClient,
13
14
  )
14
15
  from .schemas.events import Event, RelatedResource
@@ -53,13 +54,14 @@ def emit_event(
53
54
  AssertingEventsClient,
54
55
  PrefectCloudEventsClient,
55
56
  PrefectEventsClient,
57
+ PrefectEphemeralEventsClient,
56
58
  ]
57
59
  worker_instance = EventsWorker.instance()
58
60
 
59
61
  if worker_instance.client_type not in operational_clients:
60
62
  return None
61
63
 
62
- event_kwargs = {
64
+ event_kwargs: Dict[str, Any] = {
63
65
  "event": event,
64
66
  "resource": resource,
65
67
  }