prefect-client 2.16.7__py3-none-any.whl → 2.16.9__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 (62) hide show
  1. prefect/_internal/compatibility/experimental.py +9 -8
  2. prefect/_internal/concurrency/api.py +23 -42
  3. prefect/_internal/concurrency/waiters.py +25 -22
  4. prefect/_internal/pydantic/__init__.py +12 -3
  5. prefect/_internal/pydantic/_base_model.py +7 -4
  6. prefect/_internal/pydantic/_compat.py +39 -453
  7. prefect/_internal/pydantic/_flags.py +2 -0
  8. prefect/_internal/pydantic/_types.py +8 -0
  9. prefect/_internal/pydantic/utilities/__init__.py +0 -0
  10. prefect/_internal/pydantic/utilities/model_construct.py +56 -0
  11. prefect/_internal/pydantic/utilities/model_copy.py +55 -0
  12. prefect/_internal/pydantic/utilities/model_dump.py +136 -0
  13. prefect/_internal/pydantic/utilities/model_dump_json.py +112 -0
  14. prefect/_internal/pydantic/utilities/model_fields.py +50 -0
  15. prefect/_internal/pydantic/utilities/model_json_schema.py +82 -0
  16. prefect/_internal/pydantic/utilities/model_rebuild.py +80 -0
  17. prefect/_internal/pydantic/utilities/model_validate.py +75 -0
  18. prefect/_internal/pydantic/utilities/model_validate_json.py +68 -0
  19. prefect/_internal/pydantic/utilities/type_adapter.py +71 -0
  20. prefect/_internal/schemas/bases.py +1 -17
  21. prefect/_internal/schemas/validators.py +425 -4
  22. prefect/blocks/kubernetes.py +7 -3
  23. prefect/client/cloud.py +1 -1
  24. prefect/client/orchestration.py +8 -8
  25. prefect/client/schemas/actions.py +348 -285
  26. prefect/client/schemas/objects.py +47 -126
  27. prefect/client/schemas/responses.py +231 -57
  28. prefect/concurrency/events.py +2 -2
  29. prefect/context.py +2 -1
  30. prefect/deployments/base.py +4 -3
  31. prefect/deployments/runner.py +7 -25
  32. prefect/deprecated/packaging/base.py +5 -6
  33. prefect/deprecated/packaging/docker.py +19 -25
  34. prefect/deprecated/packaging/file.py +10 -5
  35. prefect/deprecated/packaging/orion.py +9 -4
  36. prefect/deprecated/packaging/serializers.py +8 -58
  37. prefect/engine.py +23 -22
  38. prefect/events/actions.py +16 -1
  39. prefect/events/related.py +4 -4
  40. prefect/events/schemas/automations.py +13 -2
  41. prefect/events/schemas/deployment_triggers.py +73 -5
  42. prefect/events/schemas/events.py +1 -1
  43. prefect/flows.py +3 -0
  44. prefect/infrastructure/provisioners/ecs.py +1 -0
  45. prefect/logging/configuration.py +2 -2
  46. prefect/pydantic/__init__.py +48 -2
  47. prefect/pydantic/main.py +2 -2
  48. prefect/serializers.py +6 -31
  49. prefect/settings.py +40 -17
  50. prefect/software/python.py +3 -5
  51. prefect/utilities/callables.py +1 -1
  52. prefect/utilities/collections.py +2 -1
  53. prefect/utilities/schema_tools/validation.py +2 -2
  54. prefect/workers/base.py +19 -10
  55. prefect/workers/block.py +3 -7
  56. prefect/workers/process.py +2 -5
  57. {prefect_client-2.16.7.dist-info → prefect_client-2.16.9.dist-info}/METADATA +3 -2
  58. {prefect_client-2.16.7.dist-info → prefect_client-2.16.9.dist-info}/RECORD +61 -50
  59. prefect/_internal/schemas/transformations.py +0 -106
  60. {prefect_client-2.16.7.dist-info → prefect_client-2.16.9.dist-info}/LICENSE +0 -0
  61. {prefect_client-2.16.7.dist-info → prefect_client-2.16.9.dist-info}/WHEEL +0 -0
  62. {prefect_client-2.16.7.dist-info → prefect_client-2.16.9.dist-info}/top_level.txt +0 -0
@@ -29,8 +29,16 @@ from prefect._internal.schemas.fields import CreatedBy, DateTimeTZ, UpdatedBy
29
29
  from prefect._internal.schemas.validators import (
30
30
  get_or_create_run_name,
31
31
  get_or_create_state_name,
32
+ list_length_50_or_less,
32
33
  raise_on_name_alphanumeric_dashes_only,
33
34
  raise_on_name_with_banned_characters,
35
+ set_run_policy_deprecated_fields,
36
+ validate_default_queue_id_not_none,
37
+ validate_max_metadata_length,
38
+ validate_message_template_variables,
39
+ validate_name_present_on_nonanonymous_blocks,
40
+ validate_not_negative,
41
+ validate_parent_and_ref_diff,
34
42
  )
35
43
  from prefect.client.schemas.schedules import SCHEDULE_TYPES
36
44
  from prefect.settings import PREFECT_CLOUD_API_URL, PREFECT_CLOUD_UI_URL
@@ -296,7 +304,13 @@ class State(ObjectBaseModel, Generic[R]):
296
304
  def is_paused(self) -> bool:
297
305
  return self.type == StateType.PAUSED
298
306
 
299
- def copy(self, *, update: dict = None, reset_fields: bool = False, **kwargs):
307
+ def copy(
308
+ self,
309
+ *,
310
+ update: Optional[Dict[str, Any]] = None,
311
+ reset_fields: bool = False,
312
+ **kwargs,
313
+ ):
300
314
  """
301
315
  Copying API models should return an object that could be inserted into the
302
316
  database again. The 'timestamp' is reset using the default factory.
@@ -387,18 +401,7 @@ class FlowRunPolicy(PrefectBaseModel):
387
401
 
388
402
  @root_validator
389
403
  def populate_deprecated_fields(cls, values):
390
- """
391
- If deprecated fields are provided, populate the corresponding new fields
392
- to preserve orchestration behavior.
393
- """
394
- if not values.get("retries", None) and values.get("max_retries", 0) != 0:
395
- values["retries"] = values["max_retries"]
396
- if (
397
- not values.get("retry_delay", None)
398
- and values.get("retry_delay_seconds", 0) != 0
399
- ):
400
- values["retry_delay"] = values["retry_delay_seconds"]
401
- return values
404
+ return set_run_policy_deprecated_fields(values)
402
405
 
403
406
 
404
407
  class FlowRun(ObjectBaseModel):
@@ -427,7 +430,7 @@ class FlowRun(ObjectBaseModel):
427
430
  description="The version of the flow executed in this flow run.",
428
431
  example="1.0",
429
432
  )
430
- parameters: dict = Field(
433
+ parameters: Dict[str, Any] = Field(
431
434
  default_factory=dict, description="Parameters for the flow run."
432
435
  )
433
436
  idempotency_key: Optional[str] = Field(
@@ -437,7 +440,7 @@ class FlowRun(ObjectBaseModel):
437
440
  " run is not created multiple times."
438
441
  ),
439
442
  )
440
- context: dict = Field(
443
+ context: Dict[str, Any] = Field(
441
444
  default_factory=dict,
442
445
  description="Additional context for the flow run.",
443
446
  example={"my_var": "my_val"},
@@ -526,6 +529,16 @@ class FlowRun(ObjectBaseModel):
526
529
  default=None, description="Job variables for the flow run."
527
530
  )
528
531
 
532
+ # These are server-side optimizations and should not be present on client models
533
+ # TODO: Deprecate these fields
534
+
535
+ state_type: Optional[StateType] = Field(
536
+ default=None, description="The type of the current flow run state."
537
+ )
538
+ state_name: Optional[str] = Field(
539
+ default=None, description="The name of the current flow run state."
540
+ )
541
+
529
542
  def __eq__(self, other: Any) -> bool:
530
543
  """
531
544
  Check for "equality" to another flow run schema
@@ -544,16 +557,6 @@ class FlowRun(ObjectBaseModel):
544
557
  def set_default_name(cls, name):
545
558
  return get_or_create_run_name(name)
546
559
 
547
- # These are server-side optimizations and should not be present on client models
548
- # TODO: Deprecate these fields
549
-
550
- state_type: Optional[StateType] = Field(
551
- default=None, description="The type of the current flow run state."
552
- )
553
- state_name: Optional[str] = Field(
554
- default=None, description="The name of the current flow run state."
555
- )
556
-
557
560
 
558
561
  class TaskRunPolicy(PrefectBaseModel):
559
562
  """Defines of how a task run should retry."""
@@ -585,32 +588,15 @@ class TaskRunPolicy(PrefectBaseModel):
585
588
 
586
589
  @root_validator
587
590
  def populate_deprecated_fields(cls, values):
588
- """
589
- If deprecated fields are provided, populate the corresponding new fields
590
- to preserve orchestration behavior.
591
- """
592
- if not values.get("retries", None) and values.get("max_retries", 0) != 0:
593
- values["retries"] = values["max_retries"]
594
-
595
- if (
596
- not values.get("retry_delay", None)
597
- and values.get("retry_delay_seconds", 0) != 0
598
- ):
599
- values["retry_delay"] = values["retry_delay_seconds"]
600
-
601
- return values
591
+ return set_run_policy_deprecated_fields(values)
602
592
 
603
593
  @validator("retry_delay")
604
594
  def validate_configured_retry_delays(cls, v):
605
- if isinstance(v, list) and (len(v) > 50):
606
- raise ValueError("Can not configure more than 50 retry delays per task.")
607
- return v
595
+ return list_length_50_or_less(v)
608
596
 
609
597
  @validator("retry_jitter_factor")
610
598
  def validate_jitter_factor(cls, v):
611
- if v is not None and v < 0:
612
- raise ValueError("`retry_jitter_factor` must be >= 0.")
613
- return v
599
+ return validate_not_negative(v)
614
600
 
615
601
 
616
602
  class TaskRunInput(PrefectBaseModel):
@@ -834,7 +820,7 @@ class BlockSchema(ObjectBaseModel):
834
820
  """A representation of a block schema."""
835
821
 
836
822
  checksum: str = Field(default=..., description="The block schema's unique checksum")
837
- fields: dict = Field(
823
+ fields: Dict[str, Any] = Field(
838
824
  default_factory=dict, description="The block schema's field schema"
839
825
  )
840
826
  block_type_id: Optional[UUID] = Field(default=..., description="A block type ID")
@@ -860,7 +846,9 @@ class BlockDocument(ObjectBaseModel):
860
846
  "The block document's name. Not required for anonymous block documents."
861
847
  ),
862
848
  )
863
- data: dict = Field(default_factory=dict, description="The block document's data")
849
+ data: Dict[str, Any] = Field(
850
+ default_factory=dict, description="The block document's data"
851
+ )
864
852
  block_schema_id: UUID = Field(default=..., description="A block schema ID")
865
853
  block_schema: Optional[BlockSchema] = Field(
866
854
  default=None, description="The associated block schema"
@@ -889,11 +877,7 @@ class BlockDocument(ObjectBaseModel):
889
877
 
890
878
  @root_validator
891
879
  def validate_name_is_present_if_not_anonymous(cls, values):
892
- # anonymous blocks may have no name prior to actually being
893
- # stored in the database
894
- if not values.get("is_anonymous") and not values.get("name"):
895
- raise ValueError("Names must be provided for block documents.")
896
- return values
880
+ return validate_name_present_on_nonanonymous_blocks(values)
897
881
 
898
882
 
899
883
  class Flow(ObjectBaseModel):
@@ -913,34 +897,14 @@ class Flow(ObjectBaseModel):
913
897
  return raise_on_name_with_banned_characters(v)
914
898
 
915
899
 
916
- class FlowRunnerSettings(PrefectBaseModel):
917
- """
918
- An API schema for passing details about the flow runner.
919
-
920
- This schema is agnostic to the types and configuration provided by clients
921
- """
922
-
923
- type: Optional[str] = Field(
924
- default=None,
925
- description=(
926
- "The type of the flow runner which can be used by the client for"
927
- " dispatching."
928
- ),
900
+ class MinimalDeploymentSchedule(PrefectBaseModel):
901
+ schedule: SCHEDULE_TYPES = Field(
902
+ default=..., description="The schedule for the deployment."
929
903
  )
930
- config: Optional[dict] = Field(
931
- default=None, description="The configuration for the given flow runner type."
904
+ active: bool = Field(
905
+ default=True, description="Whether or not the schedule is active."
932
906
  )
933
907
 
934
- # The following is required for composite compatibility in the ORM
935
-
936
- def __init__(self, type: str = None, config: dict = None, **kwargs) -> None:
937
- # Pydantic does not support positional arguments so they must be converted to
938
- # keyword arguments
939
- super().__init__(type=type, config=config, **kwargs)
940
-
941
- def __composite_values__(self):
942
- return self.type, self.config
943
-
944
908
 
945
909
  class DeploymentSchedule(ObjectBaseModel):
946
910
  deployment_id: Optional[UUID] = Field(
@@ -955,15 +919,6 @@ class DeploymentSchedule(ObjectBaseModel):
955
919
  )
956
920
 
957
921
 
958
- class MinimalDeploymentSchedule(PrefectBaseModel):
959
- schedule: SCHEDULE_TYPES = Field(
960
- default=..., description="The schedule for the deployment."
961
- )
962
- active: bool = Field(
963
- default=True, description="Whether or not the schedule is active."
964
- )
965
-
966
-
967
922
  class Deployment(ObjectBaseModel):
968
923
  """An ORM representation of deployment data."""
969
924
 
@@ -1091,7 +1046,7 @@ class BlockSchema(ObjectBaseModel):
1091
1046
  """An ORM representation of a block schema."""
1092
1047
 
1093
1048
  checksum: str = Field(default=..., description="The block schema's unique checksum")
1094
- fields: dict = Field(
1049
+ fields: Dict[str, Any] = Field(
1095
1050
  default_factory=dict, description="The block schema's field schema"
1096
1051
  )
1097
1052
  block_type_id: Optional[UUID] = Field(default=..., description="A block type ID")
@@ -1149,21 +1104,14 @@ class BlockDocumentReference(ObjectBaseModel):
1149
1104
 
1150
1105
  @root_validator
1151
1106
  def validate_parent_and_ref_are_different(cls, values):
1152
- parent_id = values.get("parent_block_document_id")
1153
- ref_id = values.get("reference_block_document_id")
1154
- if parent_id and ref_id and parent_id == ref_id:
1155
- raise ValueError(
1156
- "`parent_block_document_id` and `reference_block_document_id` cannot be"
1157
- " the same"
1158
- )
1159
- return values
1107
+ return validate_parent_and_ref_diff(values)
1160
1108
 
1161
1109
 
1162
1110
  class Configuration(ObjectBaseModel):
1163
1111
  """An ORM representation of account info."""
1164
1112
 
1165
1113
  key: str = Field(default=..., description="Account info key")
1166
- value: dict = Field(default=..., description="Account info")
1114
+ value: Dict[str, Any] = Field(default=..., description="Account info")
1167
1115
 
1168
1116
 
1169
1117
  class SavedSearchFilter(PrefectBaseModel):
@@ -1355,12 +1303,7 @@ class FlowRunNotificationPolicy(ObjectBaseModel):
1355
1303
 
1356
1304
  @validator("message_template")
1357
1305
  def validate_message_template_variables(cls, v):
1358
- if v is not None:
1359
- try:
1360
- v.format(**{k: "test" for k in FLOW_RUN_NOTIFICATION_TEMPLATE_KWARGS})
1361
- except KeyError as exc:
1362
- raise ValueError(f"Invalid template variable provided: '{exc.args[0]}'")
1363
- return v
1306
+ return validate_message_template_variables(v)
1364
1307
 
1365
1308
 
1366
1309
  class Agent(ObjectBaseModel):
@@ -1425,23 +1368,7 @@ class WorkPool(ObjectBaseModel):
1425
1368
 
1426
1369
  @validator("default_queue_id", always=True)
1427
1370
  def helpful_error_for_missing_default_queue_id(cls, v):
1428
- """
1429
- Default queue ID is required because all pools must have a default queue
1430
- ID, but it represents a circular foreign key relationship to a
1431
- WorkQueue (which can't be created until the work pool exists).
1432
- Therefore, while this field can *technically* be null, it shouldn't be.
1433
- This should only be an issue when creating new pools, as reading
1434
- existing ones will always have this field populated. This custom error
1435
- message will help users understand that they should use the
1436
- `actions.WorkPoolCreate` model in that case.
1437
- """
1438
- if v is None:
1439
- raise ValueError(
1440
- "`default_queue_id` is a required field. If you are "
1441
- "creating a new WorkPool and don't have a queue "
1442
- "ID yet, use the `actions.WorkPoolCreate` model instead."
1443
- )
1444
- return v
1371
+ return validate_default_queue_id_not_none(v)
1445
1372
 
1446
1373
 
1447
1374
  class Worker(ObjectBaseModel):
@@ -1508,13 +1435,7 @@ class Artifact(ObjectBaseModel):
1508
1435
 
1509
1436
  @validator("metadata_")
1510
1437
  def validate_metadata_length(cls, v):
1511
- max_metadata_length = 500
1512
- if not isinstance(v, dict):
1513
- return v
1514
- for key in v.keys():
1515
- if len(str(v[key])) > max_metadata_length:
1516
- v[key] = str(v[key])[:max_metadata_length] + "..."
1517
- return v
1438
+ return validate_max_metadata_length(v)
1518
1439
 
1519
1440
 
1520
1441
  class ArtifactCollection(ObjectBaseModel):
@@ -14,9 +14,9 @@ from typing_extensions import Literal
14
14
  import prefect.client.schemas.objects as objects
15
15
  from prefect._internal.schemas.bases import ObjectBaseModel, PrefectBaseModel
16
16
  from prefect._internal.schemas.fields import CreatedBy, DateTimeTZ, UpdatedBy
17
- from prefect._internal.schemas.transformations import FieldFrom, copy_model_fields
18
17
  from prefect.client.schemas.schedules import SCHEDULE_TYPES
19
18
  from prefect.utilities.collections import AutoEnum
19
+ from prefect.utilities.names import generate_slug
20
20
 
21
21
  R = TypeVar("R")
22
22
 
@@ -154,43 +154,140 @@ class WorkerFlowRunResponse(PrefectBaseModel):
154
154
  flow_run: objects.FlowRun
155
155
 
156
156
 
157
- @copy_model_fields
158
157
  class FlowRunResponse(ObjectBaseModel):
159
- name: str = FieldFrom(objects.FlowRun)
160
- flow_id: UUID = FieldFrom(objects.FlowRun)
161
- state_id: Optional[UUID] = FieldFrom(objects.FlowRun)
162
- deployment_id: Optional[UUID] = FieldFrom(objects.FlowRun)
163
- work_queue_id: Optional[UUID] = FieldFrom(objects.FlowRun)
164
- work_queue_name: Optional[str] = FieldFrom(objects.FlowRun)
165
- flow_version: Optional[str] = FieldFrom(objects.FlowRun)
166
- parameters: dict = FieldFrom(objects.FlowRun)
167
- idempotency_key: Optional[str] = FieldFrom(objects.FlowRun)
168
- context: dict = FieldFrom(objects.FlowRun)
169
- empirical_policy: objects.FlowRunPolicy = FieldFrom(objects.FlowRun)
170
- tags: List[str] = FieldFrom(objects.FlowRun)
171
- parent_task_run_id: Optional[UUID] = FieldFrom(objects.FlowRun)
172
- state_type: Optional[objects.StateType] = FieldFrom(objects.FlowRun)
173
- state_name: Optional[str] = FieldFrom(objects.FlowRun)
174
- run_count: int = FieldFrom(objects.FlowRun)
175
- expected_start_time: Optional[DateTimeTZ] = FieldFrom(objects.FlowRun)
176
- next_scheduled_start_time: Optional[DateTimeTZ] = FieldFrom(objects.FlowRun)
177
- start_time: Optional[DateTimeTZ] = FieldFrom(objects.FlowRun)
178
- end_time: Optional[DateTimeTZ] = FieldFrom(objects.FlowRun)
179
- total_run_time: datetime.timedelta = FieldFrom(objects.FlowRun)
180
- estimated_run_time: datetime.timedelta = FieldFrom(objects.FlowRun)
181
- estimated_start_time_delta: datetime.timedelta = FieldFrom(objects.FlowRun)
182
- auto_scheduled: bool = FieldFrom(objects.FlowRun)
183
- infrastructure_document_id: Optional[UUID] = FieldFrom(objects.FlowRun)
184
- infrastructure_pid: Optional[str] = FieldFrom(objects.FlowRun)
185
- created_by: Optional[CreatedBy] = FieldFrom(objects.FlowRun)
186
- work_pool_id: Optional[UUID] = FieldFrom(objects.FlowRun)
158
+ name: str = Field(
159
+ default_factory=lambda: generate_slug(2),
160
+ description=(
161
+ "The name of the flow run. Defaults to a random slug if not specified."
162
+ ),
163
+ example="my-flow-run",
164
+ )
165
+ flow_id: UUID = Field(default=..., description="The id of the flow being run.")
166
+ state_id: Optional[UUID] = Field(
167
+ default=None, description="The id of the flow run's current state."
168
+ )
169
+ deployment_id: Optional[UUID] = Field(
170
+ default=None,
171
+ description=(
172
+ "The id of the deployment associated with this flow run, if available."
173
+ ),
174
+ )
175
+ work_queue_name: Optional[str] = Field(
176
+ default=None, description="The work queue that handled this flow run."
177
+ )
178
+ flow_version: Optional[str] = Field(
179
+ default=None,
180
+ description="The version of the flow executed in this flow run.",
181
+ example="1.0",
182
+ )
183
+ parameters: Dict[str, Any] = Field(
184
+ default_factory=dict, description="Parameters for the flow run."
185
+ )
186
+ idempotency_key: Optional[str] = Field(
187
+ default=None,
188
+ description=(
189
+ "An optional idempotency key for the flow run. Used to ensure the same flow"
190
+ " run is not created multiple times."
191
+ ),
192
+ )
193
+ context: Dict[str, Any] = Field(
194
+ default_factory=dict,
195
+ description="Additional context for the flow run.",
196
+ example={"my_var": "my_val"},
197
+ )
198
+ empirical_policy: objects.FlowRunPolicy = Field(
199
+ default_factory=objects.FlowRunPolicy,
200
+ )
201
+ tags: List[str] = Field(
202
+ default_factory=list,
203
+ description="A list of tags on the flow run",
204
+ example=["tag-1", "tag-2"],
205
+ )
206
+ parent_task_run_id: Optional[UUID] = Field(
207
+ default=None,
208
+ description=(
209
+ "If the flow run is a subflow, the id of the 'dummy' task in the parent"
210
+ " flow used to track subflow state."
211
+ ),
212
+ )
213
+ run_count: int = Field(
214
+ default=0, description="The number of times the flow run was executed."
215
+ )
216
+ expected_start_time: Optional[DateTimeTZ] = Field(
217
+ default=None,
218
+ description="The flow run's expected start time.",
219
+ )
220
+ next_scheduled_start_time: Optional[DateTimeTZ] = Field(
221
+ default=None,
222
+ description="The next time the flow run is scheduled to start.",
223
+ )
224
+ start_time: Optional[DateTimeTZ] = Field(
225
+ default=None, description="The actual start time."
226
+ )
227
+ end_time: Optional[DateTimeTZ] = Field(
228
+ default=None, description="The actual end time."
229
+ )
230
+ total_run_time: datetime.timedelta = Field(
231
+ default=datetime.timedelta(0),
232
+ description=(
233
+ "Total run time. If the flow run was executed multiple times, the time of"
234
+ " each run will be summed."
235
+ ),
236
+ )
237
+ estimated_run_time: datetime.timedelta = Field(
238
+ default=datetime.timedelta(0),
239
+ description="A real-time estimate of the total run time.",
240
+ )
241
+ estimated_start_time_delta: datetime.timedelta = Field(
242
+ default=datetime.timedelta(0),
243
+ description="The difference between actual and expected start time.",
244
+ )
245
+ auto_scheduled: bool = Field(
246
+ default=False,
247
+ description="Whether or not the flow run was automatically scheduled.",
248
+ )
249
+ infrastructure_document_id: Optional[UUID] = Field(
250
+ default=None,
251
+ description="The block document defining infrastructure to use this flow run.",
252
+ )
253
+ infrastructure_pid: Optional[str] = Field(
254
+ default=None,
255
+ description="The id of the flow run as returned by an infrastructure block.",
256
+ )
257
+ created_by: Optional[CreatedBy] = Field(
258
+ default=None,
259
+ description="Optional information about the creator of this flow run.",
260
+ )
261
+ work_queue_id: Optional[UUID] = Field(
262
+ default=None, description="The id of the run's work pool queue."
263
+ )
264
+
265
+ work_pool_id: Optional[UUID] = Field(
266
+ description="The work pool with which the queue is associated."
267
+ )
187
268
  work_pool_name: Optional[str] = Field(
188
269
  default=None,
189
270
  description="The name of the flow run's work pool.",
190
271
  example="my-work-pool",
191
272
  )
192
- state: Optional[objects.State] = FieldFrom(objects.FlowRun)
193
- job_variables: Optional[dict] = FieldFrom(objects.FlowRun)
273
+ state: Optional[objects.State] = Field(
274
+ default=None,
275
+ description="The state of the flow run.",
276
+ example=objects.State(type=objects.StateType.COMPLETED),
277
+ )
278
+ job_variables: Optional[dict] = Field(
279
+ default=None, description="Job variables for the flow run."
280
+ )
281
+
282
+ # These are server-side optimizations and should not be present on client models
283
+ # TODO: Deprecate these fields
284
+
285
+ state_type: Optional[objects.StateType] = Field(
286
+ default=None, description="The type of the current flow run state."
287
+ )
288
+ state_name: Optional[str] = Field(
289
+ default=None, description="The name of the current flow run state."
290
+ )
194
291
 
195
292
  def __eq__(self, other: Any) -> bool:
196
293
  """
@@ -199,7 +296,7 @@ class FlowRunResponse(ObjectBaseModel):
199
296
  Estimates times are rolling and will always change with repeated queries for
200
297
  a flow run so we ignore them during equality checks.
201
298
  """
202
- if isinstance(other, FlowRunResponse):
299
+ if isinstance(other, objects.FlowRun):
203
300
  exclude_fields = {"estimated_run_time", "estimated_start_time_delta"}
204
301
  return self.dict(exclude=exclude_fields) == other.dict(
205
302
  exclude=exclude_fields
@@ -207,30 +304,108 @@ class FlowRunResponse(ObjectBaseModel):
207
304
  return super().__eq__(other)
208
305
 
209
306
 
210
- @copy_model_fields
211
307
  class DeploymentResponse(ObjectBaseModel):
212
- name: str = FieldFrom(objects.Deployment)
213
- version: Optional[str] = FieldFrom(objects.Deployment)
214
- description: Optional[str] = FieldFrom(objects.Deployment)
215
- flow_id: UUID = FieldFrom(objects.Deployment)
216
- schedule: Optional[SCHEDULE_TYPES] = FieldFrom(objects.Deployment)
217
- is_schedule_active: bool = FieldFrom(objects.Deployment)
218
- paused: bool = FieldFrom(objects.Deployment)
219
- schedules: List[objects.DeploymentSchedule] = FieldFrom(objects.Deployment)
220
- infra_overrides: Dict[str, Any] = FieldFrom(objects.Deployment)
221
- parameters: Dict[str, Any] = FieldFrom(objects.Deployment)
222
- tags: List[str] = FieldFrom(objects.Deployment)
223
- work_queue_name: Optional[str] = FieldFrom(objects.Deployment)
224
- last_polled: Optional[DateTimeTZ] = FieldFrom(objects.Deployment)
225
- parameter_openapi_schema: Optional[Dict[str, Any]] = FieldFrom(objects.Deployment)
226
- path: Optional[str] = FieldFrom(objects.Deployment)
227
- pull_steps: Optional[List[dict]] = FieldFrom(objects.Deployment)
228
- entrypoint: Optional[str] = FieldFrom(objects.Deployment)
229
- manifest_path: Optional[str] = FieldFrom(objects.Deployment)
230
- storage_document_id: Optional[UUID] = FieldFrom(objects.Deployment)
231
- infrastructure_document_id: Optional[UUID] = FieldFrom(objects.Deployment)
232
- created_by: Optional[CreatedBy] = FieldFrom(objects.Deployment)
233
- updated_by: Optional[UpdatedBy] = FieldFrom(objects.Deployment)
308
+ name: str = Field(default=..., description="The name of the deployment.")
309
+ version: Optional[str] = Field(
310
+ default=None, description="An optional version for the deployment."
311
+ )
312
+ description: Optional[str] = Field(
313
+ default=None, description="A description for the deployment."
314
+ )
315
+ flow_id: UUID = Field(
316
+ default=..., description="The flow id associated with the deployment."
317
+ )
318
+ schedule: Optional[SCHEDULE_TYPES] = Field(
319
+ default=None, description="A schedule for the deployment."
320
+ )
321
+ is_schedule_active: bool = Field(
322
+ default=True, description="Whether or not the deployment schedule is active."
323
+ )
324
+ paused: bool = Field(
325
+ default=False, description="Whether or not the deployment is paused."
326
+ )
327
+ schedules: List[objects.DeploymentSchedule] = Field(
328
+ default_factory=list, description="A list of schedules for the deployment."
329
+ )
330
+ infra_overrides: Dict[str, Any] = Field(
331
+ default_factory=dict,
332
+ description="Overrides to apply to the base infrastructure block at runtime.",
333
+ )
334
+ parameters: Dict[str, Any] = Field(
335
+ default_factory=dict,
336
+ description="Parameters for flow runs scheduled by the deployment.",
337
+ )
338
+ pull_steps: Optional[List[dict]] = Field(
339
+ default=None,
340
+ description="Pull steps for cloning and running this deployment.",
341
+ )
342
+ tags: List[str] = Field(
343
+ default_factory=list,
344
+ description="A list of tags for the deployment",
345
+ example=["tag-1", "tag-2"],
346
+ )
347
+ work_queue_name: Optional[str] = Field(
348
+ default=None,
349
+ description=(
350
+ "The work queue for the deployment. If no work queue is set, work will not"
351
+ " be scheduled."
352
+ ),
353
+ )
354
+ last_polled: Optional[DateTimeTZ] = Field(
355
+ default=None,
356
+ description="The last time the deployment was polled for status updates.",
357
+ )
358
+ parameter_openapi_schema: Optional[Dict[str, Any]] = Field(
359
+ default=None,
360
+ description="The parameter schema of the flow, including defaults.",
361
+ )
362
+ path: Optional[str] = Field(
363
+ default=None,
364
+ description=(
365
+ "The path to the working directory for the workflow, relative to remote"
366
+ " storage or an absolute path."
367
+ ),
368
+ )
369
+ entrypoint: Optional[str] = Field(
370
+ default=None,
371
+ description=(
372
+ "The path to the entrypoint for the workflow, relative to the `path`."
373
+ ),
374
+ )
375
+ manifest_path: Optional[str] = Field(
376
+ default=None,
377
+ description=(
378
+ "The path to the flow's manifest file, relative to the chosen storage."
379
+ ),
380
+ )
381
+ storage_document_id: Optional[UUID] = Field(
382
+ default=None,
383
+ description="The block document defining storage used for this flow.",
384
+ )
385
+ infrastructure_document_id: Optional[UUID] = Field(
386
+ default=None,
387
+ description="The block document defining infrastructure to use for flow runs.",
388
+ )
389
+ created_by: Optional[CreatedBy] = Field(
390
+ default=None,
391
+ description="Optional information about the creator of this deployment.",
392
+ )
393
+ updated_by: Optional[UpdatedBy] = Field(
394
+ default=None,
395
+ description="Optional information about the updater of this deployment.",
396
+ )
397
+ work_queue_id: UUID = Field(
398
+ default=None,
399
+ description=(
400
+ "The id of the work pool queue to which this deployment is assigned."
401
+ ),
402
+ )
403
+ enforce_parameter_schema: bool = Field(
404
+ default=False,
405
+ description=(
406
+ "Whether or not the deployment should enforce the parameter schema."
407
+ ),
408
+ )
234
409
  work_pool_name: Optional[str] = Field(
235
410
  default=None,
236
411
  description="The name of the deployment's work pool.",
@@ -239,7 +414,6 @@ class DeploymentResponse(ObjectBaseModel):
239
414
  default=None,
240
415
  description="Current status of the deployment.",
241
416
  )
242
- enforce_parameter_schema: bool = FieldFrom(objects.Deployment)
243
417
 
244
418
 
245
419
  class MinimalConcurrencyLimitResponse(PrefectBaseModel):
@@ -20,8 +20,8 @@ def _emit_concurrency_event(
20
20
  }
21
21
 
22
22
  related = [
23
- RelatedResource(
24
- __root__={
23
+ RelatedResource.parse_obj(
24
+ {
25
25
  "prefect.resource.id": f"prefect.concurrency-limit.{limit.id}",
26
26
  "prefect.resource.role": "concurrency-limit",
27
27
  }
prefect/context.py CHANGED
@@ -5,6 +5,7 @@ These contexts should never be directly mutated by the user.
5
5
 
6
6
  For more user-accessible information about the current run, see [`prefect.runtime`](../runtime/flow_run).
7
7
  """
8
+
8
9
  import os
9
10
  import sys
10
11
  import warnings
@@ -75,7 +76,7 @@ class ContextModel(BaseModel):
75
76
  _token: Token = PrivateAttr(None)
76
77
 
77
78
  class Config:
78
- allow_mutation = False
79
+ # allow_mutation = False
79
80
  arbitrary_types_allowed = True
80
81
  extra = "forbid"
81
82