Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get tasks status in AWS Step Functions (boto3)

I am currently using boto3 (the Amazon Web Services (AWS) SDK for Python) to create state machines, start executions and also in my workers to retrieve tasks and report their status (completed successfully or failed).

I have another service that needs to know the tasks' status and I would like to do so by retrieving it from AWS. I searched the available methods and it is only possible to get the status of a state machine/execution as a whole (RUNNING|SUCCEEDED|FAILED|TIMED_OUT|ABORTED).

There is also the get_execution_history method but each step is identified by an id numbered sequentially and there is no information about the task itself (only in the "stateEnteredEventDetails" event, where the name of the task is present, but the subsequentially events may not be related to it, so it is impossible to know if the task was successful or not).

Is it really not possible to retrieve the status of a specific task, or am I missing something?

Thank you!

like image 333
Sofia Avatar asked May 04 '20 21:05

Sofia


1 Answers

I had the same problem, and it seems that step functions does not consider the states and tasks as entities, and therefore there is not an API to get info about them.

In order to get info about the task's status you need to parse the information in the execution history. In my case I first check the execution status:

import boto3
import json
client = boto3.client("stepfunctions")

response = client.describe_execution(
    executionArn=EXECUTION_ARN
)
status = response["status"]

and if it is "FAILED" then I analyze the history and get the most relevant fields for my use case (for events of type "TaskFailed"):

response = client.get_execution_history(
    executionArn=EXECUTION_ARN,
    maxResults=1000
)
events = response["events"]

while response.get("nextToken"):
    response = client.get_execution_history(
        executionArn=EXECUTION_ARN,
        maxResults=1000,
        nextToken=response["nextToken"]
    )
    events += response["events"]
causes = [
    json.loads(e["taskFailedEventDetails"]["cause"])
    for e in events
    if e["type"] == "TaskFailed"
]

return [
    {
        "ClusterArn": cause["ClusterArn"],
        "Containers": [
            {
                "ContainerArn": container["ContainerArn"],
                "Name": container["Name"],
                "ExitCode": container["ExitCode"],
                "Overrides": cause["Overrides"]["ContainerOverrides"][i]
            }
            for i, container in enumerate(cause["Containers"])
        ],
        "TaskArn": cause["TaskArn"],
        "StoppedReason": cause["StoppedReason"]
    }
    for cause in causes
]

like image 188
jcozar87 Avatar answered Oct 19 '22 11:10

jcozar87