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()

python
magiclock.bootstrap(vault_dir=None, *, app_version="1.0.0") -> MagicLockRuntime

Brings 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 any max_app_version your 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()

python
magiclock.open_model(path, *, vault_dir=None, passphrase=None, key=None) -> bytes

Decrypts a .enc envelope produced by protect-model and returns the plaintext bytes — in memory only, never written to disk.

  • path — path to the .enc file.
  • 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.
python
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:

python
# 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:

python
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
ExceptionRaised when
NotActivatedErrorNo activation found on this machine — run magiclock activate (or let the CLI auto-activate on first encrypt).
VaultLockedErrorThe 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.
TrialExpiredErrorA --trial, --expires-in, or --expires-at artifact is past its decryption window.
SubscriptionExpiredErrorYour plan has lapsed. This only blocks new encryption — it's never raised on the decrypt path.
SubscriptionInvalidErrorThe subscription credential is missing where required, malformed, or fails signature verification.
PortableFormatErrorA portable (--no-bind-machine) envelope is malformed or from an unsupported version.
PortableKeyErrorThe passphrase or key passed to open_model()/run --key doesn't match a portable artifact.
DebuggerDetectedErrorA 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.