def _from_task_run_data(cls, task_run: dict) -> "TaskRunView": """ Instantiate a `TaskRunView` from serialized data This method deserializes objects into their Prefect types. Args: - task_run: The serialized task run data Returns: A populated `TaskRunView` instance """ task_run = task_run.copy() # Create a copy to avoid mutation task_run_id = task_run.pop("id") task_data = task_run.pop("task") # The serialized state _could_ be null if the backend has not # created it yet, this would typically be seen with mapped tasks serialized_state = task_run.pop( "serialized_state") or Scheduled().serialize() return cls( task_run_id=task_run_id, state=State.deserialize(serialized_state), task_id=task_data["id"], task_slug=task_data["slug"], **task_run, )
def test_serialization_of_cached_inputs_with_unsafe_values(cls): unsafe5 = Result(5, result_handler=JSONResultHandler()) state = cls(cached_inputs=dict(hi=unsafe5, bye=unsafe5)) serialized = state.serialize() new_state = State.deserialize(serialized) assert isinstance(new_state, cls) assert new_state.cached_inputs == dict(hi=NoResult, bye=NoResult)
def test_serialization_of_cached_inputs(): safe5 = SafeResult(5, result_handler=JSONResultHandler()) state = Pending(cached_inputs=dict(hi=safe5, bye=safe5)) serialized = state.serialize() new_state = State.deserialize(serialized) assert isinstance(new_state, Pending) assert new_state.cached_inputs == state.cached_inputs
def test_serialization_of_cached_inputs_with_unsafe_values(cls): unsafe5 = PrefectResult(value=5) state = cls(cached_inputs=dict(hi=unsafe5, bye=unsafe5)) serialized = state.serialize() new_state = State.deserialize(serialized) assert isinstance(new_state, cls) assert new_state.cached_inputs == dict(hi=PrefectResult(), bye=PrefectResult())
def _from_flow_run_data( cls, flow_run_data: dict, task_runs: Iterable["TaskRunView"] = None) -> "FlowRunView": """ Instantiate a `TaskRunView` from serialized data. This method deserializes objects into their Prefect types. Exists to maintain consistency in the design of backend "View" classes. Args: - flow_run_data: A dict of flow run data - task_runs: An optional iterable of task runs to pre-populate the cache with Returns: A populated `FlowRunView` instance """ flow_run_data = flow_run_data.copy() # Avoid mutating the input object flow_run_id = flow_run_data.pop("id") serialized_state = flow_run_data.pop("serialized_state") state = ( State.deserialize(serialized_state) if serialized_state # Flow run may not have initialized its state yet else Pending( message="A state for this flow run is not yet available.")) run_config_data = flow_run_data.pop("run_config") run_config = (RunConfigSchema().load(run_config_data) if run_config_data else None) states_data = flow_run_data.pop("states", []) states = list( sorted( [ _TimestampedState.from_dict(state_data) for state_data in states_data ], key=lambda s: s.timestamp, )) updated_at = cast(pendulum.DateTime, pendulum.parse(flow_run_data.pop("updated"))) return cls( flow_run_id=flow_run_id, task_runs=task_runs, state=state, updated_at=updated_at, states=states, run_config=run_config, **flow_run_data, )
def test_serialize_and_deserialize_on_raw_cached_state(): now = pendulum.now("utc") state = Cached( cached_inputs=dict(x=Result(99), p=Result("p")), result=dict(hi=5, bye=6), cached_result_expiration=now, ) serialized = state.serialize() new_state = State.deserialize(serialized) assert isinstance(new_state, Cached) assert new_state.color == state.color assert new_state.result is None assert new_state.cached_result_expiration == state.cached_result_expiration assert new_state.cached_inputs == dict.fromkeys(["x", "p"], NoResult)
def test_serialize_and_deserialize_on_mixed_cached_state(): safe_dct = SafeResult(dict(hi=5, bye=6), result_handler=JSONResultHandler()) now = pendulum.now("utc") state = Cached( cached_inputs=dict(x=Result(2), p=Result("p")), result=safe_dct, cached_result_expiration=now, ) serialized = state.serialize() new_state = State.deserialize(serialized) assert isinstance(new_state, Cached) assert new_state.color == state.color assert new_state.result == dict(hi=5, bye=6) assert new_state.cached_result_expiration == state.cached_result_expiration assert new_state.cached_inputs == dict.fromkeys(["x", "p"], NoResult)
def test_serialize_and_deserialize_on_mixed_cached_state(): safe_dct = PrefectResult(location=json.dumps(dict(hi=5, bye=6))) now = pendulum.now("utc") state = Cached( cached_inputs=dict(x=PrefectResult(value=2), p=PrefectResult(value="p")), result=safe_dct, cached_result_expiration=now, ) serialized = state.serialize() new_state = State.deserialize(serialized) assert isinstance(new_state, Cached) assert new_state.color == state.color assert new_state._result.location == json.dumps(dict(hi=5, bye=6)) assert new_state.cached_result_expiration == state.cached_result_expiration assert new_state.cached_inputs == dict.fromkeys(["x", "p"], PrefectResult())
def test_serialize_and_deserialize_on_safe_cached_state(): safe = SafeResult("99", result_handler=JSONResultHandler()) safe_dct = SafeResult(dict(hi=5, bye=6), result_handler=JSONResultHandler()) now = pendulum.now("utc") state = Cached( cached_inputs=dict(x=safe, p=safe), result=safe_dct, cached_result_expiration=now, ) serialized = state.serialize() new_state = State.deserialize(serialized) assert isinstance(new_state, Cached) assert new_state.color == state.color assert new_state.result == dict(hi=5, bye=6) assert new_state.cached_result_expiration == state.cached_result_expiration assert new_state.cached_inputs == state.cached_inputs