The Base Extension Class
Relevant source files
The following files were used as context for generating this wiki page:
The ExtensionBase class is the core architectural component of the Meltano Extension Developer Kit (EDK). It serves as an abstract base class (ABC) that defines the essential interface and lifecycle methods for building custom Meltano extensions. These extensions are typically used to wrap existing CLI tools or provide utility functionality within the Meltano ecosystem.
By inheriting from ExtensionBase, developers can implement standardized hooks for initialization, invocation, and metadata description. This ensures that all extensions built with the EDK maintain a consistent behavioral contract, allowing Meltano to interact with them predictably.
Sources: meltano/edk/extension.py:33-35, README.md:7-9
Core Interface and Lifecycle
The ExtensionBase class defines a specific lifecycle for extension execution. This lifecycle includes pre-invocation setup, the primary execution logic, and post-invocation cleanup.
Lifecycle Methods
| Method | Type | Description |
|---|---|---|
initialize(force) | Optional | On-demand initialization of the extension. Defaults to a no-op. |
pre_invoke(name, *args) | Optional | Setup logic executed before the main command. |
invoke(name, *args) | Required | The primary execution logic for the extension. |
post_invoke(name, *args) | Optional | Cleanup or reporting logic executed after the main command. |
describe() | Required | Returns metadata about the extension's capabilities and commands. |
Sources: meltano/edk/extension.py:36-84
Execution Flow
The following diagram illustrates the standard execution flow when an extension is triggered via the pass_through_invoker or a similar execution harness.
The pass_through_invoker method wraps these lifecycle steps in try-except blocks to ensure that unhandled exceptions are logged and result in a hard exit of the process.
Sources: meltano/edk/extension.py:109-148
Metadata and Description
Extensions must describe themselves so that Meltano can understand their available commands and capabilities. This is achieved through the describe() method, which returns a models.Describe object.
Formatting Descriptions
The EDK provides a describe_formatted method that can output this metadata in several formats defined by the DescribeFormat enum:
text: Uses a pretty-printed representation.json: Returns a JSON-serialized string of the description.yaml: Returns a YAML-serialized string of the description.
Sources: meltano/edk/extension.py:24-30, meltano/edk/extension.py:86-107
Data Models
The description is built using structured data classes that define how commands are exposed.
Sources: meltano/edk/models.py:6-38
Invocation and Subprocess Management
While ExtensionBase defines the interface, extensions often use the Invoker class within their invoke method to manage subprocesses. The Invoker handles executing binaries with specific environments and working directories.
Subprocess Execution Logic
The EDK supports both standard blocking execution and asynchronous execution with logged output.
Implementation Example
A typical implementation involves inheriting from ExtensionBase and implementing the abstract methods. Arguments are passed using the ExecArg type, which allows for str or bytes.
class CustomExtension(ExtensionBase):
def invoke(self, command_name: str | None, *command_args: ExecArg) -> None:
# Execution logic here
pass
def describe(self) -> models.Describe:
return models.Describe(
commands=[
models.ExtensionCommand(
name="my_extension",
description="A custom extension"
)
]
)
Sources: tests/test_meltano_edk.py:13-34, meltano/edk/types.py:10
Summary
The ExtensionBase class provides the structural foundation for all Meltano extensions. It enforces a consistent lifecycle (pre_invoke, invoke, post_invoke) and a standardized way to report capabilities via the describe method. Integrated with the Invoker utility and structured models, it allows developers to wrap complex CLI tools while maintaining the metadata requirements of the Meltano ecosystem.