CipherExplain SDK — register models and get encrypted SHAP explanations via the CipherExplain API
Project description
CipherExplain Python SDK
Register your own models and get encrypted SHAP explanations via the CipherExplain API.
Install
pip install cipherexplain
Dependencies installed automatically: httpx, numpy, scikit-learn.
Quick start
from cipherexplain_sdk import CipherExplainClient, extract_spec
client = CipherExplainClient(api_key="vb_...")
# 1. Train locally — nothing leaves your machine
from sklearn.linear_model import LogisticRegression
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
model = LogisticRegression().fit(scaler.fit_transform(X_train), y_train)
# 2. Extract weights only (no pickle, no training data)
spec = extract_spec(model, "my_model", feature_names=["age", "income", "score"],
scaler=scaler)
# 3. Register with the API
client.register(spec)
# 4. Get SHAP explanations — pass raw values, scaler is applied server-side
result = client.explain_raw("my_model", x_raw)
print(result["shap_values"]) # per-feature attributions
print(result["prediction"]) # 0.0–1.0 probability
Supported model types
Only linear classifiers can be registered — weights are serialised to JSON, so the model must be fully described by a coefficient matrix and intercept vector.
| Framework | How |
|---|---|
sklearn LogisticRegression |
extract_spec(model, ...) |
sklearn LinearSVC |
extract_spec(model, ...) |
Any sklearn-compatible object with coef_ / intercept_ |
extract_spec(model, ...) |
PyTorch nn.Linear |
extract_spec(layer, ...) |
PyTorch pure-linear nn.Sequential |
extract_spec(seq, ...) |
TensorFlow / Keras Dense (no activation) |
from_weights(layer.get_weights()[0].T, layer.get_weights()[1], ...) |
| JAX / statsmodels / R / anything else | from_weights(coef, intercept, ...) |
Non-linear models (tree ensembles, MLPs with activations) are not supported — they cannot be serialised to JSON weights safely.
TensorFlow / Keras example
from cipherexplain_sdk import from_weights
# Keras model with a single Dense output layer
import numpy as np
w, b = keras_model.layers[-1].get_weights() # w shape: (n_features, n_classes)
spec = from_weights(
coef=w.T, # transpose to (n_classes, n_features)
intercept=b,
model_id="keras_model",
feature_names=[...],
classes=[0, 1],
)
client.register(spec)
JAX / statsmodels / R example
from cipherexplain_sdk import from_weights
# Pass coefficient array and intercept directly
spec = from_weights(
coef=[[0.42, -0.17, 0.93]], # shape (1, n_features) for binary
intercept=[-0.31],
model_id="my_model",
feature_names=["f1", "f2", "f3"],
classes=[0, 1],
scaler_mean=[0.0, 0.0, 0.0], # optional: embed scaler for /explain_raw
scaler_scale=[1.0, 1.0, 1.0],
)
client.register(spec)
Client reference
client = CipherExplainClient(api_key="vb_...", base_url="https://cipherexplain.vaultbytes.com")
Model management
| Method | Description |
|---|---|
client.register(spec) |
Register a model (spec from extract_spec or from_weights) |
client.list_models() |
List all models available to your key |
client.delete(model_id) |
Delete a registered model and free its slot |
Slot limits: free = 1 model · developer = 10 · enterprise = unlimited
Explanations
| Method | Description |
|---|---|
client.explain(model_id, features) |
SHAP explanation — features must be pre-scaled |
client.explain_raw(model_id, features) |
SHAP explanation — raw values, auto-scaled server-side |
Both return:
{
"prediction": 0.74, # model probability
"base_rate": 0.31, # baseline (training set average)
"shap_values": [...], # per-feature attribution (sum ≈ prediction - base_rate)
"feature_names": [...],
"metadata": {...}
}
Reports & account
| Method | Description |
|---|---|
client.report(benchmark_data) |
Generate PDF audit report — returns raw bytes, save as .pdf |
client.usage() |
Monthly quota: used / remaining for explain and oracle |
client.rotate_key() |
Issue new key, deactivate current. Models migrate automatically. |
client.health() |
API health check — no key required |
client.load_demo_model() |
Load the demo credit model (credit_model) |
Generating a PDF audit report
import json
# Load benchmark results from the FHE Testing Oracle
with open("oracle_benchmark.json") as f:
benchmark = json.load(f)
pdf_bytes = client.report(benchmark)
with open("audit_report.pdf", "wb") as f:
f.write(pdf_bytes)
Requires Developer or Enterprise tier.
Key rotation
result = client.rotate_key()
print(result["new_key"]) # vb_... — save this immediately
print(result["models_migrated"]) # all your models move automatically
# Your old key is now inactive — create a new client
client = CipherExplainClient(api_key=result["new_key"])
Error handling
All methods raise httpx.HTTPStatusError on API errors. Check exc.response.status_code:
import httpx
try:
client.register(spec)
except httpx.HTTPStatusError as exc:
if exc.response.status_code == 401:
print("Missing X-API-Key")
elif exc.response.status_code == 403:
print("Invalid key or tier restriction (e.g. PDF reports need Developer+)")
elif exc.response.status_code == 404:
print("Model not found")
elif exc.response.status_code == 409:
print("Model ID already registered — delete it first or use a different ID")
elif exc.response.status_code == 422:
print("Validation error:", exc.response.json()["detail"])
elif exc.response.status_code == 429:
print("Quota exceeded — model slot limit or monthly call limit reached")
else:
raise
Tier limits
| Free | Developer | Enterprise | |
|---|---|---|---|
| SHAP API calls / month | 50 | 5,000 | 50,000 |
| Oracle runs / month | 3 | 500 | 5,000 |
| Model slots | 1 | 10 | Unlimited |
| PDF audit reports | — | Yes | Yes |
Get an API key
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 cipherexplain-0.1.0.tar.gz.
File metadata
- Download URL: cipherexplain-0.1.0.tar.gz
- Upload date:
- Size: 26.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 |
b5f6f37f2c09a7d0425f6ffac2383d2b93c09b75614fccda30e58cc373bb7f6b
|
|
| MD5 |
49451837c53160ddc7a1ca9c4e68ecc2
|
|
| BLAKE2b-256 |
ca0fe519e71612be31341f07a7081993cc0c618972fe1c45e47e891144b03603
|
Provenance
The following attestation bundles were made for cipherexplain-0.1.0.tar.gz:
Publisher:
workflow.yml on VaultBytes/CipherExplain
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
cipherexplain-0.1.0.tar.gz -
Subject digest:
b5f6f37f2c09a7d0425f6ffac2383d2b93c09b75614fccda30e58cc373bb7f6b - Sigstore transparency entry: 1294808918
- Sigstore integration time:
-
Permalink:
VaultBytes/CipherExplain@dd6de0e94c71f25114be436d613cd4fcb5fbff85 -
Branch / Tag:
refs/tags/sdk-v0.1.0 - Owner: https://github.com/VaultBytes
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
workflow.yml@dd6de0e94c71f25114be436d613cd4fcb5fbff85 -
Trigger Event:
push
-
Statement type:
File details
Details for the file cipherexplain-0.1.0-py3-none-any.whl.
File metadata
- Download URL: cipherexplain-0.1.0-py3-none-any.whl
- Upload date:
- Size: 28.5 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 |
f7eda9b1cd1ad878521cd45e3a64e089326551f6867b62d3259b0d6be0b48151
|
|
| MD5 |
f4391d1e321a3b73157529530a7a12fb
|
|
| BLAKE2b-256 |
ea0435384615d7e2ed202e455f22edd2c84d086f6718231a700826c1a700ddca
|
Provenance
The following attestation bundles were made for cipherexplain-0.1.0-py3-none-any.whl:
Publisher:
workflow.yml on VaultBytes/CipherExplain
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
cipherexplain-0.1.0-py3-none-any.whl -
Subject digest:
f7eda9b1cd1ad878521cd45e3a64e089326551f6867b62d3259b0d6be0b48151 - Sigstore transparency entry: 1294808989
- Sigstore integration time:
-
Permalink:
VaultBytes/CipherExplain@dd6de0e94c71f25114be436d613cd4fcb5fbff85 -
Branch / Tag:
refs/tags/sdk-v0.1.0 - Owner: https://github.com/VaultBytes
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
workflow.yml@dd6de0e94c71f25114be436d613cd4fcb5fbff85 -
Trigger Event:
push
-
Statement type: