Skip to content

Asynchronous workflows

Overview

If published in asynchronous mode, a workflow does not directly return the results of an analysis to an API client program. Instead, the client program must:

  1. Submit an analysis request, containing the input to the workflow, to immediately obtain a task ID.
  2. Poll NL Flow until the task is complete.
  3. Ask for the results of the task, that is the output of the workflow.

The publication mode is called asynchronous precisely because the workflow does not respond live, keeping the caller waiting, but "frees" the client immediately—so that it can do something else—while the analysis task runs in the background: it is up to the caller to "inform itself" on the status of the task and retrieve the results when the task is completed.

A workflow published in asynchronous mode therefore exposes resources:

  • To create a new analysis task
  • To know the status of one or more analysis tasks
  • To retrieve the input transmitted when requesting the creation of a task
  • To get the workflow output once an analysis task is finished
  • To cancel one or more analysis tasks

Commonalities

All requests for resources of a workflow published in asynchronous mode must have these characteristics:

  1. The endpoint has to start with:

    https://host/api/v1/runtime/workflow/workflowId/task

    where you have to replace:

    • host with the host name or IP address of the NL Flow runtime.
    • workflowId with the workflow ID.

    To get the workflow ID you can access the NL Flow application and:

    1. Open the workflow in the Workflows view of the dashboard.
    2. Display identifying information.
    3. Copy the value of the Workflow ID field.
  2. In every request you must set the following header:

    X-API-KEY: API key

    where you have to replace API key with the API key associated with the workflow.
    Learn more about API keys in the article dedicated to this topic inside the NL Flow manual.

Creation of a new analysis task

Endpoint

The endpoint coincides with the root common to all requests.

HTTP verb

The verb to use is POST.

Request headers

In addition to the common headers, add:

Content-type: application/json; charset=utf-8

Optionally, you can also add the X-Correlation-Id header for troubleshooting purposes.
Its value can be any string and must be unique for each request and can be mentioned when asking for support in case of unexpected errors. Support personnel can then track API calls based on this value when examining the NL Flow API logs.

Request body

The body of task creation requests must be an UTF-8 encoded JSON object. It is the input to the workflow and represents the document to analyze.
The object must contain all the keys that the workflow needs to use. They can be the keys expected by the first block of each flow: in the NL Flow application documentation you can find the description of the keys expected by the blocks, for example model blocks and processor blocks. Alternatively, they can be the keys defined in the workflow's input format.

Response

The HTTP status on success is 202 (Accepted).

The response body is a JSON object like this:

{
     "taskId": "a301ad0d-40d6-478a-a7a4-fd4a60aab8fd"
}

where taskId is the ID of the newly created task. This value must be used in all the subsequent requests about the task.

Task status

These resources are used to know the status of one or more tasks or to have the list of tasks in a given status.

Status of a given task

Endpoint

To the common stem it is necessary to add:

/taskId/status

where taskId is the ID of the task obtained in response to the task creation request.
This resource is normally requested multiple times, with an interval between subsequent requests, until the status of the task is COMPLETED. After that, the client program requests the task results resource.

HTTP verb

The verb to use is GET.

Request headers

No headers in addition to the common ones are required.

Request body

No body is needed for the request.

Response

The response body is a JSON object like this:

{
     "status": "COMPLETED"
}

where status is the status of the task.

Status of multiple tasks

Endpoint

To the common stem it is necessary to add:

/status?taskIds=task1Id[,task2Id[,...]]

where task1Id, task2Id, etc. are the IDs of the tasks.

HTTP verb

The verb to use is GET.

Request headers

No headers in addition to the common ones are required.

Request body

No body is needed for the request.

Response

The response body is a JSON object like this:

{
    "taskStatusMap": {
        "e6a631df-020c-4ff0-bc2b-f48a8e6a5036": "COMPLETED",
        "a860f051-bd6e-40e7-baa0-115a3963da7c": "COMPLETED",
    }
}

where the taskStatusMap object has a property for each task specified in the endpoint, if it exists. The property name is the task ID, the property value is the task status.

List of tasks in a given status

Endpoint

To get the list of only the tasks in certain statuses, add:

/status?taskStatuses=status1[,status2[,...]]

to the common stem, where status1, status2, etc. are the statuses of the tasks to list.

HTTP verb

The verb to use is GET.

Request headers

No headers in addition to the common ones are required.

Request body

No body is needed for the request.

Response

The response body is a JSON object like this:

{
    "taskStatusMap": {
        "e6a631df-020c-4ff0-bc2b-f48a8e6a5036": "COMPLETED",
        "a860f051-bd6e-40e7-baa0-115a3963da7c": "COMPLETED",
    }
}

where the taskStatusMap object has a property for each task. The property name is the task ID, the property value is one the task statuses specified in the endpoint.

List and status of all tasks

Endpoint

To get the list and the status of all the tasks, add:

/status

to the common stem.

HTTP verb

The verb to use is GET.

Request headers

No headers in addition to the common ones are required.

Request body

No body is needed for the request.

Response

The response body is a JSON object like this:

{
    "taskStatusMap": {
        "e6a631df-020c-4ff0-bc2b-f48a8e6a5036": "COMPLETED",
        "a860f051-bd6e-40e7-baa0-115a3963da7c": "COMPLETED",
        "3c7840de-d0e3-446e-8e4d-d8771a8b4ade": "RUNNING",
        "3a3da5c6-4754-4c10-8f58-922322ef0aba": "SUBMITTED"
    }
}

where the taskStatusMap object has a property for each task. The property name is the task ID, the property value is the task status.

Request associated with a task

This resource returns the workflow's input for a given task, that is the body of the task creation request.

Endpoint

To the common stem it is necessary to add:

/taskId/request

where taskId is the ID of the task obtained in response to the task creation request.

HTTP verb

The verb to use is GET.

Request headers

No headers in addition to the common ones are required.

Request body

No body is needed for the request.

Response

The response body is the JSON object that was used as the request body when submitting the task.

Results

This resource contains the workflow's output for a given, completed, task.
It can be requested multiple times as long as the task has not been canceled.

Endpoint

To the common stem it is necessary to add:

/taskId/response

where taskId is the task ID obtained in response to the task creation request.

HTTP verb

The verb to use is GET.

Request headers

No headers in addition to the common ones are required.

Request body

No body is needed for the request.

Response

If the status of the task is COMPLETED, the response body is a JSON corresponding to the workflow output.

If the status of the task is ERROR, the response body is a JSON containing the detail of the error, for example:

{
    "message": "Cannot execute workflow 5941302d-c109-4b20-aa1a-3370e1d91ce6 for taskId 6c3bb18c-acdc-4407-b4f4-5a0f4701bd38 because workflow does not become ready",
    "details": {
        "stream": {
            "id": "benthos",
            "desired": 1,
            "actual": 1,
            "status": "GREEN"
        },
        "services": [
            {
                "id": "executor-5941302d",
                "desired": 1,
                "actual": 0,
                "status": "RED",
                "rolloutStatus": "InProgress",
                "rolloutStatusReason": "AwaitingNewReplicasToBeAvailable",
                "replicasDetail": [
                    {
                        "name": "depl-executor-5941302d-5e1d319e-ee7c-4070-a00e-0ffa5e854c7ld4ch",
                        "ready": false,
                        "available": false,
                        "startedAt": "2023-07-17T12:30:20Z",
                        "age": "1h33m34.372636619s",
                        "status": "Running",
                        "atLatestSpec": true
                    }
                ]
            },
            {
                "id": "knowledge-m-63fd8140",
                "desired": 1,
                "actual": 1,
                "status": "GREEN",
                "rolloutStatus": "Complete",
                "replicasDetail": [
                    {
                        "name": "depl-knowledge-m-63fd8140-da9b70cc-42f3-486e-9b34-30f85a1e9zhxd",
                        "ready": true,
                        "available": true,
                        "startedAt": "2023-07-17T12:30:19Z",
                        "age": "1h33m36.372707126s",
                        "status": "Running",
                        "atLatestSpec": true
                    }
                ]
            }
        ]
    }
}

Cancellation

Request these resources to cancel tasks. Canceling completed tasks if a good practice but is not mandatory since any task is automatically canceled after 24 hours.

Cancellation of a given task

Endpoint

To cancel a given task, add:

/taskId

to the common stem, where taskId is the task ID obtained in response to the task creation request.

HTTP verb

The verb to use is DELETE.

Request headers

No headers in addition to the common ones are required.

Request body

No body is needed for the request.

Response

If successful, the response has no body and the HTTP status is 204 (No content).

Cancellation of all the tasks in a given status

Endpoint

To cancel only tasks in certain statuses, add:

?taskStatuses=status1[,status2[,...]]

to the common stem, where status1, status2, etc. are the statuses of the tasks to cancel.

HTTP verb

The verb to use is DELETE.

Request headers

No headers in addition to the common ones are required.

Request body

No body is needed for the request.

Response

If successful, the response has no body and the HTTP status is 204 (No content).

Cancellation of all the tasks

The endpoint coincides with the root common to all requests.

HTTP verb

The verb to use is DELETE.

Request headers

No headers in addition to the common ones are required.

Request body

No body is needed for the request.

Response

If successful, the response has no body and the HTTP status is 204 (No content).

Status of a task

The status of a task can be:

  • SUBMITTED: the task was submitted and has been queued.
  • RUNNING: the task was popped from the queue and it's being executed.
  • COMPLETED: the task was completed, results can be retrieved.
  • ERROR: there was an error during task execution, the description of the error can be retrieved.
  • DROPPED: the task was dropped because the workflow was unpublished.