class FlowSchema(ObjectSchema): # All nested 'many' types that are stored as a `Set` in the `Flow` must be sorted # using a `value_selection_fn` so `Flow.serialized_hash()` is deterministic class Meta: object_class = lambda: prefect.core.Flow exclude_fields = ["type", "parameters"] # ordered to make sure Task objects are loaded before Edge objects, due to Task caching ordered = True project = fields.String(allow_none=True) name = fields.String(required=True, allow_none=True) version = fields.String(allow_none=True) description = fields.String(allow_none=True) type = fields.Function(lambda flow: to_qualified_name(type(flow)), lambda x: x) schedule = fields.Nested(ScheduleSchema, allow_none=True) parameters = Nested(ParameterSchema, value_selection_fn=get_parameters, many=True) tasks = Nested(TaskSchema, value_selection_fn=get_tasks, many=True) edges = Nested(EdgeSchema, value_selection_fn=get_edges, many=True) reference_tasks = Nested(TaskSchema, value_selection_fn=get_reference_tasks, many=True, only=["slug"]) environment = fields.Nested(EnvironmentSchema, allow_none=True) run_config = fields.Nested(RunConfigSchema, allow_none=True) storage = fields.Nested(StorageSchema, allow_none=True) @post_load def create_object(self, data: dict, **kwargs: Any) -> prefect.core.Flow: """ Flow edges are validated, for example to make sure the keys match Task inputs, but because we are deserializing all Tasks as base Tasks, the edge validation will fail (base Tasks have no inputs). Therefore we hold back the edges from Flow initialization and assign them explicitly. Args: - data (dict): the deserialized data Returns: - Flow """ data["validate"] = False flow = super().create_object(data) return flow
class FlowSchema(ObjectSchema): class Meta: object_class = lambda: prefect.core.Flow exclude_fields = ["id", "type", "parameters"] # ordered to make sure Task objects are loaded before Edge objects, due to Task caching ordered = True id = fields.String() project = fields.String(allow_none=True) name = fields.String(required=True, allow_none=True) version = fields.String(allow_none=True) description = fields.String(allow_none=True) type = fields.Function(lambda flow: to_qualified_name(type(flow)), lambda x: x) schedule = fields.Nested(ScheduleSchema, allow_none=True) parameters = Nested(ParameterSchema, value_selection_fn=get_parameters, many=True) tasks = fields.Nested(TaskSchema, many=True) edges = fields.Nested(EdgeSchema, many=True) reference_tasks = Nested(TaskSchema, value_selection_fn=get_reference_tasks, many=True, only=["id"]) environment = fields.Nested(EnvironmentSchema, allow_none=True) @post_load def create_object(self, data: dict) -> prefect.core.Flow: """ Flow edges are validated, for example to make sure the keys match Task inputs, but because we are deserializing all Tasks as base Tasks, the edge validation will fail (base Tasks have no inputs). Therefore we hold back the edges from Flow initialization and assign them explicitly. Args: - data (dict): the deserialized data Returns: - Flow """ data["validate"] = False flow = super().create_object(data) if "id" in data: flow.id = data["id"] return flow
class PendingSchema(BaseStateSchema): class Meta: object_class = state.Pending cached_inputs = fields.Dict( key=fields.Str(), values=Nested(StateResultSchema, value_selection_fn=get_safe), allow_none=True, )
class FailedSchema(FinishedSchema): class Meta: object_class = state.Failed cached_inputs = fields.Dict( key=fields.Str(), values=Nested(StateResultSchema, value_selection_fn=get_safe), allow_none=True, )
class BaseStateSchema(ObjectSchema): class Meta: object_class = state.State context = fields.Dict(key=fields.Str(), values=JSONCompatible(), allow_none=True) message = fields.String(allow_none=True) _result = Nested(StateResultSchema, allow_none=False, value_selection_fn=get_safe) cached_inputs = fields.Dict( key=fields.Str(), values=Nested(StateResultSchema, value_selection_fn=get_safe), allow_none=True, ) @post_load def create_object(self, data: dict, **kwargs: Any) -> state.State: result_obj = data.pop("_result", None) data["result"] = result_obj base_obj = super().create_object(data) return base_obj
class TimedOutSchema(FinishedSchema): class Meta: object_class = state.TimedOut cached_inputs = fields.Dict( key=fields.Str(), values=Nested(StateResultSchema, value_selection_fn=get_safe, attr="cached_inputs"), allow_none=True, )
class CachedSchema(SuccessSchema): class Meta: object_class = state.Cached cached_inputs = fields.Dict( key=fields.Str(), values=Nested(StateResultSchema, value_selection_fn=get_safe, attr="cached_inputs"), allow_none=True, ) cached_parameters = JSONCompatible(allow_none=True) cached_result_expiration = fields.DateTime(allow_none=True)
class BaseStateSchema(ObjectSchema): class Meta: object_class = state.State message = fields.String(allow_none=True) _result = Nested(StateResultSchema, allow_none=False, value_selection_fn=get_safe) @post_load def create_object(self, data: dict, **kwargs: Any) -> state.State: result_obj = data.pop("_result", result.NoResult) data["result"] = result_obj base_obj = super().create_object(data) return base_obj
class Schema(marshmallow.Schema): child = Nested(Child, value_selection_fn=get_child)