Use maltego.server.TransformSetting to declare extra inputs that Maltego should collect and send to a transform. At execution time the SDK normalizes those inputs into the transform's settings parameter, keyed by the original TransformSetting.name.
**Client availability:** Basic transform settings are supported in Maltego Graph Browser and Maltego Graph Desktop. Global settings and settings marked ``auth=True`` are currently supported in Maltego Graph Desktop only.Basic usage
from typing import Any, Dict
from maltego.entities import Phrase
from maltego.server import TransformSetting, register_transform
@register_transform(
display_name="Search API [Acme]",
settings=[
TransformSetting(
name="api_key",
display_name="API Key",
optional=False,
auth=True,
popup=True,
),
TransformSetting(
name="max_results",
display_name="Maximum Results",
type="int",
default_value=25,
),
],
)
async def search(
input_entity: Phrase,
settings: Dict[str, Any],
) -> Phrase:
api_key = settings["api_key"]
max_results = settings["max_results"]
return Phrase(f"{api_key}:{max_results}")Common type values include string, int, double, boolean, date, datetime, daterange, and the corresponding list variants. For an end-to-end walkthrough, see the Writing Your First Transform (Quickstart) article.
Setting types
The type parameter accepts either a TransformSetting.Types member or the corresponding wire string. The SDK deserializes the value to the Python type shown in the table.
TransformSetting.Types | Wire string | Python runtime type | | Notes |
|---|---|---|---|
Types.str | "string" | str | | Default type when type is omitted |
Types.int |
|
| |
Types.float |
|
| |
Types.boolean |
|
| |
Types.date |
|
| |
Types.datetime |
|
| |
Types.datetime_range |
|
| Relative or absolute range; see "Date ranges" below |
Types.str_list |
|
| |
Types.int_list |
|
| |
Types.float_list |
|
| |
Types.boolean_list |
|
| |
Types.date_list |
|
|
Popup vs persistent
The popup parameter controls when Maltego shows the settings dialog to the user before running a transform.
popup=False(the default) -- persistent: Maltego stores the value after the first run and reuses it silently on subsequent runs. Use this for stable configuration such as API keys, server URLs, or filter flags.popup=True-- popup: Maltego opens the settings dialog on every execution, giving the user the opportunity to change the value each time. Use this for inputs that vary between runs, such as search queries or time windows.
settings=[
# User is prompted on every run — time window changes frequently
TransformSetting(
name="search_window",
display_name="Search Window",
type=TransformSetting.Types.datetime_range,
popup=True,
),
# Stored once and reused silently — stable configuration value
TransformSetting(
name="api_endpoint",
display_name="API Endpoint URL",
type=TransformSetting.Types.str,
default_value="https://api.example.com",
popup=False,
),
]Required vs optional
The optional parameter controls whether the transform can run without a value for this setting.
optional=True(the default) -- the transform runs even when the user has not supplied a value; your code receivesNonefor that setting. Always provide a fallback when reading optional settings.optional=False-- required: Maltego blocks execution and shows a validation error if the user has not supplied a value. Your code can safely assume the value is present (non-None).
settings=[
# Execution is blocked if this is blank
TransformSetting(
name="search_query",
display_name="Search Query",
type=TransformSetting.Types.str,
optional=False,
),
# Transform still runs; fall back to default_value or a hardcoded fallback
TransformSetting(
name="result_limit",
display_name="Result Limit",
type=TransformSetting.Types.int,
default_value=10,
optional=True,
),
]
# In the transform function:
query: str = settings["search_query"] # safe: guaranteed present
limit: int = settings.get("result_limit") or 10 # safe: provide fallbackDate ranges
The datetime_range type accepts either a relative named range or an absolute start/end pair.
Relative range -- pass one of the 25 daterange.Ranges members:
from maltego.server import TransformSetting, daterange
TransformSetting(
name="time_window",
display_name="Time Window",
type=TransformSetting.Types.datetime_range,
default_value=daterange(date_range=daterange.Ranges.last_7_days),
)Available relative date ranges:
daterange.Ranges.todaydaterange.Ranges.yesterdaydaterange.Ranges.week_to_datedaterange.Ranges.business_week_to_datedaterange.Ranges.month_to_datedaterange.Ranges.year_to_datedaterange.Ranges.previous_weekdaterange.Ranges.previous_business_weekdaterange.Ranges.previous_monthdaterange.Ranges.previous_yeardaterange.Ranges.last_15_minutesdaterange.Ranges.last_30_minutesdaterange.Ranges.last_4_hoursdaterange.Ranges.last_12_hoursdaterange.Ranges.last_24_hoursdaterange.Ranges.last_7_daysdaterange.Ranges.last_30_daysdaterange.Ranges.last_60_daysdaterange.Ranges.last_90_daysdaterange.Ranges.last_6_monthsdaterange.Ranges.last_1_yeardaterange.Ranges.last_2_yearsdaterange.Ranges.last_5_yearsdaterange.Ranges.last_10_yearsdaterange.Ranges.since_unix_epoch_time
Absolute range -- pass explicit start and end objects. Both must be date or datetime (mixing is allowed); you must supply both or neither:
from datetime import date
from maltego.server import daterange
absolute_range = daterange(start=date(2024, 1, 1), end=date(2024, 3, 31))At runtime the SDK deserializes the wire value to a daterange object. Access start, end, and the named range:
window = settings.get("time_window")
if window:
if window.range: # relative — a daterange.Ranges member
print(window.range.value)
else: # absolute
print(window.start, window.end)Default-value semantics
The default_value parameter sets the initial value shown in the Maltego settings dialog:
- If
default_value=None(the default), the field is shown empty. - The value must match the declared
type; passing a mismatched type raisesTypeErrorat import time. - For list types (
str_list,int_list, ...), pass a Python list whose elements match the inner type. dateanddatetimevalues are normalized to UTC during construction.- When
optional=Trueand the user clears the field, your transform receivesNoneregardless of anydefault_value--default_valueis only a display hint, not a server-side fallback.
Setting-name rules
The name parameter must be a non-empty string of 1-128 characters. It must start with a letter, digit, or underscore and contain only ASCII letters, digits, underscores, hyphens, and dots:
valid: api_key max-results acme.config.v2
invalid: .hidden --flag (empty string)Violating this rule raises ValueError at import time.
Naming and scope
The discovery payload serializes a setting name differently depending on the flags you set. The important distinction is:
- Discovery / storage name: what the client sees and stores.
- Runtime settings key: what your transform reads in
settings.
The SDK strips the discovery prefixes during execution, so your transform still reads the original name.
| Flags | Discovery name | Runtime key in settings | Recommended use |
|---|---|---|---|
| Default | {ns}.{transform}.{name} | name | Normal per-transform settings |
is_global=True | global#{ns}.{name} | name | Share one stored value across transforms in the same namespace |
is_global_setting=True | {ns}.global.global#{name} | name | Compatibility with older global-setting naming |
is_oauth=True | name | name | OAuth token setting injected by the SDK |
use_raw_name=True | name | name | Reuse a pre-existing external setting name as-is |
is_global=True is the current SDK flag for one shared namespace-wide value. is_global_setting=True is a compatibility flag for integrations that already rely on the older global-setting naming shape. Runtime access remains settings.get("<name>") for both flags because the SDK deserializes settings back to the original name.
Auth-related settings
auth=True marks a setting as authentication-related. Use it for API keys, passwords, or similar sensitive values that should be presented as auth inputs in the Maltego client.
TransformSetting(
name="api_key",
display_name="API Key",
optional=False,
auth=True,
popup=True,
)is_oauth=True is different: it identifies the special token setting used by OAuth-backed transforms. In normal usage you do not set it manually. The SDK creates that setting for you when you pass authenticator=... to register_transform.
OAuth-backed settings
When you register a transform with an authenticator, the server injects an additional hidden setting with this shape:
TransformSetting(
name=OAUTH.access_token_input,
display_name="OAuth Token",
optional=True,
auth=True,
popup=False,
is_oauth=True,
)The transform still reads the token by the original name:
token = settings[OAUTH.access_token_input]See the OAuth Authentication article for the full OAuth flow.
Global settings
Use global settings when the same value should be reused across more than one transform:
settings=[
TransformSetting(
name="workspace_id",
display_name="Workspace",
is_global=True,
),
]is_global=True is the current SDK flag for new code. Use is_global_setting=True only when you need compatibility with an existing global setting name that was already distributed to clients. Runtime access remains settings.get("<name>") for both forms.
API reference
For the generated class reference, see the SDK API Reference article.