Prompts
Wait for a response from an operator before continuing
Tasks can easily gather input from operators using prompts. Each prompt contains a parameter form,
similar to what you see when executing a task or runbook. When a prompt is created, a run will wait
for a response before continuing. Prompts allow you to specify reviewers with with
Approvals to build dynamic approval flows.
Prompts are automatically cancelled when their containing task times out which occurs after 1 hour
by default.
For prompts that may take longer than 1 hour to respond to, you can extend the timeout of a
standard-runtime task up to 12 hours or a workflow runtime
task up to 60 days.
See Timeouts for more information.
Example: dry runs
Example: dry runs
A common use case for prompts is to perform dry-runs. Let's look at an example:
typescriptCopied1import airplane from "airplane";23export default airplane.task(4{5slug: "task_dryrun",6},7async () => {8// Perform a dry-run and show the output to the operator with a display.9const dryRun = await airplane.execute("my_task_slug", {10dry_run: true,11});12await airplane.display.json(dryRun.output);1314// Ask the operator if we should continue.15const { ok } = await airplane.prompt(16{ ok: "boolean" },17{18description: `Review the dry-run output above. If it looks correct, select OK to apply the changes.`,19},20);21if (!ok) {22await airplane.display.text("Exiting due to bad dryrun");23return;24}2526// If confirmed, we can re-run:27const run = await airplane.execute("my_task_slug", {28dry_run: false,29});3031return run.output;32},33);
pythonCopied1import airplane234@airplane.task()5def task_dryrun():6# Perform a dry-run and show the output to the operator with a display.7dry_run = airplane.execute(8"my_task_slug",9{10"dry_run": True,11},12)13airplane.display.json(dry_run.output)14# Ask the operator if we should continue.15airplane.prompt(16description=(17"Review the dry-run output above. If it looks correct, "18"click OK to apply the changes."19),20)21# If confirmed, we can re-run:22run = airplane.execute(23"my_task_slug",24{25"dry_run": False,26},27)
If you've done UNIX scripting before, you have likely seen this pattern using the
read
command --
e.g.bashCopied1# perform a dry-run...23read -p "Continue? [yN] " -n 1 -r4echo5if [[ $REPLY =~ ^[Yy]$ ]]6then7# apply!8fi
Compared to the classic shell script, prompts offer a few compelling advantages:
- Notifications: Users are automatically notified when prompted.
- Parameters: Prompts can ask for arbitrary parameters with validation.
- Slack: Prompts can be responded to directly from Slack.
Parameters
Parameters
Prompt parameters support the same configuration options as task parameters e.g. default values,
descriptions, constraints, and more! See Parameters for more information about
Airplane parameters.
Short text
Short text
Creates a prompt for a short text input.

typescriptCopied1const { email } = await airplane.prompt(2// Mapping of slug -> parameter definition3{ email: "shorttext" },4);5// or6const { email } = await airplane.prompt({7// Mapping of slug -> parameter definition8email: {9type: "shorttext",10name: "Email address",11// ...12},13});
pythonCopied1values = airplane.prompt(2# Mapping of slug -> parameter definition3{"email": str}4)5# Access prompt value via values['email']67# or8values = airplane.prompt(9{10# Mapping of slug -> parameter definition11#12# More details about inline parameter configuration can be found here:13# https://docs.airplane.dev/tasks/python-config#additional-configuration14#15# `Annotated` must be imported from the `typing` module in Python 3.9+ or16# from the `typing_extensions` module in Python 3.8 and below.17"email": Annotated[18str,19airplane.ParamConfig(20name="Email address",21# ...22),23]24},25)26# Access prompt value via values['email']
Long text
Long text
Creates a prompt for a long text input that renders as a multi-line
text area.

typescriptCopied1const { reason } = await airplane.prompt(2// Mapping of slug -> parameter definition3{ reason: "longtext" },4);5// or6const { reason } = await airplane.prompt({7// Mapping of slug -> parameter definition8reason: {9type: "longtext",10name: "Refund reason",11// ...12},13});
pythonCopied1values = airplane.prompt(2# Mapping of slug -> parameter definition3{"reason": airplane.LongText}4)5# Access prompt value via values['reason']67# or8values = airplane.prompt(9{10# Mapping of slug -> parameter definition11#12# More details about inline parameter configuration can be found here:13# https://docs.airplane.dev/tasks/python-config#additional-configuration14#15# `Annotated` must be imported from the `typing` module in Python 3.9+ or16# from the `typing_extensions` module in Python 3.8 and below.17"reason": Annotated[18airplane.LongText,19airplane.ParamConfig(20name="Refund reason",21# ...22),23]24},25)26# Access prompt value via values['reason']
SQL
SQL
Creates a prompt for a SQL input that renders within a code editor with SQL
syntax highlighting.

typescriptCopied1const { query } = await airplane.prompt(2// Mapping of slug -> parameter definition3{ query: "sql" },4);5// or6const { query } = await airplane.prompt({7// Mapping of slug -> parameter definition8query: {9type: "sql",10name: "SQL query",11// ...12},13});
pythonCopied1values = airplane.prompt(2# Mapping of slug -> parameter definition3{"query": airplane.SQL}4)5# Access prompt value via values['query']67# or8values = airplane.prompt(9{10# Mapping of slug -> parameter definition11#12# More details about inline parameter configuration can be found here:13# https://docs.airplane.dev/tasks/python-config#additional-configuration14#15# `Annotated` must be imported from the `typing` module in Python 3.9+ or16# from the `typing_extensions` module in Python 3.8 and below.17"query": Annotated[18airplane.SQL,19airplane.ParamConfig(20name="SQL query",21# ...22),23]24},25)26# Access prompt value via values['query']
Float
Float
Creates a prompt for a floating point input.

typescriptCopied1const { cost } = await airplane.prompt(2// Mapping of slug -> parameter definition3{ cost: "float" },4);5// or6const { cost } = await airplane.prompt({7// Mapping of slug -> parameter definition8cost: {9type: "float",10name: "Amount to charge",11// ...12},13});
pythonCopied1values = airplane.prompt(2# Mapping of slug -> parameter definition3{"cost": float}4)5# Access prompt value via values['cost']67# or8values = airplane.prompt(9{10# Mapping of slug -> parameter definition11#12# More details about inline parameter configuration can be found here:13# https://docs.airplane.dev/tasks/python-config#additional-configuration14#15# `Annotated` must be imported from the `typing` module in Python 3.9+ or16# from the `typing_extensions` module in Python 3.8 and below.17"cost": Annotated[18float,19airplane.ParamConfig(20name="Amount to charge",21# ...22),23]24},25)26# Access prompt value via values['cost']
Integer
Integer
Creates a prompt for an integer input.

typescriptCopied1const { count } = await airplane.prompt(2// Mapping of slug -> parameter definition3{ count: "integer" },4);5// or6const { count } = await airplane.prompt({7// Mapping of slug -> parameter definition8count: {9type: "integer",10name: "Record count",11// ...12},13});
pythonCopied1values = airplane.prompt(2# Mapping of slug -> parameter definition3{"count": int}4)5# Access prompt value via values['count']67# or8values = airplane.prompt(9{10# Mapping of slug -> parameter definition11#12# More details about inline parameter configuration can be found here:13# https://docs.airplane.dev/tasks/python-config#additional-configuration14#15# `Annotated` must be imported from the `typing` module in Python 3.9+ or16# from the `typing_extensions` module in Python 3.8 and below.17"count": Annotated[18int,19airplane.ParamConfig(20name="Record count",21# ...22),23]24},25)26# Access prompt value via values['count']
Boolean
Boolean
Creates a prompt for a boolean input.

typescriptCopied1const { ok } = await airplane.prompt(2// Mapping of slug -> parameter definition3{ ok: "boolean" },4);5// or6const { ok } = await airplane.prompt({7// Mapping of slug -> parameter definition8ok: {9type: "boolean",10name: "Continue",11// ...12},13});
pythonCopied1value = airplane.prompt(2# Mapping of slug -> parameter definition3{"ok": bool}4)5# Access prompt value via value['ok']67# or8value = airplane.prompt(9{10# Mapping of slug -> parameter definition11#12# More details about inline parameter configuration can be found here:13# https://docs.airplane.dev/tasks/python-config#additional-configuration14#15# `Annotated` must be imported from the `typing` module in Python 3.9+ or16# from the `typing_extensions` module in Python 3.8 and below.17"ok": Annotated[18bool,19airplane.ParamConfig(20name="Continue",21# ...22),23]24},25)26# Access prompt value via value['ok']
Date
Date
Creates a prompt for a date input. Dates identify a day of the year and do
not include a time component. If you need that, see Datetime.

typescriptCopied1const { date } = await airplane.prompt(2// Mapping of slug -> parameter definition3{ date: "date" },4);5// or6const { date } = await airplane.prompt({7// Mapping of slug -> parameter definition8date: {9type: "date",10name: "Start date",11// ...12},13});
pythonCopied1values = airplane.prompt(2# Mapping of slug -> parameter definition3{"date": datetime.date}4)5# Access prompt value via values['date']67# or8values = airplane.prompt(9{10# Mapping of slug -> parameter definition11#12# More details about inline parameter configuration can be found here:13# https://docs.airplane.dev/tasks/python-config#additional-configuration14#15# `Annotated` must be imported from the `typing` module in Python 3.9+ or16# from the `typing_extensions` module in Python 3.8 and below.17"date": Annotated[18datetime.date,19airplane.ParamConfig(20name="Start date",21# ...22),23]24},25)26# Access prompt value via values['date']
Datetime
Datetime

typescriptCopied1const { timestamp } = await airplane.prompt(2// Mapping of slug -> parameter definition3{ timestamp: "datetime" },4);5// or6const { timestamp } = await airplane.prompt({7// Mapping of slug -> parameter definition8timestamp: {9type: "datetime",10name: "Incident start",11// ...12},13});
pythonCopied1values = airplane.prompt(2# Mapping of slug -> parameter definition3{"timestamp": datetime.datetime}4)5# Access prompt value via values['timestamp']67# or8values = airplane.prompt(9{10# Mapping of slug -> parameter definition11#12# More details about inline parameter configuration can be found here:13# https://docs.airplane.dev/tasks/python-config#additional-configuration14#15# `Annotated` must be imported from the `typing` module in Python 3.9+ or16# from the `typing_extensions` module in Python 3.8 and below.17"timestamp": Annotated[18datetime.datetime,19airplane.ParamConfig(20name="Incident start",21# ...22),23]24},25)26# Access prompt value via values['timestamp']
File
File
Creates a prompt for a File input.

typescriptCopied1const { photo } = await airplane.prompt(2// Mapping of slug -> parameter definition3{ photo: "upload" },4);5// or6const { photo } = await airplane.prompt({7// Mapping of slug -> parameter definition8photo: {9type: "upload",10name: "Receipt photo",11// ...12},13});
pythonCopied1values = airplane.prompt(2# Mapping of slug -> parameter definition3{"photo": airplane.File}4)5# Access prompt value via values['photo']67# or8values = airplane.prompt(9{10# Mapping of slug -> parameter definition11#12# More details about inline parameter configuration can be found here:13# https://docs.airplane.dev/tasks/python-config#additional-configuration14#15# `Annotated` must be imported from the `typing` module in Python 3.9+ or16# from the `typing_extensions` module in Python 3.8 and below.17"photo": Annotated[18airplane.File,19airplane.ParamConfig(20name="Receipt photo",21# ...22),23]24},25)26# Access prompt value via values['photo']
Config variables
Config variables
Support for prompts with Config variables parameters is coming soon.
JSON
JSON
Creates a prompt for a JSON input.

typescriptCopied1const { payload } = await airplane.prompt(2// Mapping of slug -> parameter definition3{ payload: "json" },4);5// or6const { payload } = await airplane.prompt({7// Mapping of slug -> parameter definition8payload: {9type: "json",10name: "JSON Payload",11// ...12},13});
pythonCopied1values = airplane.prompt(2# Mapping of slug -> parameter definition3{"payload": airplane.JSON}4)5# Access prompt value via values['payload']67# or8values = airplane.prompt(9{10# Mapping of slug -> parameter definition11#12# More details about inline parameter configuration can be found here:13# https://docs.airplane.dev/tasks/python-config#additional-configuration14#15# `Annotated` must be imported from the `typing` module in Python 3.9+ or16# from the `typing_extensions` module in Python 3.8 and below.17"payload": Annotated[18airplane.JSON,19airplane.ParamConfig(20name="JSON Payload",21# ...22),23]24},25)26# Access prompt value via values['payload']
Cancellation
Cancellation
Cancelling a prompt will throw an error. You can handle this error in your code to perform any
cleanup or other actions.

typescriptCopied1try {2const { amount } = await airplane.prompt(3{ amount: "integer" },4{ description: "## How much should the customer be refunded?" },5);6} catch (err) {7// import { PromptCancelledError } from "airplane";8if (err instanceof PromptCancelledError) {9// Handle cancellation10airplane.display.text("Refund prompt was cancelled, no refund was issued.");11}12}
pythonCopied1try:2airplane.prompt(3{"amount": int}, description="## How much should the customer be refunded?"4)5except airplane.PromptCancelledError:6airplane.display.text("Refund prompt was cancelled, no refund was issued.");
Examples
Examples
Multi-parameter forms
Multi-parameter forms
Create a multi-parameter form by specifying more than one parameter.

typescriptCopied1const { amount, reason } = await airplane.prompt({2// Mapping of slug -> parameter definition3reason: "shorttext",4amount: "float",5});6// or7const { amount, reason } = await airplane.prompt({8// Mapping of slug -> parameter definition9reason: {10type: "shorttext",11name: "Refund reason",12// ...13},14amount: {15type: "float",16name: "Refund amount",17// ...18},19});
pythonCopied1values = airplane.prompt(2{3# Mapping of slug -> parameter definition4"reason": str,5"amount": float,6},7)8# Access prompt value via values['reason'], values['amount']910# or11values = airplane.prompt(12{13# Mapping of slug -> parameter definition14#15# More details about inline parameter configuration can be found here:16# https://docs.airplane.dev/tasks/python-config#additional-configuration17#18# `Annotated` must be imported from the `typing` module in Python 3.9+ or19# from the `typing_extensions` module in Python 3.8 and below.20"reason": Annotated[21str,22airplane.ParamConfig(23name="Refund reason",24# ...25),26],27"amount": Annotated[28float,29airplane.ParamConfig(30name="Refund amount",31# ...32),33],34},35)36# Access prompt value via values['reason'], values['amount']
Confirmation
Confirmation
Create a prompt that has no parameters to ask users for confirmation.

typescriptCopied1// Convenience helper for prompts with no parameters2await airplane.prompt.confirm({ description: "## Please review run before continuing." });34// Equivalent to5await airplane.prompt({}, { description: "## Please review run before continuing." });
pythonCopied1airplane.prompt(description="## Please review run before continuing.")
Select options
Select options
Create a prompt for selecting a value from a list of options. Accepts values numbers, strings,
booleans, and objects.

typescriptCopied1const users = [2{ name: "Colin", id: "usr1" },3{ name: "Lee", id: "usr2" },4];5const user = await airplane.prompt.select("User", users, {6optionToLabel: (user) => user.name,7});
pythonCopied1values = airplane.prompt(2# Mapping of slug -> parameter definition3#4# More details about inline parameter configuration can be found here:5# https://docs.airplane.dev/tasks/python-config#additional-configuration6#7# `Annotated` must be imported from the `typing` module in Python 3.9+ or8# from the `typing_extensions` module in Python 3.8 and below.9{10"user": Annotated[11str,12airplane.ParamConfig(13options=[14airplane.LabeledOption(label="usr1", value="Colin"),15airplane.LabeledOption(label="usr2", value="Lee"),16]17),18]19}20);21# Access prompt value via values['user']
Background prompts
Background prompts
Prompts can be created in the background via
prompt.background
. When used in combination with the
Submit Prompt API endpoint, you are able to able to programmatically
submit prompts from outside of Airplane's runtime.typescriptCopied1// Create a prompt in the background to get an ID.2const myPrompt = await airplane.prompt.background({ deploy_succeeded: "boolean" });34// Start a downstream processes and pass a reference to the prompt via its ID.5await airplane.rest.request("deploy_resource", "POST", "/startDeploy", {6body: { promptID: myPrompt.promptID },7});89// In this case, the request from the downstream processes would look like10// curl https://api.airplane.dev/v0/prompts/submit \11// -X POST \12// -H "X-Airplane-API-Key: $AIRPLANE_API_KEY" \13// -d '{14// "id": "pmt20221122zyydx3rho2t",15// "values": {16// "deploy_succeeded": "true",17// }18//}'1920// Wait on the downstream process to submit the prompt via the Airplane API.21const { deploy_succeeded } = await myPrompt.wait();
pythonCopied1# Create a prompt in the background to get an ID.2my_prompt = airplane.prompt({"deploy_succeeded": bool}, background=True)34# Start a downstream processes and pass a reference to the prompt via its ID.5airplane.rest.request(6"deployResource",7"POST",8"/startDeploy",9body={"promptID": my_prompt.prompt_id},10)1112# In this case, the request from the downstream processes would look like13# curl https://api.airplane.dev/v0/prompts/submit \14# -X POST \15# -H "X-Airplane-API-Key: $AIRPLANE_API_KEY" \16# -d '{17# "id": "pmt20221122zyydx3rho2t",18# "values": {19# "deploy_succeeded": "true",20# }21# }'2223# Wait on the downstream process to submit the prompt via the prompts submit endpoint.24values = my_prompt.wait()
Finding the prompt submitter
Finding the prompt submitter
Background prompts expose a method that returns metadata about
the user who submitted the prompt (if any).
typescriptCopied1// Create a prompt in the background2const myPrompt = await airplane.prompt.background({ deploy_succeeded: "boolean" });34// Wait for the prompt to be submitted5const { deploy_succeeded } = await myPrompt.wait();67// Get the prompt submitter8const { name, email } = await myPrompt.submitter();
pythonCopied1# Create a prompt in the background2my_prompt = airplane.prompt({"deploy_succeeded": bool}, background=True)34# Wait for the prompt to be submitted5values = my_prompt.wait()67# Get the prompt submitter8submitter = my_prompt.submitter()9# submitter.name, submitter.email
Slack support
Slack support
Airplane's Slack integration supports submitting prompts via Slack. For more information, see
Slack integration.
SDK reference
SDK reference
See Prompt SDK reference for more information.