SDK for writing alembic external adapters in Python
Project description
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 complete,
copyable starting point.
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 |
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:
OpisCreate,Update, orDelete(dispatch withisinstance).CreateandUpdatecarry the full desiredObject;Updatealso carrieschangesandbackend_id;Deletecarrieskeyandbackend_id.Objecthasuid,type_name,key, andattrs.State.backend_id(type_name, uid)looks up the engine's existing backend id for an object, so renames stay stable.Schemaparses intoTypeSchema/FieldSchema/FieldType, so schema-driven adapters can, for example, find reference fields viafield.type.kind == "ref"andfield.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
license
Apache-2.0
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file alembic_adapter_sdk-0.1.0.tar.gz.
File metadata
- Download URL: alembic_adapter_sdk-0.1.0.tar.gz
- Upload date:
- Size: 15.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d5df0d037303a2a2b3b75f545d4841773b07f6f8c47dc0376fae618fb20f10e4
|
|
| MD5 |
e76516ee96892af3e007102d37600aa3
|
|
| BLAKE2b-256 |
47d6eb3b8518d289120f18b4832256dc2a36adc04cf76040e70d8c0fcafbc60d
|
Provenance
The following attestation bundles were made for alembic_adapter_sdk-0.1.0.tar.gz:
Publisher:
publish.yml on cyberwitchery/alembic-adapter-sdk-python
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
alembic_adapter_sdk-0.1.0.tar.gz -
Subject digest:
d5df0d037303a2a2b3b75f545d4841773b07f6f8c47dc0376fae618fb20f10e4 - Sigstore transparency entry: 1980447465
- Sigstore integration time:
-
Permalink:
cyberwitchery/alembic-adapter-sdk-python@ec0db4e168e1a697da508b6cd6b23c956faca943 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/cyberwitchery
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@ec0db4e168e1a697da508b6cd6b23c956faca943 -
Trigger Event:
push
-
Statement type:
File details
Details for the file alembic_adapter_sdk-0.1.0-py3-none-any.whl.
File metadata
- Download URL: alembic_adapter_sdk-0.1.0-py3-none-any.whl
- Upload date:
- Size: 13.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9c60da71b6e09dc67a678fe97f8afc4cf1d673a01f021dfa1affb82579482a57
|
|
| MD5 |
6fc1f41374bc01b6b9a618e70c238427
|
|
| BLAKE2b-256 |
e7e161d5e546f43e45fc8f4081ff77c2970c4a19df0012bd614fc55b33dd7e5c
|
Provenance
The following attestation bundles were made for alembic_adapter_sdk-0.1.0-py3-none-any.whl:
Publisher:
publish.yml on cyberwitchery/alembic-adapter-sdk-python
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
alembic_adapter_sdk-0.1.0-py3-none-any.whl -
Subject digest:
9c60da71b6e09dc67a678fe97f8afc4cf1d673a01f021dfa1affb82579482a57 - Sigstore transparency entry: 1980447598
- Sigstore integration time:
-
Permalink:
cyberwitchery/alembic-adapter-sdk-python@ec0db4e168e1a697da508b6cd6b23c956faca943 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/cyberwitchery
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@ec0db4e168e1a697da508b6cd6b23c956faca943 -
Trigger Event:
push
-
Statement type: