Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
d75b8a7
Gate optional GPy dependencies; add pytest markers; make wrappers imp…
AlejandroGomezFrieiro Oct 14, 2025
ee58765
refactor: unify dependency gating and markers; promote matplotlib & D…
AlejandroGomezFrieiro Oct 15, 2025
f5bc001
docs: document pytest marker taxonomy and gating (Ticket 024)
AlejandroGomezFrieiro Oct 15, 2025
82e5308
docs: clarify optional extras; add GPy to docs extra and switch RTD t…
AlejandroGomezFrieiro Oct 15, 2025
d01caa6
merge: bring docs extras clarification and RTD config update from opt…
AlejandroGomezFrieiro Oct 15, 2025
f4c3902
ci: split core and gpy test jobs; document optional extras in changelog
AlejandroGomezFrieiro Oct 15, 2025
3c057c5
feat(extras): introduce optional dependency groups and docs updates\n…
AlejandroGomezFrieiro Oct 15, 2025
b7cc71f
chore: remove tracked .opencode timeline file
AlejandroGomezFrieiro Oct 15, 2025
61aa33e
build: migrate packaging to PEP 621 in pyproject.toml with dynamic ve…
AlejandroGomezFrieiro Oct 15, 2025
4fd20bd
build: migrate CI & docs to extras-based installation; add packaging …
AlejandroGomezFrieiro Oct 15, 2025
4fe9a61
chore: Run black and isort
AlejandroGomezFrieiro Oct 15, 2025
70f66a8
Answer comments with minor changes
AlejandroGomezFrieiro Nov 5, 2025
7f27f2f
Adds random seed fixture for uniform sampling
AlejandroGomezFrieiro Nov 5, 2025
0128fc2
Passes to , and updates the tests
AlejandroGomezFrieiro Nov 5, 2025
39e5d33
Cleanup pyproject.toml dependencies
AlejandroGomezFrieiro Nov 5, 2025
9a614ec
Fixes bad definition in pyproject toml
AlejandroGomezFrieiro Nov 5, 2025
a7e9de8
Add comments to all guarded imports
AlejandroGomezFrieiro Nov 12, 2025
574b94d
Remove gpy from several tests and one notebook
apaleyes Dec 19, 2025
4c72915
Notice, update rtd python version
apaleyes Dec 19, 2025
f1e24e1
Test for modern python versions
apaleyes Dec 19, 2025
387f90b
Add nbformat
apaleyes Dec 19, 2025
df270b6
Add integ tests install, fix a warning, fix linting
apaleyes Dec 19, 2025
6d8e7e0
improve test skipping
apaleyes Dec 19, 2025
9d5b1ac
fix?
apaleyes Dec 19, 2025
e8685e3
Improve coverage reports, remove editable installs
apaleyes Dec 19, 2025
ff9f010
One job to monitor
apaleyes Dec 19, 2025
b24a4c4
fix?
apaleyes Dec 19, 2025
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
14 changes: 8 additions & 6 deletions .github/workflows/codecov.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,16 @@ jobs:
run: |
python -m pip install --upgrade pip
python -m pip install flake8 pytest
pip install -r requirements/requirements.txt
pip install -r requirements/test_requirements.txt
# work around issues with GPy setting matplotlib backend
echo 'backend: Agg' > matplotlibrc
pip install .
- name: Run coverage
- name: Run core coverage
run: |
pip install .[tests]
python -m pytest --verbose --cov emukit --cov-report term-missing tests
- name: Run GPy coverage
run: |
pip install ".[tests, gpy]"
# work around issues with GPy setting matplotlib backend
echo 'backend: Agg' > matplotlibrc
python -m pytest -m 'gpy or not gpy' --verbose --cov emukit --cov-report term-missing tests
- name: Run codecov
if: success()
run: |
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/format.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ jobs:
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements/test_requirements.txt
pip install -e .[tests]
- name: Lint with flake8
run: |
# stop the build if there are Python syntax errors or undefined names
Expand Down
70 changes: 54 additions & 16 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,35 +7,59 @@ on:
branches: [ main ]

jobs:
all_tests:
core_tests:

runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.9", "3.10", "3.11"]
python-version: ["3.10", "3.13"]

steps:
- uses: actions/checkout@v5
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v6
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
- name: Install core dependencies (no GPy)
run: |
python -m pip install --upgrade pip
pip install -r requirements/requirements.txt
pip install -r requirements/test_requirements.txt
pip install -r requirements/integration_test_requirements.txt -q
# work around issues with GPy setting matplotlib backend
pip install .[tests]
# work around issues with GPy setting matplotlib backend (defensive even w/o GPy)
echo 'backend: Agg' > matplotlibrc
pip install .
- name: Unit tests
- name: Unit tests (core)
run: |
python -m pytest tests
- name: Integration tests
- name: Integration tests (core)
run: |
pip install .[integration-tests]
python -m pytest integration_tests

gpy_tests:

runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.11"]

steps:
- uses: actions/checkout@v5
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v6
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies with GPy extra
run: |
python -m pip install --upgrade pip
pip install ".[tests, gpy]"
echo 'backend: Agg' > matplotlibrc
- name: Unit tests (with GPy)
run: |
python -m pytest tests -m 'gpy or not gpy'
- name: Integration tests (with GPy)
run: |
pip install ".[integration-tests, examples]"
python -m pytest integration_tests -m 'gpy or not gpy'

os_versions:

strategy:
Expand All @@ -49,14 +73,28 @@ jobs:
uses: actions/setup-python@v6
with:
python-version: "3.10"
- name: Install dependencies
- name: Install dependencies (core)
run: |
python -m pip install --upgrade pip
pip install -r requirements/requirements.txt
pip install -r requirements/test_requirements.txt
# work around issues with GPy setting matplotlib backend
pip install .[tests]
# work around issues with GPy setting matplotlib backend (defensive even w/o GPy)
echo 'backend: Agg' > matplotlibrc
pip install .
- name: Unit tests
- name: Unit tests (core, multi-OS)
run: |
python -m pytest tests

all-pass:
if: always()
needs: [core_tests, gpy_tests, os_versions]

runs-on: ubuntu-latest

steps:
- name: Check all tests pass
run: |
if [[ "${{ needs.core_tests.result }}" != "success" && "${{ needs.core_tests.result }}" != "skipped" ]] || \
[[ "${{ needs.gpy_tests.result }}" != "success" && "${{ needs.gpy_tests.result }}" != "skipped" ]] || \
[[ "${{ needs.os_versions.result }}" != "success" && "${{ needs.os_versions.result }}" != "skipped" ]]; then
echo "One or more test jobs failed"
exit 1
fi
7 changes: 5 additions & 2 deletions .readthedocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,14 @@ version: 2
build:
os: ubuntu-22.04
tools:
python: "3.9"
python: "3.10"

sphinx:
configuration: doc/conf.py

python:
install:
- requirements: requirements/doc_requirements.txt
- method: pip
path: .
extra_requirements:
- docs
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,16 @@
# Changelog
All notable changes to Emukit will be documented in this file.

## [0.5.0]
- Upgrade codebase to allow `numpy` versions greater than 2.0, while maintaining backwards compatibility. `GPy` remains pinned to `numpy<2.0` due to upstream constraints, but core Emukit functionality is now independent of it. Users can now install and use Emukit core API with `numpy>=2.0`.
- Packaging: Adopt PEP 621 metadata in `pyproject.toml`; dynamic version from `emukit.__version__`.
- Packaging: Introduced setuptools extras (`gpy`, `bnn`, `sklearn`, `docs`, `examples`, `tests`, `dev`).
- CI: Workflows now install extras via `pip install -e .[tests]` (and `[tests,gpy]`) instead of requirements files.
- Docs: Updated installation guide, README, CONTRIBUTING to prefer extras over legacy `requirements/` files.
- Tests: Documented pytest marker and optional dependency usage.
- Docs build: Use `docs` extra (includes GPy).
- Maintenance: Legacy requirements files retained temporarily for reference; deprecation planned.

## [0.4.11]
- Various bugfixes, including installation on Windows
- Updated copyright info
Expand Down
63 changes: 59 additions & 4 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ Before submitting the pull request, please go through this checklist to make the
## Setting up a development environment

### Building the code
See installing from source.
See installing from source (from version 0.5.0 using `pip install -e .[tests]` for core development, and `pip install -e .[dev]` for examples and docs as well). Note that, due to `numpy` version incompatibilities brought forwards by legacy dependencies (such as `GPy`), it is recommended to develop core features without installing any of the extras, using `tests` whenever possible. This will be improved whenever major dependencies, such as `GPy`, are updated.

### Running tests
Run the full suite of unit tests or integration tests with these commands:
Expand All @@ -91,10 +91,65 @@ from the top level directory. To check unit test coverage, run this:
pytest --verbose --cov emukit --cov-report term-missing tests
```

Notice that unit tests and integration tests have their own set of additional dependencies. Those can be found in the `requirements` folder, and installed with:
Notice that unit tests and integration tests have their own set of additional dependencies. You can install them via extras defined in `pyproject.toml`:
```
pip install -r requirements/test_requirements.txt
pip install -r requirements/integration_test_requirements.txt
# Core + test tooling
pip install -e .[tests]

# Add optional dependency groups as needed (examples):
pip install -e .[gpy]
pip install -e .[bnn]
pip install -e .[sklearn]
# Or everything:
pip install -e .[examples]
```
Legacy requirement files in `requirements/` remain temporarily for reference but will be phased out; prefer extras going forward.

### Test markers & optional dependencies
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This section is dope!

Emukit uses pytest markers to group tests that rely on optional dependencies. Current markers (defined in `pyproject.toml` under `[tool.pytest.ini_options]`):

- gpy: tests requiring GPy optional dependency
- pybnn: tests requiring pybnn optional dependency
- sklearn: tests requiring scikit-learn optional dependency
- notebooks: tests executing Jupyter notebooks (requires nbformat, nbconvert)

Example of gating a test that needs GPy:
```python
import pytest

pytest.importorskip("GPy") # skip if GPy not installed
pytestmark = pytest.mark.gpy # file-level marker (can also set per test)

def test_some_gpy_integration():
import GPy
# ... assertions using GPy ...
```
Function-level alternative:
```python
import pytest

def test_feature_x():
GPy = pytest.importorskip("GPy")
# ... use GPy ...

test_feature_x = pytest.mark.gpy(test_feature_x)
```
Guidelines:
- Always protect optional imports with `pytest.importorskip("<module>")` to turn absence into a skip, not an error.
- Apply the corresponding marker (`pytestmark = pytest.mark.<marker>` or function-level) so contributors can include/exclude groups via `-m`.
- When introducing a new optional dependency group, add its marker entry in `setup.cfg` under `[tool:pytest]` and document it in this section.
- Avoid installing heavy optional dependencies in default dev loops; install only when working on that area (e.g. `pip install .[gpy]`).
- Notebook execution tests use the `notebooks` marker; exclude them during rapid iteration with `pytest -m 'not notebooks'`.
- Keep slow or heavyweight examples under an appropriate marker instead of core unit tests.

Filtering examples:
Run only core tests (skip all optional groups):
```
pytest -m 'not (gpy or pybnn or sklearn or notebooks)'
```
Run just the sklearn tests:
```
pytest -m sklearn
```

### Formatting
Expand Down
40 changes: 37 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,43 @@ pip install emukit

For other install options, see our [documentation](https://emukit.readthedocs.io/en/latest/installation.html).

### Dependencies / Prerequisites
Emukit's primary dependencies are Numpy and GPy.
See [requirements](requirements/requirements.txt).
### Dependencies / Optional Extras
Core dependencies are the numerical Python stack (NumPy, SciPy, matplotlib, emcee). Optional groups enable additional features without pulling heavy dependencies into a minimal install:

- `gpy`: Gaussian process wrappers, multi-fidelity models, Bayesian quadrature (adds `GPy`). Also see notice below.
- `bnn`: Bayesian neural network (Bohamiann) and Profet meta-surrogate examples (adds `pybnn`, `torch`).
- `sklearn`: scikit-learn model wrapper and examples (adds `scikit-learn`).
- `docs`: Build documentation locally (adds Sphinx toolchain + GPy to render GP API docs).
- `tests`: Test tooling.
- `full`: Convenience meta extra installing all of the above.

Install extras via pip:
```
# Core install
pip install emukit

# Add GPy-based functionality
pip install emukit[gpy]

# Bohamiann & Profet examples (Bayesian neural nets)
pip install emukit[bnn]

# scikit-learn model wrapper support
pip install emukit[sklearn]

# Build documentation (includes GPy + Sphinx toolchain)
pip install emukit[docs]

# Bundle for running most example scripts (GPy + pybnn + torch + scikit-learn)
pip install emukit[examples]

# Everything (gpy + bnn + sklearn + examples + docs + test tooling)
pip install emukit[full]
```
Legacy pinned requirement files remain in the `requirements/` directory for reference but extras (above) are the preferred installation mechanism going forward.

### NumPy 2 notice
Core Emukit functionality works with NumPy 2.0+. However, some parts of Emukit (e.g. most acquisition functions) need GPy, that for the time being is a bit behind. If using GPy is critical for you, consider installing earlier versions of Emukit.

## Getting started
For examples see our [tutorial notebooks](http://nbviewer.jupyter.org/github/emukit/emukit/blob/main/notebooks/index.ipynb).
Expand Down
58 changes: 49 additions & 9 deletions doc/installation.rst
Original file line number Diff line number Diff line change
@@ -1,27 +1,67 @@
Installation
============

Emukit requires Python 3.5 or above and NumPy for basic functionality. Some core features also need GPy. Some advanced elements may have their own dependencies, but their installation is optional.
Emukit requires Python 3.10 or above. The core installation provides the numerical stack and Emukit's pure numpy features. Gaussian process functionality based on GPy, multi-fidelity models, and quadrature models require the optional GPy extra.

To install emukit, just run
To install the core emukit package (without GPy), run

.. code-block:: bash

pip install emukit

Installation from sources
Optional dependencies
________
The simplest way to install emukit from sources is to run
You can install optional dependency groups via setuptools extras. Each group enables additional functionality without inflating the core install:

- ``gpy``: Gaussian process wrappers, multi-fidelity models, Bayesian quadrature (adds ``GPy``).
- ``bnn``: Bayesian neural network (Bohamiann) and Profet meta-surrogate examples (adds ``pybnn``, ``torch``).
- ``sklearn``: scikit-learn model wrapper and related examples (adds ``scikit-learn``).
- ``docs``: Build documentation locally (Sphinx toolchain + GPy for rendering GP API docs).
- ``tests``: Test tooling only.
- ``examples``: Convenience bundle for most example scripts (installs ``GPy``, ``pybnn``, ``torch``, ``scikit-learn``).
- ``dev``: Convenience meta extra installing all of the above.

.. code-block:: bash

# Gaussian processes / multi-fidelity / quadrature
pip install emukit[gpy]

# Bayesian neural network & Profet examples
pip install emukit[bnn]

# scikit-learn model wrapper
pip install emukit[sklearn]

# Build documentation locally (includes gpy)
pip install emukit[docs]

# Bundle of example dependencies
pip install emukit[examples]

# Everything (gpy + bnn + sklearn + examples + docs + tests)
pip install emukit[dev]

Installation from sources


.. code-block:: bash

pip install git+https://github.com/emukit/emukit.git

If you would like a bit more control, you can do it step by step: clone the repo, install dependencies, install emukit.
If you would like a bit more control (e.g. for development), clone the repo, install dependencies, install emukit.

.. code-block:: bash

git clone https://github.com/emukit/emukit.git
cd Emukit
pip install -r requirements/requirements.txt
python setup.py develop
git clone https://github.com/emukit/emukit.git
cd Emukit
# Editable install with desired extras (examples below)
pip install -e .[tests] # core + test tooling
pip install -e .[gpy] # add GPy-based functionality
# Or everything:
pip install -e .[dev]

`python setup.py develop` is no longer needed; PEP 621 metadata in `pyproject.toml` enables editable installs directly via pip (PEP 660).

NumPy 2 notice
________
Core Emukit functionality works with NumPy 2.0+. However, some parts of Emukit (e.g. most acquisition functions) need GPy, that for the time being is a bit behind. If using GPy is critical for you, consider installing earlier versions of Emukit.
Loading