Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
7c9deaa
add xgboost installation mode
AHReccese Oct 18, 2026
590c82e
add xgboost requirement
AHReccese Oct 18, 2026
3f7527f
add xgboost requirement to `meta.yaml`
AHReccese Oct 18, 2026
66a86dd
add xgboost support + fix CLI bug (remove model input from constructor)
AHReccese Oct 18, 2026
0bd0153
Add support for XGBoost in PyMilo (categories, messages)
AHReccese Oct 18, 2026
4ee0e1a
add support for XGBoost models in backward compatible manner
AHReccese Oct 18, 2026
8f14334
update docstring for the removed `model` input
AHReccese Oct 18, 2026
ce9e02a
Add conditional support for XGBoost models in the transporter.
AHReccese Oct 18, 2026
a3bb2fd
Add unit tests for XGBoost survival regression
AHReccese Oct 18, 2026
e0ed01d
Add unit tests for XGBRanker with various ranking objectives
AHReccese Oct 18, 2026
77d5315
Add unit tests for XGBRFClassifier in the XGBoost module
AHReccese Oct 18, 2026
d1aa8fc
Add unit tests for XGBClassifier with binary objectives in the XGBoos…
AHReccese Oct 18, 2026
83ef554
Add unit tests for XGBRegressor in the XGBoost module, including pipe…
AHReccese Oct 18, 2026
884b145
Add unit tests for XGBClassifier with multiclass objectives in the XG…
AHReccese Oct 18, 2026
77d350a
Add unit tests for XGBRegressor with various regression objectives in…
AHReccese Oct 18, 2026
0235303
Add unit tests for XGBRFRegressor in the XGBoost module
AHReccese Oct 18, 2026
b40da4c
Add unit tests for native booster in the XGBoost module, covering reg…
AHReccese Oct 18, 2026
e45cae6
Add unit tests for XGBRegressor in ML streaming scenario, validating …
AHReccese Oct 18, 2026
8ba010a
fix the bug in `--init` in dockerfile
AHReccese Oct 18, 2026
b066d13
add xgboost chain
AHReccese Oct 18, 2026
29bd2b2
refactor harcoded strings in pymilo client constructor
AHReccese Oct 18, 2026
6026268
Add support for XGBoost model classes and enhance model class retriev…
AHReccese Oct 18, 2026
cd15efb
Add BoosterTransporter class to handle serialization and deserializat…
AHReccese Oct 18, 2026
cf8de1d
Add test util for xgboost.Booster round-trip validation, comparing pr…
AHReccese Oct 18, 2026
702eca6
add xgboost models to `SUPPORTED_MODELS.md`
AHReccese Oct 18, 2026
d918076
Add MANIFEST.in to include necessary files for sdist packaging
AHReccese Oct 18, 2026
03f3656
Enhance BSpline handling in PreprocessingTransporter to support both …
AHReccese Oct 18, 2026
f2c737c
add xgboost models tests runner
AHReccese Oct 18, 2026
2dfa405
Refactor model handling in `pymilo_obj.py` to use generic ML model fu…
AHReccese Oct 18, 2026
dfc1874
Add support for XGBoost models in `pymilo_func.py` + refactor existin…
AHReccese Oct 18, 2026
05c8237
drop hardcoded id + refactor scenario3 to reuse.
AHReccese Oct 18, 2026
76df0de
fix error in docstring
AHReccese Oct 18, 2026
0b53ff9
add xgboost mode to cover full install in CI
AHReccese Oct 18, 2026
1fd8a76
Add CLI server preparation fixture and related tests in `test_streami…
AHReccese Oct 18, 2026
52c1963
Update .gitignore to include coverage files and IDE configurations
AHReccese Oct 18, 2026
044a1eb
minimal update on `README` (temporary)
AHReccese Nov 3, 2026
97c9d90
`CHANGELOG.md` updated
AHReccese Nov 3, 2026
ba430ea
Add OpenMP runtime installation step for XGBoost on macOS in CI workflow
AHReccese Nov 3, 2026
64a6a4f
fix codacy flags
AHReccese Nov 3, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,13 @@ jobs:
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python-version }}
- name: Install OpenMP runtime for XGBoost (macOS)
if: runner.os == 'macOS'
run: brew install libomp
- name: Installation
run: |
python -m pip install --upgrade pip
pip install .["streaming"]
pip install ".[streaming,xgboost]"
- name: Test requirements Installation
run: |
python otherfiles/requirements-splitter.py
Expand Down
8 changes: 8 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,13 @@ htmlcov/
.cache
nosetests.xml
coverage.xml
coverage_*.xml
*,cover
.hypothesis/

# Generated by otherfiles/requirements-splitter.py from dev-requirements.txt (CI only)
test-requirements.txt

# Translations
*.mo
*.pot
Expand Down Expand Up @@ -82,9 +86,13 @@ celerybeat-schedule

# virtualenv
.venv/
.venv*/
venv/
ENV/

# Editor / IDE
.vscode/

# Spyder project settings
.spyderproject

Expand Down
31 changes: 31 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,42 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
## [Unreleased]
### Added
- `.codacy.yaml`
- `XGBoostChain` class in `pymilo/chains/xgboost_chain.py`
- `BoosterTransporter` class in `pymilo/transporters/booster_transporter.py`
- `XGBOOST_SUPPORTED_TABLE`, `XGBOOST_SUPPORTED_CATEGORIES` and `CLI_XGBOOST_NOT_INSTALLED` in `pymilo/pymilo_param.py`
- `get_xgboost_class` and `get_ml_model_class` functions in `pymilo/utils/util.py`
- `get_xgboost_version` and `get_framework_versions` functions in `pymilo/pymilo_func.py`
- `get_ml_model_data` function in `pymilo/pymilo_func.py`
- `to_ml_model` function in `pymilo/pymilo_func.py`
- `pymilo_xgb_booster_test` function in `pymilo/utils/test_pymilo.py`
- `xgboost-requirements.txt`
- XGBoost models test runner
- `scenario5` XGBoost test for streaming
- `PYMILO_CLIENT_DEFAULT_CLIENT_ID` and `PYMILO_CLIENT_DEFAULT_ML_MODEL_ID` in `pymilo/streaming/param.py`
- `MANIFEST.in`
### Changed
- `get_requires` function in `setup.py`
- `meta.yaml`
- `dev-requirements.txt`
- `requirements.txt`
- `Export` class in `pymilo/pymilo_obj.py`
- `Import` class in `pymilo/pymilo_obj.py`
- `print_supported_ml_models` function in `pymilo/pymilo_func.py`
- `pymilo/__main__.py`
- `.github/workflows/test.yml`
- `scenario3` in `tests/test_ml_streaming/scenarios/scenario3.py`
- `serialize_spline` function in `PreprocessingTransporter`
- `deserialize_spline` function in `PreprocessingTransporter`
- `SUPPORTED_MODELS.md` updated
- `README.md` updated
### Fixed
- PyMilo CLI server launch
- `generate_dockerfile` `--init` CMD
- Source distribution packaging
- `Export.save` directory creation
### Removed
- `get_sklearn_data` function in `pymilo/pymilo_func.py`
- `to_sklearn_model` function in `pymilo/pymilo_func.py`
## [1.6] - 2026-04-03
### Added
- `_check_response_error` function in `WebSocketClientCommunicator`
Expand Down
5 changes: 5 additions & 0 deletions MANIFEST.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# setup.py reads these at build time, so they must ship inside the sdist.
include requirements.txt
include streaming-requirements.txt
include xgboost-requirements.txt
include CHANGELOG.md
40 changes: 22 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,27 @@ The `Import` class facilitates importing of serialized models from JSON files, J

This loaded model is exactly the same as the original trained model.

### XGBoost
PyMilo transparently exports and imports XGBoost models, just like scikit-learn ones.

⚠️ In order to use XGBoost support, make sure you've installed the `xgboost` mode of PyMilo:

```console
pip install pymilo[xgboost]
```

Both the scikit-learn-style wrappers (`XGBRegressor`, `XGBClassifier`, `XGBRanker`, `XGBRFRegressor`, `XGBRFClassifier`) and the native `xgboost.Booster` are supported.

```python
from xgboost import XGBRegressor
from pymilo import Export, Import

model = XGBRegressor(n_estimators=20).fit(X_train, y_train)
Export(model).save("xgb.json")

restored = Import("xgb.json").to_model()
```

### ML streaming
You can easily serve your ML model from a remote server using `ML streaming` feature of PyMilo.

Expand Down Expand Up @@ -314,24 +335,7 @@ result = pymilo_client.predict(x_test)


## Supported ML models
| scikit-learn | PyTorch |
| ---------------- | ---------------- |
| Linear Models ✅ | - |
| Neural Networks ✅ | - |
| Trees ✅ | - |
| Clustering ✅ | - |
| Naïve Bayes ✅ | - |
| Support Vector Machines (SVMs) ✅ | - |
| Nearest Neighbors ✅ | - |
| Ensemble Models ✅ | - |
| Pipeline Model ✅ | - |
| Preprocessing Models ✅ | - |
| Cross Decomposition Models ✅ | - |
| Feature Extractor Models ✅ | - |
| Composite Models ✅ | - |


Details are available in [Supported Models](https://github.com/openscilab/pymilo/blob/main/SUPPORTED_MODELS.md).
See [Supported Models](https://github.com/openscilab/pymilo/blob/main/SUPPORTED_MODELS.md).

## Issues & bug reports

Expand Down
46 changes: 45 additions & 1 deletion SUPPORTED_MODELS.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Supported Models

**Last Update: 2025-12-30**
**Last Update: 2026-09-07**


<h2 id="scikit-learn">Scikit-Learn</h2>
Expand Down Expand Up @@ -798,3 +798,47 @@
<td>>=1.5</td>
</tr>
</table>

<h2 id="xgboost">XGBoost</h2>

Available when PyMilo is installed with the optional `xgboost` extra (`pip install pymilo[xgboost]`).

📚 <a href="https://xgboost.readthedocs.io/" target="_blank"><b>XGBoost Documentation</b></a>

<table>
<tr align="center">
<th>ID</th>
<th>Model Name</th>
<th>PyMilo Version</th>
</tr>
<tr align="center">
<td>1</td>
<td><b>XGBRegressor</b></td>
<td>>=1.7</td>
</tr>
<tr align="center">
<td>2</td>
<td><b>XGBClassifier</b></td>
<td>>=1.7</td>
</tr>
<tr align="center">
<td>3</td>
<td><b>XGBRanker</b></td>
<td>>=1.7</td>
</tr>
<tr align="center">
<td>4</td>
<td><b>XGBRFRegressor</b></td>
<td>>=1.7</td>
</tr>
<tr align="center">
<td>5</td>
<td><b>XGBRFClassifier</b></td>
<td>>=1.7</td>
</tr>
<tr align="center">
<td>6</td>
<td><b>Booster (native)</b></td>
<td>>=1.7</td>
</tr>
</table>
1 change: 1 addition & 0 deletions dev-requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ requests==2.33.0; python_full_version >= "3.10"
requests>=2.0.0; python_full_version < "3.10"
websockets==15.0.1
pydantic==2.13.2
xgboost==3.4.1
setuptools>=40.8.0
vulture>=1.0
bandit>=1.5.1
Expand Down
1 change: 1 addition & 0 deletions otherfiles/meta.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ requirements:
- fastapi>=0.68.0
- pydantic>=1.5.0
- websockets>=9.0
- xgboost>=1.7.0

about:
home: https://github.com/openscilab/pymilo
Expand Down
22 changes: 16 additions & 6 deletions pymilo/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,17 @@
CLI_MORE_INFO,
CLI_UNKNOWN_MODEL,
CLI_ML_STREAMING_NOT_INSTALLED,
CLI_XGBOOST_NOT_INSTALLED,
XGBOOST_SUPPORTED_TABLE,
)
from .pymilo_func import print_supported_ml_models, pymilo_help
from .pymilo_obj import Import
from .utils.util import get_sklearn_class
from .utils.util import get_ml_model_class

ml_streaming_support = True
try:
from .streaming import PymiloServer, Compression, CommunicationProtocol
from .streaming.param import PYMILO_CLIENT_DEFAULT_CLIENT_ID, PYMILO_CLIENT_DEFAULT_ML_MODEL_ID
except BaseException:
ml_streaming_support = False

Expand Down Expand Up @@ -95,9 +98,12 @@ def main():
_model = _model.to_model()
elif args.init:
model_name = args.init
model_class = get_sklearn_class(model_name)
model_class = get_ml_model_class(model_name)
if model_class is None:
print(f"{CLI_UNKNOWN_MODEL}\n{print_supported_ml_models()}")
if model_name in XGBOOST_SUPPORTED_TABLE:
print(f"{CLI_XGBOOST_NOT_INSTALLED}\n{CLI_MORE_INFO}")
else:
print(f"{CLI_UNKNOWN_MODEL}\n{print_supported_ml_models()}")
return
run_ps = True
_model = model_class()
Expand All @@ -109,12 +115,16 @@ def main():
pymilo_help()
parser.print_help()
else:
PymiloServer(
model=_model,
pymilo_server = PymiloServer(
port=_port,
compressor=_compressor,
communication_protocol=_communication_protocol,
).communicator.run()
)
if _model is not None:
pymilo_server.init_client(PYMILO_CLIENT_DEFAULT_CLIENT_ID)
pymilo_server.init_ml_model(PYMILO_CLIENT_DEFAULT_CLIENT_ID, PYMILO_CLIENT_DEFAULT_ML_MODEL_ID)
pymilo_server.set_ml_model(PYMILO_CLIENT_DEFAULT_CLIENT_ID, PYMILO_CLIENT_DEFAULT_ML_MODEL_ID, _model)
pymilo_server.communicator.run()


if __name__ == '__main__':
Expand Down
11 changes: 11 additions & 0 deletions pymilo/chains/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@
from .cross_decomposition_chain import cross_decomposition_chain
from ..utils.util import get_sklearn_type, check_str_in_iterable

try:
from .xgboost_chain import xgboost_chain as _xgboost_chain
except BaseException:
_xgboost_chain = None


MODEL_TYPE_TRANSPORTER = {
"LINEAR_MODEL": linear_chain.transport,
Expand All @@ -23,6 +28,9 @@
"CROSS_DECOMPOSITION": cross_decomposition_chain.transport,
}

if _xgboost_chain is not None:
MODEL_TYPE_TRANSPORTER["XGBOOST"] = _xgboost_chain.transport


def get_concrete_transporter(model):
"""
Expand All @@ -37,6 +45,9 @@ def get_concrete_transporter(model):
if upper_model in MODEL_TYPE_TRANSPORTER.keys():
return upper_model, MODEL_TYPE_TRANSPORTER[upper_model]

if _xgboost_chain is not None and _xgboost_chain.is_supported(model):
return "XGBOOST", _xgboost_chain.transport

if linear_chain.is_supported(model):
return "LINEAR_MODEL", linear_chain.transport
elif neural_network_chain.is_supported(model):
Expand Down
Loading
Loading