Custom Adapters
The Custom Adapter feature lets you author an adapter in Python and store it outside any single integration, together with a typed configuration schema. You can reuse one custom adapter across integrations, and each adapter can hold several named configurations that each supply their own values.
Custom Adapters share the Shared Code page with Shared Modules and appear under the Custom Adapters tab.
Permissions
Users must have the can_use_custom_adapters permission to access the Custom Adapters tab. This permission is independent of can_use_shared_modules; a user might have either, both, or neither.
Anatomy
Users with the permission see the Custom Adapters tab on the Shared Code page.
A custom adapter comprises two kinds of object:
A Custom Adapter Code — the Python source and its configuration schema. This is the reusable definition.
One or more Configs — concrete sets of values that satisfy a Custom Adapter Code's schema. Each config belongs to exactly one Custom Adapter Code.
The tab contains these elements:
Adapter Selection Pane: Select an existing custom adapter, or start a new one.
Adapter Name: Name the adapter. The read-only System ID hint beneath this field shows the identifier that the platform derives from the name.
Description: Enter an optional free-text description.
Adapter Code: Enter the Python source for the adapter.
Config Schema: Define the configuration fields and their types.
Save and Delete: Save or remove the Custom Adapter Code.
Configs table: Lists the configs defined for the adapter, their active state, and their validation status. This table appears after you save the adapter.
Custom Adapter Code
Name
REQUIRED | Unique display name for the adapter.
System ID
DERIVED, READ-ONLY | Identifier used to reference the adapter. See System Identifier.
Description
OPTIONAL | Free-text description.
Adapter Code
REQUIRED | Python source for the adapter. See Adapter Code.
Config Schema
REQUIRED | Field names and their types. See Config Schema.
System Identifier
The platform derives the System ID automatically from the name; you cannot edit it directly. To derive it, the platform replaces each run of non-alphanumeric characters with a single underscore, removes leading and trailing underscores, and uppercases the result.
My REST API
MY_REST_API
acct-lookup (v2)
ACCT_LOOKUP_V2
The System ID must be unique across all custom adapters. If you save a name that derives to an identifier already in use, the platform rejects it with a validation error.
The platform recalculates the System ID from the name every time you save the adapter. Renaming an adapter changes its System ID, which can break existing references to the adapter.
Config Schema
The config schema is a JSON object mapping each field name to a type. It defines which values a config for this adapter must supply.
string
text
integer
whole number
float
number
boolean
true / false
array
JSON array
Enter as JSON in the config dialog.
object
JSON object
Enter as JSON in the config dialog.
file
file upload
The platform encrypts this value at rest as a base64 string. Maximum size 1 MB. See Encrypted Fields.
Field names must be strings. The platform rejects any type outside this list when you save the adapter.
Changing the schema of an adapter that already has configs can invalidate those configs. Adding a field leaves existing configs without a value for it; changing a field's type might cause existing values to no longer match. The interface shows a warning describing the impact before you save such a change. Removing a field drops that field's value from existing configs.
Configs
A config is a named set of values for one Custom Adapter Code. You enter a config through the config dialog. Each config has:
Name
REQUIRED | Name of the config.
Active
Whether the config is available for use.
Config Values
One input per schema field, typed according to the schema.
A config's values must match the adapter's schema exactly: every schema field must be present, no config can supply an unlisted field, and each value must match its field's type. You cannot save a config that does not satisfy these rules.
Encrypted Fields
The platform stores encrypted_string and file fields encrypted at rest, separately from the other config values.
In the config dialog and in API responses, the platform masks a stored encrypted value with the sentinel __ENCRYPTED__ instead of showing it. When you edit an existing config:
Leave the masked value in place to preserve the stored encrypted value.
Enter a new value to replace it.
The config dialog shows encrypted_string fields as password inputs. A file field shows an "uploaded" state with a Replace action. The platform reads each uploaded file as base64, and the file must not exceed 1 MB.
Adapter Code
The platform compiles and executes adapter code server-side. The Python editor performs syntax checking as you write the code.
Available Names
The platform injects these names into the adapter code's namespace; you do not need to import them:
BaseAdapter
Base class the adapter class extends.
AdapterRequest
The request object passed to execute().
AdapterResponse
The response object execute() returns.
AdapterFlowController
Flow-control helper for sequencing steps.
MessageTypes
Message-type constants used when reporting errors on a response.
base64
Python's base64 module, for decoding file fields.
The standard import statement is available for other modules (for example import requests).
Required Structure
Adapter code must define a class named exactly CustomAdapter that extends BaseAdapter:
If your code does not define a class named CustomAdapter, execution fails with the error "Custom adapter code must define a class named 'CustomAdapter'."
execute(self, request)is required. It receives anAdapterRequestand must return anAdapterResponse.validate_config(self)is optional. The platform calls it during config validation; see Config Validation.
The Request Object
request.payload
The field mappings the integration passes to the adapter.
request.service_name
The name of the service request invoking the adapter.
Access the Configuration
Inside the adapter, self.config is a plain dictionary of the resolved config values, with any encrypted fields already decrypted. Access values by key:
file fields arrive as base64-encoded strings. Decode them with the injected base64 module:
Return a Response
Build and return an AdapterResponse. Set success and payload, and report failures with add_message_and_stack_trace(message_type, message):
If the adapter does not handle an exception raised in execute(), the platform catches it and returns a failed AdapterResponse with the message type MessageTypes.UNCATEGORIZED_ERROR.
Example: Default Template
New adapters open with the following template, which authenticates with a bearer token, posts the request payload, and maps common request failures onto message types:
The template ships with a matching schema of base_url (string), api_key (encrypted_string), and timeout (integer).
Config Validation
The Validate action on a single config, and Validate All on the adapter, instantiate the adapter with that config and call its validate_config() method:
A
validate_config()that returns without raising marks the config as passed.An exception from
validate_config()marks the config as failed. View the raised message through the config's View Log action.A config whose code fails to compile fails validation with "Failed to compile custom adapter code: …".
Validation runs asynchronously; each config shows one of the following states:
Spinner
Validation in progress.
Green check
Passed.
Red error icon
Failed. Open View Log for the message.
Amber warning
Result unknown. The validation process did not report a result.
—
Not yet validated.
Custom Adapter Usage
A saved Custom Adapter Code's System ID identifies it. A config for that adapter must be active before the integration can use it. You invoke adapters from within an integration with the calladapter special function.
After the adapter is bound and active, it receives the integration's field mappings as request.payload and returns its AdapterResponse to the integration.
Limitations and Notes
Custom adapters provide no built-in authentication. You must implement any authentication a request requires in the adapter code, using values from the config schema. For example, store a token or password in an
encrypted_stringfield. See How to authenticate custom adapter requests.Adapter code must define a class named exactly
CustomAdapter.The platform derives the System ID from the name and changes it when you rename the adapter.
Deleting a Custom Adapter Code also deletes all of its configs. Before you delete, the interface reports the number of configs it removes.
Changing an adapter's config schema can invalidate existing configs. The interface warns you before you save such a change.
filefields have a 1 MB limit.The platform stores
encrypted_stringandfilevalues encrypted at rest and masks them in the interface and API.
Last updated
Was this helpful?