xgboost-bridge
Export trained XGBoost models as portable JSON artifacts, with a reference
predictor for validating them. Companion to
xgboost-predictor on
npm, which runs inference on those artifacts with zero dependencies in
browser and edge runtimes.
Why this exists: the standard way to take an XGBoost model out of Python — converting it to ONNX and running it elsewhere — fails silently. Conversion succeeds, inference runs, and the predictions are wrong, with no exception and no warning. This library exists so that a model it can't handle raises an error instead of returning a plausible wrong number.
Full documentation, the artifact format specification, and the rationale behind every design decision live in the source repository:
FORMAT.md— the artifact format.COMPAT.md— compatibility and support policy.docs/DECISIONS.md— engineering decisions and their evidence.
1.0 scope
Binary classification, regression, and Cox survival objectives —
binary:logistic, reg:squarederror, survival:cox — with the gbtree
booster only. dart and gblinear raise a specific error at export rather
than being approximated. Multi-class objectives are out of scope for this
release and also raise on export.
Install
# Read exported artifacts and run the reference predictor. Requires only numpy.
pip install xgboost-bridge
# Also export models. Requires Python >=3.12: XGBoost 3.3.0 itself does.
pip install "xgboost-bridge[export]"
The base package's floor is Python >=3.10 — reading an artifact and
predicting from it needs nothing but numpy. The export extra pins
xgboost==3.3.0, which requires >=3.12, so installing the base package on
3.10 or 3.11 works fine but installing the export extra there will fail to
resolve. That is XGBoost's floor, not a packaging bug.
The pin is exact rather than a range, and deliberately so. This library refuses to export a model produced by an XGBoost version it has not verified against, because version drift here is silent — XGBoost 3.4.0-dev relocated a field, and 3.3.0 reads such a model returning wrong predictions with no warning and exit code 0. A permissive range would resolve a version the exporter then refuses, so the dependency and the verified list are kept identical. Widening either requires re-probing.
Export a model
import numpy as np
import xgboost as xgb
from xgboost_bridge import export_model, to_json
feature_names = ["feature_0", "feature_1", "feature_2"]
rng = np.random.default_rng(0)
X = rng.uniform(-2.0, 2.0, size=(200, 3))
y = (X[:, 0] + 0.5 * X[:, 1] - X[:, 2] > 0.0).astype(np.float64)
dtrain = xgb.DMatrix(X, label=y, feature_names=feature_names, nthread=1)
booster = xgb.train(
{"objective": "binary:logistic", "max_depth": 3, "eta": 0.3, "nthread": 1, "seed": 0},
dtrain,
num_boost_round=10,
)
# feature_names is required whenever the model was fit from a bare array —
# a model with no feature names cannot be exported.
artifact = export_model(booster, feature_names=feature_names)
document = to_json(artifact) # a deterministic JSON string
The reference predictor reads the same artifact back, useful for confirming it before it ever reaches JavaScript:
import json
from xgboost_bridge import Predictor
predictor = Predictor.from_json(json.loads(document))
row = {"feature_0": 0.70, "feature_1": -0.20, "feature_2": 1.00}
predictor.margin(row) # np.float32(-0.44306272)
predictor.output(row) # np.float32(0.39101142)
Strict feature keys
Prediction input must match the model's feature names exactly — no missing
key, no extra key. A mismatch raises FeatureKeyMismatchError rather than
being tolerated.
What this costs you: if your input records come from a source that doesn't guarantee an exact key match — a database row with extra columns, a form with optional fields, a renamed column upstream — you have to normalize that shape yourself before calling the predictor. This library will not silently drop extra keys, and it will not silently treat a missing key as a "missing value" on your behalf. That normalization work is real, and it is deliberately pushed onto the caller.
Why it's still the right call: under lenient handling, a misspelled or
renamed feature name doesn't fail — it quietly becomes a missing-value
input, and XGBoost's missing-value branches are legitimate model structure.
The result is a confident, plausible, wrong prediction, compounding across
every tree in the ensemble. Strict keys turn that into an error at the call
site instead, which is why this library exists in the first place. Full
rationale, with the specific decisions and measurements behind it, is in
COMPAT.md.
What is refused
An unsupported objective or booster raising loudly is a documented feature
of this library. dart and gblinear raise at export; categorical splits
raise; an artifact from an XGBoost version this library hasn't verified
against raises; multi-output shapes arriving through an otherwise-permitted
objective name (for example reg:squarederror with num_target=2) raise on
arity. See
COMPAT.md
for the complete, current list and the evidence behind each refusal.
Error messages quote your artifact back
Every exception is an XGBoostBridgeError subclass, and most carry structured attributes describing what was wrong — MalformedTreeError has field, value, expected and location; NonFiniteFeatureError has index and value; FeatureKeyMismatchError has missing_keys and extra_keys. Which attributes exist depends on the exception, so catch the specific class rather than assuming a field is present. The message embeds the offending value verbatim so the failure is legible. If your artifact or prediction input can be influenced by someone else, do not pass the message straight into an HTTP response body or an HTML template: escape it, or branch on the structured attributes and compose your own. Ordinary library behaviour, noted because the attributes exist precisely so you never have to display the string.
AI Disclosure: Claude Code was used to help implement this project.
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 xgboost_bridge-1.0.0.tar.gz.
File metadata
- Download URL: xgboost_bridge-1.0.0.tar.gz
- Upload date:
- Size: 59.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
41fa305a2ecb318f8833b234ec9de2f86d3f423676993a5e217460940d66c0e0
|
|
| MD5 |
fc4a67e4aac0351283396734d25b979f
|
|
| BLAKE2b-256 |
94a73e2efb2f4e1121436ec3dea86fe6afee5221fd5519b0a719c5a3bb0d3148
|
Provenance
The following attestation bundles were made for xgboost_bridge-1.0.0.tar.gz:
Publisher:
release.yml on anirudhmazumder/xgboost-bridge
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
xgboost_bridge-1.0.0.tar.gz -
Subject digest:
41fa305a2ecb318f8833b234ec9de2f86d3f423676993a5e217460940d66c0e0 - Sigstore transparency entry: 2371153572
- Sigstore integration time:
-
Permalink:
anirudhmazumder/xgboost-bridge@b468cd6535ada259f3c2ecff6dcb1642037ddad5 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/anirudhmazumder
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@b468cd6535ada259f3c2ecff6dcb1642037ddad5 -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file xgboost_bridge-1.0.0-py3-none-any.whl.
File metadata
- Download URL: xgboost_bridge-1.0.0-py3-none-any.whl
- Upload date:
- Size: 66.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
df604b78352f989f021de7df39c978c61a9c77ff7f7210549cdebec170e3c7b0
|
|
| MD5 |
437d63accddc19cb9b1b449a97c042cb
|
|
| BLAKE2b-256 |
7ee6670a30064537a3b59c5f960cb470556a713206b05f2fe955d06c0605857e
|
Provenance
The following attestation bundles were made for xgboost_bridge-1.0.0-py3-none-any.whl:
Publisher:
release.yml on anirudhmazumder/xgboost-bridge
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
xgboost_bridge-1.0.0-py3-none-any.whl -
Subject digest:
df604b78352f989f021de7df39c978c61a9c77ff7f7210549cdebec170e3c7b0 - Sigstore transparency entry: 2371153596
- Sigstore integration time:
-
Permalink:
anirudhmazumder/xgboost-bridge@b468cd6535ada259f3c2ecff6dcb1642037ddad5 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/anirudhmazumder
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@b468cd6535ada259f3c2ecff6dcb1642037ddad5 -
Trigger Event:
workflow_dispatch
-
Statement type: