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
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);
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
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);
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 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. |
isCached | Whether the API returned a cached result. See server-side task caching for more details. |
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. |
is_cached | Whether the API returned a cached result. See server-side task caching for more details. |
Error handling
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. When a parent task fails, any child tasks that are in
progress will be cancelled.If instead you want the parent task to continue executing, you can catch and handle errors:
typescriptCopied1import airplane, { RunTerminationError } from "airplane";23export default airplane.task(4{5slug: "javascript_example",6},7async () => {8const taskSlug = "CHILD_TASK_SLUG";910try {11const run = await airplane.execute<User>(taskSlug, {12email: "colin@airplane.dev",13});14return run.output;15} catch (err) {16if (!(err instanceof RunTerminationError)) {17throw err;18}19// Error is caught and handled.20console.log(`This task failed with status=${err.run.status}`);21}22},23);2425type User = { id: string; name: string; email: string };
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:10# Error is caught and handled.11print("This task failed with status: ", e.run.status)
Execute rules & constraints
Execute rules & constraints
- Each task has a maximum number of concurrent runs that can be executed at once, determined by your team's limits. If the maximum number of concurrent runs is exceeded, the task will be queued until a slot becomes available.
- Child runs will inherit the run 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.