def fields_from_state(state: prefect.engine.state.State, timestamp=None): """ Returns a dict that contains fields that could be inferred from a state object """ if timestamp is None: timestamp = pendulum.now("utc") # update all state columns return dict( state=type(state).__name__, timestamp=timestamp, message=state.message, result=state.result, start_time=getattr(state, "start_time", None), serialized_state=state.serialize(), )
async def test_cloud_hook( cloud_hook_id: str, flow_run_id: str = None, state: prefect.engine.state.State = None, ): """ Sends a test payload to a hook Args: - cloud_hook_id (str): the hook id - flow_run_id (str, optional): a flow run ID to test with. If provided, the event will pull event details from the flow run - state (State, optional): a sample state """ if state is None: state = prefect.engine.state.Success(message="Test success state") serialized_state = state.serialize() if cloud_hook_id is None: raise ValueError("Invalid ID") # verify that the hook actually exists hook = await models.CloudHook.where(id=cloud_hook_id).first( {"type", "config", "tenant_id"}) if not hook: raise ValueError("Invalid ID") # if a flow run has been provided, construct an event mirroring the actual event # we'd expect to see if flow_run_id: flow_run = await models.FlowRun.where(id=flow_run_id).first( {"id", "tenant_id", "flow_id", "name", "version"}) new_flow_run = Box( id=flow_run.id, is_test_event=True, tenant_id=flow_run.tenant_id, flow_id=flow_run.flow_id, name=flow_run.name, version=flow_run.version + 1, state=type(state).__name__, serialized_state=state.serialize(), ) flow = await models.Flow.where(id=flow_run.flow_id).first( selection_set={ "id": True, "tenant_id": True, "name": True, "environment": True, "version_group_id": True, }) tenant = await models.Tenant.where(id=flow_run.tenant_id ).first({"id", "slug"}) test_event = events.FlowRunStateChange( flow_run=new_flow_run.to_dict(), flow=flow.dict(), tenant=tenant.dict(), state=dict( version=1, state=serialized_state["type"], serialized_state=serialized_state, ), ) # otherwise populate the event with dummy data else: test_event = events.FlowRunStateChange( is_test_event=True, flow_run=dict(id=str(uuid.uuid4()), name=names.generate_slug(2)), tenant=dict(id=hook.tenant_id, slug="test-slug"), flow=dict(id=str(uuid.uuid4()), name="Cloud Hook Test Flow"), state=dict( version=1, state=serialized_state["type"], serialized_state=serialized_state, ), ) if hook.type == "WEBHOOK": await _call_webhook(url=hook.config["url"], event=test_event) elif hook.type == "SLACK_WEBHOOK": await _call_slack_webhook(url=hook.config["url"], event=test_event) elif hook.type == "PREFECT_MESSAGE": await _call_prefect_message(event=test_event) elif hook.type == "TWILIO": await _call_twilio( account_sid=hook.config["account_sid"], auth_token=hook.config["auth_token"], messaging_service_sid=hook.config["messaging_service_sid"], to=hook.config["to"], event=test_event, ) elif hook.type == "PAGERDUTY": await _call_pagerduty( api_token=hook.config["api_token"], routing_key=hook.config["routing_key"], severity=hook.config["severity"], event=test_event, ) else: raise ValueError("Invalid type")