Interactive prompts allow transforms to pause and request input from users during execution. This enables dynamic, user-driven workflows where transforms can ask questions, collect parameters, or confirm actions.
**Client availability:** Interactive prompts are currently supported in Maltego Graph Desktop only. Do not rely on prompts in Maltego Graph Browser workflows.Enabling Interactive Transforms
To use prompts, set interactive=True in the @register_transform decorator:
from maltego.server import register_transform, MaltegoContext
from maltego.entities import Phrase
@register_transform(
display_name="My Interactive Transform",
transform_set="My Transforms",
interactive=True # Recommended: advertises prompt capability to client
)
async def my_interactive_transform(
entity: Phrase,
context: MaltegoContext
) -> Phrase:
...The ``interactive=True`` flag is **metadata** that tells the Maltego client this transform uses prompts during discovery.Choice Prompts
Use context.choice_prompt() to present options and let users select one or more:
from maltego.model.prompt import PromptItem
@register_transform(interactive=True, ...)
async def choice_example(entity: Phrase, context: MaltegoContext):
response = await context.choice_prompt(
message="Would you like to continue?",
options=[
PromptItem("yes", "Yes, continue"),
PromptItem("no", "No, stop"),
],
timeout=30, # Seconds before using default
default_option_id="yes" # Used if timeout occurs
)
if "no" in response.result:
return None
return Phrase("Continuing...")PromptItem Parameters
| Parameter | Type | Description |
|---|---|---|
item_id | str | Unique identifier returned in response.result |
display_name | str | Display text shown to user (optional, defaults to item_id) |
choice_prompt() Parameters
| Parameter | Type | Description |
|---|---|---|
message | str | Question or instruction shown to user |
options | List[PromptItem] | Available choices |
timeout | int | Seconds to wait before using default (optional) |
default_option_id | str | Option ID to use on timeout (optional) |
Response Object
The response contains:
result: List of selected option IDs (for choice prompts) or dict of values (for input prompts)reason: Why the prompt completed (COMPLETED,TIMED_OUT,CANCELLED)
Control Types
By default, choice_prompt displays options as a simple list. Use the control parameter to customize the UI.
from maltego.model.prompt import (
PromptItem,
DropdownControl,
RadioControl,
CheckboxControl,
ButtonControl,
)
# Dropdown - single selection from a dropdown menu
response = await context.choice_prompt(
message="Select a data source:",
options=[
PromptItem("dns", "DNS Records"),
PromptItem("whois", "WHOIS Data"),
],
control=DropdownControl(default_option_id="dns", label="Source"),
)
if "dns" in response.result:
# User selected DNS
...
# Radio buttons - single selection with all options visible
response = await context.choice_prompt(
message="Choose an action:",
options=[
PromptItem("scan", "Quick Scan"),
PromptItem("deep", "Deep Analysis"),
],
control=RadioControl(default_option_id="scan"),
)
if "deep" in response.result:
# User selected Deep Analysis
...
# Checkboxes - multiple selection
response = await context.choice_prompt(
message="Select features to enable:",
options=[
PromptItem("cache", "Enable Caching"),
PromptItem("log", "Verbose Logging"),
],
control=CheckboxControl(default_option_ids=["cache"]),
)
if "cache" in response.result:
# User selected caching
...
if "log" in response.result:
# User selected logging
...
# Buttons - single selection as clickable buttons
response = await context.choice_prompt(
message="How would you like to proceed?",
options=[
PromptItem("continue", "Continue"),
PromptItem("cancel", "Cancel"),
],
control=ButtonControl(default_option_id="continue"),
)
if "cancel" in response.result:
return None| Control | Selection | Use Case |
|---|---|---|
DropdownControl | Single | Many options, compact UI |
RadioControl | Single | Few options, all visible |
CheckboxControl | Multiple | Multi-select options |
ButtonControl | Single | Quick actions, confirmations |
Multi-Choice Prompts
Use multi_choice_prompt to display multiple controls in a single dialog:
response = await context.multi_choice_prompt(
message="Configure your search:",
controls=[
DropdownControl(
control_id="source",
label="Data Source",
options=[PromptItem("api1", "API 1"), PromptItem("api2", "API 2")],
default_option_id="api1",
),
CheckboxControl(
control_id="options",
label="Options",
options=[PromptItem("cache", "Use Cache"), PromptItem("retry", "Auto Retry")],
default_option_ids=["cache"],
),
],
timeout=60,
)
# For multi_choice_prompt, result is keyed by control_id
context.log.inform(f"Result: {response.result}")Input Prompts
Use context.input_prompt() to collect various types of data:
from maltego.model.prompt import InputPromptItem, InputTypes
@register_transform(interactive=True, ...)
async def input_example(entity: Phrase, context: MaltegoContext):
inputs = [
InputPromptItem("search_term", InputTypes.str, "default value"),
InputPromptItem("max_results", InputTypes.int, 10),
InputPromptItem("include_old", InputTypes.boolean, False),
]
response = await context.input_prompt(
message="Configure your search:",
items=inputs,
timeout=120
)
# Access collected values
search_term = response.result.get("search_term")
max_results = response.result.get("max_results")
...Available Input Types
| Type | Description | Default Value Example |
|---|---|---|
InputTypes.str | Single string | "default" |
InputTypes.str_list | List of strings | ["a", "b"] |
InputTypes.int | Single integer | 10 |
InputTypes.int_list | List of integers | [1, 2, 3] |
InputTypes.float | Single float | 3.14 |
InputTypes.float_list | List of floats | [1.0, 2.5] |
InputTypes.boolean | Checkbox (true/false) | False |
InputTypes.boolean_list | List of booleans | [True, False] |
InputTypes.date | Date picker | None |
InputTypes.date_list | List of dates | None |
InputTypes.datetime | Date and time picker | None |
InputTypes.datetime_range | Start and end datetime | None |
InputPromptItem Parameters
InputPromptItem(
input_id="field_name", # Key in response.result
input_type=InputTypes.str, # Type of input
default_value="default", # Optional default value
display_name="Field Name" # Optional display label
)Complete Example
Run maltego-transforms start my_project to create a new project from the template. See transforms/prompts_example.py for runnable examples of all prompt types covered in this guide.
Best Practices
- Always set reasonable timeouts - Don't leave users waiting indefinitely
- Provide sensible defaults - Users should be able to proceed quickly
- Use clear, concise messages - Users should understand what's being asked
- Log prompt outcomes - Help with debugging by logging what users chose
- Handle cancellation gracefully - Return meaningful results even if user cancels