SDK reference
Generated from the docstrings in civex-plugin-sdk's public API (civex_plugin_sdk.__all__). See Writing a plugin for a guide to using it.
civex_plugin_sdk
SDK for authoring out-of-process (subprocess/container tier) civex workflow plugins.
Subclass Plugin, declare id/name/inputs/outputs/Config,
implement invoke(), and call serve() (Tier 1) or serve_container()
(Tier 2) from the plugin script's __main__ -- see
docs/extending/writing-a-plugin.md for the full authoring guide.
IO_TYPES = ('any', 'string', 'number', 'boolean', 'bytes', 'table', 'files', 'records', 'mapping', 'list')
module-attribute
Vocabulary for IOSpec.type.
Deliberately coarse: a step input/output is a live Python object (a DataFrame, raw bytes, a list of FileRef dicts), so this names the shape a workflow author needs to know when wiring one step into the next, not a validatable type. Nothing ever validates a runtime value against it -- host-side contract checking matches input and output names, never types.
any no constraint / plugin-specific
string text scalar
number int or float
boolean true/false
bytes raw binary payload
table tabular data (a pandas DataFrame in-process)
files list of FileRef dicts ({sha256, filename, size})
records list of record dicts
mapping dict keyed by field/column name
list list of anything not covered by files/records
Plugin
Bases: PluginBase, ABC
Out-of-process plugin contract: PluginBase's declarative surface plus the one method that actually does the work.
Subclass this, set the PluginBase class attributes (id, name,
inputs, outputs, Config, ...), and implement invoke(). Pass the
subclass to civex_plugin_sdk.serve() (Tier 1) or serve_container()
(Tier 2) -- nothing else needs to instantiate it.
invoke(inputs, config, ctx)
abstractmethod
Run this plugin for one workflow step.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
inputs
|
dict[str, Any]
|
Step inputs, keyed by name, already converted from the
wire form to invoke-time values (e.g. a declared |
required |
config
|
Any
|
An instance of this plugin's |
required |
ctx
|
Ctx
|
The RPC-backed handle for reading/writing records, files,
schemas, and collections beyond what |
required |
Returns:
| Type | Description |
|---|---|
dict[str, Any]
|
Step outputs, keyed by name, matching this plugin's declared |
dict[str, Any]
|
|
dict[str, Any]
|
automatically -- return a DataFrame or raw bytes directly for a |
dict[str, Any]
|
|
PluginBase
Declarative metadata shared by every plugin tier (BUILTIN, SUBPROCESS, CONTAINER).
Set the class attributes below on a subclass; invoke() itself is
declared separately by each tier (see this package's Plugin for the
out-of-process one).
Config
Bases: BaseModel
A plugin's run-time configuration.
Override with the fields this plugin actually accepts; the model is
rendered to JSON Schema for describe and validated against the
run frame's config dict before invoke() is called.
IOSpec
Bases: BaseModel
One declared input or output of a plugin.
type is a plain str rather than a Literal[IO_TYPES] on purpose:
this model crosses the wire in a describe_result, and a Literal would
make an older host fail discovery entirely on a plugin built against a
newer SDK that added a vocabulary entry. An unrecognized type should
degrade to being displayed as-is, not take the plugin down. In-repo
declarations are held to the vocabulary by test, where a typo is worth
failing on.
Ctx
The handle invoke() receives for everything beyond inputs/config: records, files, schemas, and collections.
Every method blocks on a single rpc_call/rpc_result round trip over
writer/reader -- there is no batching or concurrency, so a plugin
calling several Ctx methods pays one blocking round trip per call.
get_context_record()
Return the record that triggered this workflow step.
Ctx has no ambient .record/.dataset fields the way in-process
WorkflowContext does -- this (and get_context_dataset()) is the
only way an out-of-process plugin learns what triggered it.
get_context_dataset()
Return the dataset that owns get_context_record()'s record.
get_file(sha256)
Return the raw bytes stored under sha256 in the object store.
store_file(data, filename)
Write data to the object store and return its FileRef dict ({sha256, filename, size}).
update_record(record_id, data)
Merge data into the record identified by record_id and return the updated record.
create_record(dataset_name, schema_name, data, context_record_id=None)
Create a record in dataset_name against schema_name and return it.
context_record_id, when omitted, defaults host-side to
get_context_record()'s id -- see WorkflowContext.create_record's
docstring for why it isn't called parent_record_id.
get_record(record_id)
Return the record identified by record_id.
find_records(dataset_name, schema_name=None, parent_record_id=None, filters=None, search=None, limit=50, offset=0)
Return records in dataset_name matching the given filters.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
dataset_name
|
str
|
Dataset to search within. |
required |
schema_name
|
str | None
|
Restrict to records of this schema, if given. |
None
|
parent_record_id
|
str | None
|
Restrict to children of this record, if given. |
None
|
filters
|
list[str] | None
|
Host-parsed filter expressions (field/operator/value), ANDed together. |
None
|
search
|
str | None
|
Free-text search over the dataset's searchable fields. |
None
|
limit
|
int
|
Maximum number of records to return. |
50
|
offset
|
int
|
Number of matching records to skip, for pagination. |
0
|
Returns:
| Type | Description |
|---|---|
list[dict[str, Any]]
|
The matching records, most-recent-first. |
delete_record(record_id)
Delete the record identified by record_id.
get_schema(name)
Return the schema named name, including its resolved fields.
list_schemas()
Return every schema in the project.
get_collection(name)
Return the collection named name.
list_collections()
Return every collection in the project.
commit()
Persist every write this Ctx made so far.
Mirrors AppContext.commit()'s in-process contract: nothing a
plugin writes via update_record/create_record/store_file/the
call_tool mutators is guaranteed durable until this is called (or
the workflow step ends and the executor commits on the plugin's
behalf).
PluginError
Bases: Exception
Base class for every error this SDK raises. Carries the {kind, message, retryable} envelope this module documents above.
Raise this directly (with a custom kind) from invoke() for a failure
that doesn't fit one of the more specific subclasses below.
to_envelope()
Return the {kind, message, retryable} dict this error sends over the wire.
CapabilityDeniedError
Bases: PluginError
Raised host-side when a plugin issues an rpc_call for a method it didn't declare in its describe capabilities list.
ConfigValidationError
Bases: PluginError
Raised when incoming run config fails validation against the plugin's declared Config model.
RpcError
serve_container(plugin_cls)
Container-tier entrypoint: isolates the actual stdout fd, then performs exactly one describe or run (per sys.argv[1]) off real stdin.
Call this (and only this) from a container-tier plugin's main -- see docs/extending/container-plugins.md.
serve(plugin_cls)
Real entrypoint: isolates the actual stdout fd, then serves forever off real stdin.
Call this (and only this) from a plugin's main.