Execute other tasks
Compose tasks together to create multi-step executions
Using the Airplane SDK, you can execute tasks programmatically from within other tasks. This is
commonly used to execute code in other languages (e.g. executing a Shell task from a JavaScript
task), to parallelize work, and to share logic between tasks.
Executing tasks with inline configuration
If your task is written in JavaScript or Python and you
want to call a task that is written in the same language and that uses inline configuration, then
you can call that task directly:
typescriptCopied1import airplane from "airplane";23export default airplane.task(4{5slug: "my_task",6},7async () => {8// This task will execute the child task defined in getUser.9const run = await getUser();10const user = run.output;11// ...12}13);1415type User = { id: string; name: string; email: string };1617export const getUser = airplane.task(18{19slug: "get_user",20},21async (): Promise<User> => {22const user = { id: "123", name: "Example", email: "example@airplane.dev" };23return user;24}25);
javascriptCopied1import airplane from "airplane";23export default airplane.task(4{5slug: "my_task",6},7async () => {8// This task will execute the child task defined in getUser.9const run = await getUser();10const user = run.output;11// ...12}13);1415export const getUser = airplane.task(16{17slug: "get_user",18},19async (params) => {20const user = { id: "123", name: "Example", email: "example@airplane.dev" };21return user;22}23);
pythonCopied1import airplane23@airplane.task()4def python_example():5# This task will execute the child task defined in get_user.6run = get_user()7return run.output89@airplane.task()10def get_user():11user = {"id": "123", "name": "Example", "email": "example@airplane.dev"}12return user
Executing tasks by slug
You can execute a task inside another task by referring to its slug. To execute a task from another
task, use the
airplane.execute
method from the JavaScript
or Python SDK. To do so, you'll first need its task
slug from the task editor. Pass this slug and an optional set of parameters into the SDK's execute
method:typescriptCopied1import airplane from "airplane";23type User = { id: string; name: string; email: string };45export default airplane.task(6{7slug: "my_task",8},9async () => {10const taskSlug = "CHILD_TASK_SLUG"; // Replace this with your task slug.11const run = await airplane.execute<User>(taskSlug, {12email: "colin@airplane.dev", // Replace this with your task's parameters.13});14return run.output;15}16);
javascriptCopied1import airplane from "airplane";23export default airplane.task(4{5slug: "my_task",6},7async () => {8const taskSlug = "CHILD_TASK_SLUG"; // Replace this with your task slug.9const run = await airplane.execute(taskSlug, {10email: "colin@airplane.dev", // Replace this with your task's parameters.11});12return run.output;13}14);
pythonCopied1import airplane23@airplane.task()4def python_example():5run = airplane.execute("CHILD_TASK_SLUG", {"email": "colin@airplane.dev"})6return run.output
Under the hood, this will look up the task's slug and perform a call to
airplane.execute
.The
airplane.execute
method asynchronously returns a Run
object with the following fields:Field | Description |
---|---|
id | The unique identifier of the run. |
taskID | The unique identifier of the executed task. |
paramValues | An object with the parameter values. |
status | The run's status. This will always be Succeeded . If a run was cancelled or failed, the SDK will throw an error that can be optionally caught. See Error handling below. |
output | The run's output. Defaults to null if the run produced no output. |
Field | Description |
---|---|
id | The unique identifier of the run. |
taskID | The unique identifier of the executed task. |
paramValues | An object with the parameter values. |
status | The run's status. This will always be Succeeded . If a run was cancelled or failed, the SDK will throw an error that can be optionally caught. See Error handling below. |
output | The run's output. Defaults to null if the run produced no output. |
Field | Description |
---|---|
id | The unique identifier of the run. |
task_id | The unique identifier of the executed task. |
param_values | An object with the parameter values. |
status | The run's status. This will always be Succeeded . If a run was cancelled or failed, the SDK will throw an error that can be optionally caught. See Error handling below. |
output | The run's output. Defaults to null if the run produced no output. |
Error handling
If a child task fails, a
RunTerminationError
will be thrown by airplane.execute
. By default,
this will bubble up and fail the parent task. You can handle these errors yourself by wrapping the
task execution:typescriptCopied1import airplane, { RunTerminationError } from "airplane";23export default airplane.task(4{5slug: "javascript_example",6},7async () => {8const taskSlug = "CHILD_TASK_SLUG"; // Replace this with your task slug.910try {11const run = await airplane.execute<User>(taskSlug, {12email: "colin@airplane.dev", // Replace this with your task's parameters.13});14return run.output;15} catch (err) {16if (!(err instanceof RunTerminationError)) {17throw err;18}19console.log(`This task failed with status=${err.run.status}`);20}21}22);2324type User = { id: string; name: string; email: string };
javascriptCopied1import airplane, { RunTerminationError } from "airplane";23export default airplane.task(4{5slug: "javascript_example",6},7async () => {8const taskSlug = "CHILD_TASK_SLUG"; // Replace this with your task slug.910try {11const run = await airplane.execute(taskSlug, {12email: "colin@airplane.dev", // Replace this with your task's parameters.13});14return run.output;15} catch (err) {16if (!(err instanceof RunTerminationError)) {17throw err;18}19console.log(`This task failed with status=${err.run.status}`);20}21}22);
pythonCopied1import airplane2from airplane.exceptions import RunTerminationException34@airplane.task()5def python_example():6try:7run = airplane.execute("exit_1", {"exit_code": 1})8return run.output9except RunTerminationException as e:10print("This task failed with status: ", e.run.status)
Execute rules & constraints
- Tasks are limited to 10 concurrent child runs and 1000 total child runs.
- All child runs are subject to the constraints of their parent. If the parent run times out or is cancelled, any child tasks that are in progress will be timed out or cancelled.