Python API Reference
bootstrap(), open_model(), the automatic compiled-tier gate, and the exceptions your code may need to handle.
The runtime API you write against is two top-level functions — everything else (activation, licensing, the gate itself) happens behind them. There is no decorator to import or apply: magiclock build inserts the license-gate check into every compiled module for you (see Compiled Build).
magiclock.bootstrap()
magiclock.bootstrap(vault_dir=None, *, app_version="1.0.0") -> MagicLockRuntimeBrings the license gate up against this machine's activation, for the current process. In a magiclock build output this call is inserted automatically at the entry module — you only need to call it yourself in a plain (non-compiled) script, before your first open_model() call.
vault_dir— override where the local activation state lives. You won't normally need this.app_version— checked against anymax_app_versionyour license sets; matters if you version-lock releases.- Returns the runtime object (rarely needed directly — most code just calls
bootstrap()for its side effect). - Raises if this machine hasn't been activated yet, or if activation is present but invalid for this machine (see Errors below).
magiclock.open_model()
magiclock.open_model(path, *, vault_dir=None, passphrase=None, key=None) -> bytesDecrypts a .enc envelope produced by protect-model and returns the plaintext bytes — in memory only, never written to disk.
path— path to the.encfile.passphrase/key— for a two-factor (--lock-passphrase) or portable (--no-bind-machine) artifact; omit for a plain machine-locked one.- Requires
bootstrap()to have run first for machine-locked artifacts.
import magiclock
magiclock.bootstrap()
weights = magiclock.open_model("model.onnx.enc")The compiled-tier gate
There's no function or decorator to call — magiclock build walks your source tree and inserts one gate check (the python_protect capability) into every module, before compiling:
# your source, unchanged by you:
def export_report(data: str) -> bytes:
...
# what `magiclock build` compiles, conceptually:
current_runtime().require_feature("python_protect")
def export_report(data: str) -> bytes:
...The check runs once per module, the first time it's imported in a process — not once per call. Because it's woven into every compiled module rather than living behind one shared, deletable decorator, an attacker has to find and patch each module individually. A non-entry module's failure propagates as a normal exception (it may be imported as a library); the entry module's failure prints a clean message and exits, since nothing else can run without it.
Errors you may need to handle
bootstrap() and open_model() raise on anything from "not activated yet" to "this artifact expired." Most integrations catch broadly and branch on the exception's class name:
try:
magiclock.bootstrap()
data = magiclock.open_model("model.onnx.enc")
except Exception as exc:
name = type(exc).__name__
if name == "NotActivatedError":
... # this machine hasn't been activated — run `magiclock activate`
elif name == "TrialExpiredError":
... # the artifact's expiry window has passed
else:
raise| Exception | Raised when |
|---|---|
NotActivatedError | No activation found on this machine — run magiclock activate (or let the CLI auto-activate on first encrypt). |
VaultLockedError | The local activation state can't be opened here — wrong machine, or the vault file was moved/tampered with. These two cases are indistinguishable by design; see Security Model. |
TrialExpiredError | A --trial, --expires-in, or --expires-at artifact is past its decryption window. |
SubscriptionExpiredError | Your plan has lapsed. This only blocks new encryption — it's never raised on the decrypt path. |
SubscriptionInvalidError | The subscription credential is missing where required, malformed, or fails signature verification. |
PortableFormatError | A portable (--no-bind-machine) envelope is malformed or from an unsupported version. |
PortableKeyError | The passphrase or key passed to open_model()/run --key doesn't match a portable artifact. |
DebuggerDetectedError | A debugger was attached at a decrypt boundary. |
RuntimeNotInitializedError (from magiclock_host.errors import RuntimeNotInitializedError) | A gated module's check ran before bootstrap() ran in this process. |
Compatibility note
.pya/.enc envelopes embed the CPython major/minor version that produced them. An artifact encrypted under 3.12 won't load under 3.13 — re-run protect/protect-model after upgrading your interpreter, rather than shipping one artifact across Python versions.