def test_get_flow_run_info_raises_informative_error(patch_post): post = patch_post(dict(data={"flow_run_by_pk": None})) with set_temporary_config( {"cloud.api": "http://my-cloud.foo", "cloud.auth_token": "secret_token"} ): client = Client() with pytest.raises(ClientError, match="not found"): client.get_flow_run_info(flow_run_id="74-salt")
def test_get_flow_run_info_with_nontrivial_payloads(monkeypatch): response = """ { "flow_run_by_pk": { "version": 0, "parameters": {"x": {"deep": {"nested": 5}}}, "context": {"my_val": "test"}, "scheduled_start_time": "2019-01-25T19:15:58.632412+00:00", "serialized_state": { "type": "Pending", "_result": {"type": "SafeResult", "value": "42", "result_handler": {"type": "JSONResultHandler"}}, "message": null, "__version__": "0.3.3+309.gf1db024", "cached_inputs": null }, "task_runs":[ { "id": "da344768-5f5d-4eaf-9bca-83815617f713", "task": { "id": "da344768-5f5d-4eaf-9bca-83815617f713", "slug": "da344768-5f5d-4eaf-9bca-83815617f713" }, "version": 0, "serialized_state": { "type": "Pending", "result": null, "message": null, "__version__": "0.3.3+309.gf1db024", "cached_inputs": null } } ] } } """ post = MagicMock(return_value=MagicMock(json=MagicMock(return_value=dict( data=json.loads(response))))) session = MagicMock() session.return_value.post = post monkeypatch.setattr("requests.Session", session) with set_temporary_config({ "cloud.graphql": "http://my-cloud.foo", "cloud.auth_token": "secret_token" }): client = Client() result = client.get_flow_run_info(flow_run_id="74-salt") assert isinstance(result, FlowRunInfoResult) assert isinstance(result.scheduled_start_time, datetime.datetime) assert result.scheduled_start_time.minute == 15 assert result.scheduled_start_time.year == 2019 assert isinstance(result.state, Pending) assert result.state.result == "42" assert result.state.message is None assert result.version == 0 assert isinstance(result.parameters, dict) assert result.parameters["x"]["deep"]["nested"] == 5 # ensures all sub-dictionaries are actually dictionaries assert json.loads(json.dumps(result.parameters)) == result.parameters assert isinstance(result.context, dict) assert result.context["my_val"] == "test"
def test_get_flow_run_info_raises_informative_error(monkeypatch): response = """ { "flow_run_by_pk": null } """ post = MagicMock(return_value=MagicMock(json=MagicMock(return_value=dict( data=json.loads(response))))) session = MagicMock() session.return_value.post = post monkeypatch.setattr("requests.Session", session) with set_temporary_config({ "cloud.graphql": "http://my-cloud.foo", "cloud.auth_token": "secret_token" }): client = Client() with pytest.raises(ClientError, match="not found"): client.get_flow_run_info(flow_run_id="74-salt")
def test_get_flow_run_info(patch_post): response = { "flow_run_by_pk": { "id": "da344768-5f5d-4eaf-9bca-83815617f713", "flow_id": "da344768-5f5d-4eaf-9bca-83815617f713", "name": "flow-run-name", "version": 0, "parameters": {}, "context": None, "scheduled_start_time": "2019-01-25T19:15:58.632412+00:00", "serialized_state": { "type": "Pending", "_result": { "type": "SafeResult", "value": "42", "result_handler": {"type": "JSONResultHandler"}, }, "message": None, "__version__": "0.3.3+309.gf1db024", "cached_inputs": None, }, "task_runs": [ { "id": "da344768-5f5d-4eaf-9bca-83815617f713", "task": { "id": "da344768-5f5d-4eaf-9bca-83815617f713", "slug": "da344768-5f5d-4eaf-9bca-83815617f713", }, "version": 0, "serialized_state": { "type": "Pending", "result": None, "message": None, "__version__": "0.3.3+309.gf1db024", "cached_inputs": None, }, } ], } } post = patch_post(dict(data=response)) with set_temporary_config( {"cloud.api": "http://my-cloud.foo", "cloud.auth_token": "secret_token"} ): client = Client() result = client.get_flow_run_info(flow_run_id="74-salt") assert isinstance(result, FlowRunInfoResult) assert isinstance(result.scheduled_start_time, datetime.datetime) assert result.scheduled_start_time.minute == 15 assert result.scheduled_start_time.year == 2019 assert isinstance(result.state, Pending) assert result.state.result == "42" assert result.state.message is None assert result.version == 0 assert isinstance(result.parameters, dict) assert result.context is None
def test_get_flow_run_info(monkeypatch): response = """ { "flow_run_by_pk": { "version": 0, "parameters": {}, "context": null, "scheduled_start_time": "2019-01-25T19:15:58.632412+00:00", "serialized_state": { "type": "Pending", "_result": {"type": "SafeResult", "value": "42", "result_handler": {"type": "JSONResultHandler"}}, "message": null, "__version__": "0.3.3+309.gf1db024", "cached_inputs": null }, "task_runs":[ { "id": "da344768-5f5d-4eaf-9bca-83815617f713", "task_id": "da344768-5f5d-4eaf-9bca-83815617f713", "version": 0, "serialized_state": { "type": "Pending", "result": null, "message": null, "__version__": "0.3.3+309.gf1db024", "cached_inputs": null } } ] } } """ post = MagicMock( return_value=MagicMock( json=MagicMock(return_value=dict(data=json.loads(response))) ) ) monkeypatch.setattr("requests.post", post) with set_temporary_config( {"cloud.graphql": "http://my-cloud.foo", "cloud.auth_token": "secret_token"} ): client = Client() result = client.get_flow_run_info(flow_run_id="74-salt") assert isinstance(result, FlowRunInfoResult) assert isinstance(result.scheduled_start_time, datetime.datetime) assert result.scheduled_start_time.minute == 15 assert result.scheduled_start_time.year == 2019 assert isinstance(result.state, Pending) assert result.state.result == "42" assert result.state.message is None assert result.version == 0 assert result.parameters == dict()
def create_prefect_flow_run(flow_name: str, project_name: str, task_refs: List, params: Mapping) -> str: """Creates new prefect flow run for given flow id, parameters, task references and API server URL to send GraphQL requests to. Returns results value and state from a Prefect flow run. """ try: flow_run = StartFlowRun(flow_name=flow_name, project_name=project_name, parameters=params) flow_run_id = flow_run.run() client = Client() while True: time.sleep(10) flow_run_info = client.get_flow_run_info(flow_run_id) flow_state = flow_run_info.state task_runs_info = flow_run_info.task_runs if flow_state.is_finished(): task_res_locs = {} for task_run in task_runs_info: # Return ref if ref string is a substring of any task slug ref = next((ref_str for ref_str in task_refs if ref_str in task_run.task_slug), None) if ref: task_id = task_run.id task_state = client.get_task_run_state(task_id) task_res_locs[ref] = task_state._result.location task_results = {} for ref, loc in task_res_locs.items(): local_res = LocalResult() result = local_res.read(loc) task_results[ref] = result.value return task_results, flow_state, task_res_locs except ValueError as err: raise err