Skip to main content

alembic-adapter-sdk (python)

a small, dependency-free sdk for writing alembic external adapters in python.

network engineering lives in python, so adapters should be writable there too. alembic delegates backend i/o to external adapters: standalone programs the alembic host spawns as subprocesses, exchanging one json request and one json response over stdin/stdout. this sdk handles that protocol so you only write the backend logic.

the import package is alembic_adapter. (the pypi distribution is alembic-adapter-sdk; the bare name alembic belongs to sqlalchemy's migration tool and is unrelated.)

install

pip install alembic-adapter-sdk

or, from a checkout:

pip install -e .

the sdk has no runtime dependencies; it speaks json with the stdlib.

writing an adapter

subclass Adapter, implement the methods your backend needs, and call run:

from alembic_adapter import Adapter, ApplyReport, AppliedOp, Create, run


class MyAdapter(Adapter):
    def setup(self, config):
        # `config` is the parsed `setup:` block from the backend config.
        self.host = (config or {}).get("host", "http://localhost:8080")

    def read(self, schema, types, state):
        # observe backend state -> list[ExternalObject]; the engine diffs it
        # against the desired inventory to build a plan. emit-only adapters
        # return [] (the default).
        return []

    def write(self, schema, ops, state):
        # apply create/update/delete ops, then report what was applied.
        report = ApplyReport()
        for op in ops:
            if isinstance(op, Create):
                ...  # create op.desired on the backend
            report.applied.append(AppliedOp(uid=op.uid, type_name=op.type_name))
        return report


if __name__ == "__main__":
    run(MyAdapter())

run reads one request from stdin, dispatches it, and writes a newline-terminated json response to stdout. any exception your adapter raises is turned into a well-formed {"ok": false, "error": ...} response.

see examples/example_adapter.py for a copyable starting point, and examples/json_store_adapter.py for a finished adapter: it keeps objects in a json file, implements every method of the contract, and converges under alembic plan/apply.

the protocol

every request carries version (currently 1) and a method. the sdk parses the payload into typed objects and serializes your results back:

method you receive you return
read schema, types, state list[ExternalObject]
write schema, ops, state ApplyReport
ensure_schema schema ProvisionReport
preview_schema schema ProvisionReport or None
capabilities nothing Capabilities

preview_schema is called at plan time to show what ensure_schema would provision without writing; return None (the default) if your adapter cannot preview.

capabilities reports the adapter's role: adapter (read+write, the default), emitter (write-only), or observer (read-only), so the host can reject import/apply up front instead of calling into a side that does nothing.

setup is the setup: block from the backend config (parsed json, usually a dict); Adapter.setup is called once before each request.

the model mirrors alembic's ir:

  • Op is Create, Update, or Delete (dispatch with isinstance). Create and Update carry the full desired Object; Update also carries changes and backend_id; Delete carries key and backend_id.
  • Object has uid, type_name, key, and attrs.
  • State.backend_id(type_name, uid) looks up the engine's existing backend id for an object, so renames stay stable.
  • Schema parses into TypeSchema / FieldSchema / FieldType, so schema-driven adapters can, for example, find reference fields via field.type.kind == "ref" and field.type.target.

for the full request/response shapes, see alembic's docs/external-adapters.md.

wiring into alembic

point a backend config at your program (see examples/backend.yaml):

backend: external
command: python3
args: ["examples/example_adapter.py"]
setup:
  host: http://localhost:8080
alembic plan  --backend external --backend-config examples/backend.yaml \
  -f inventory.yaml -o plan.json
alembic apply --backend external --backend-config examples/backend.yaml \
  -p plan.json

you can also debug the protocol by hand by piping a request into your adapter:

echo '{"version":1,"setup":{},"method":"read","schema":{"types":{}},"types":[],"state":{"mappings":{}}}' \
  | python3 examples/example_adapter.py

develop

pip install -e ".[dev]"

# tests
PYTHONPATH=src python -m unittest discover -s tests

# tests with the coverage gate (fails under 100%, matching ci)
coverage run -m unittest discover -s tests
coverage report

ruff check
ruff format --check

the unit tests assert json shapes on their own, so ci also checks the sdk against the real host, pinned to one alembic release:

# protocol conformance, with the runner that ships alongside alembic
alembic-adapter-test -- python examples/example_adapter.py

# a full converge cycle driven by the alembic cli (create, re-plan, update, delete)
bash tests/e2e-alembic.sh

both need binaries from an alembic release on your PATH; the e2e skips itself when alembic is missing.

license

Apache-2.0

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

alembic_adapter_sdk-0.3.1.tar.gz (24.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

alembic_adapter_sdk-0.3.1-py3-none-any.whl (14.7 kB view details)

Uploaded Python 3

File details

Details for the file alembic_adapter_sdk-0.3.1.tar.gz.

File metadata

  • Download URL: alembic_adapter_sdk-0.3.1.tar.gz
  • Upload date:
  • Size: 24.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for alembic_adapter_sdk-0.3.1.tar.gz
Algorithm Hash digest
SHA256 b4ae70e1a001282f2003435aa3cde8c6b075e2cb4d1df63480dd4f439adffe93
MD5 737c05273b7e8f7757145e7c5ec3c506
BLAKE2b-256 eeb17607e134c8be482e7a235de68d5a1531bd5ec9aeea367dbd6e1bc3146cb0

See more details on using hashes here.

Provenance

The following attestation bundles were made for alembic_adapter_sdk-0.3.1.tar.gz:

Publisher: publish.yml on cyberwitchery/alembic-adapter-sdk-python

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file alembic_adapter_sdk-0.3.1-py3-none-any.whl.

File metadata

File hashes

Hashes for alembic_adapter_sdk-0.3.1-py3-none-any.whl
Algorithm Hash digest
SHA256 2d06e5c3cb6bcbfa4535e243a4fd1db5b7f8977056e1f4ff151f5eb0e40b4ba5
MD5 087cd7280c3897b57bc3aa65a79ad8d1
BLAKE2b-256 0f1c62667030ecaa16c715c862fd734ac92e5c7903bf5b36f98dd699b7865afd

See more details on using hashes here.

Provenance

The following attestation bundles were made for alembic_adapter_sdk-0.3.1-py3-none-any.whl:

Publisher: publish.yml on cyberwitchery/alembic-adapter-sdk-python

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

This release

0.3.1 This release

2 files

0.3.0

2 files

0.2.0

2 files

0.1.0

2 files

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page