Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ci: automatically test all notebooks under examples/notebooks and render them in docs page #756

Merged
merged 19 commits into from
Sep 18, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
44 changes: 44 additions & 0 deletions .github/workflows/run-notebooks.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
name: Run Jupyter Notebooks

on:
push:
branches:
- main
pull_request:
branches:
- main

jobs:
prepare:
runs-on: syne-tune_ubuntu-latest_16-core
outputs:
matrix: ${{ steps.set-matrix.outputs.matrix }}
steps:
- name: check out Syne Tune
uses: actions/checkout@v3
- name: Set up Python 3.8
uses: actions/setup-python@v2
- name: Install dev dependencies
run: python -m pip install -e '.[dev]'
- name: Convert notebooks to python scripts
id: set-matrix
run: python ./.github/workflows/utils/notebooks2scripts.py
- name: Upload converted python script
uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3
with:
name: converted_notebooks
path: examples/notebooks/

tests:
needs: prepare
strategy:
fail-fast: false
matrix:
script: ${{ fromJSON(needs.prepare.outputs.matrix)}}
uses: ./.github/workflows/run-syne-tune.yml
with:
download-artifact-name: converted_notebooks
download-artifact-path: examples/notebooks/
script-path: examples/notebooks/${{ matrix.script }}
extras-require: basic
additional-command: pip install xgboost
12 changes: 12 additions & 0 deletions .github/workflows/run-syne-tune.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,12 @@ on:
extras-require:
required: false
type: string
download-artifact-path:
required: false
type: string
download-artifact-name:
required: false
type: string
secrets:
PROD_AWS_INTEG_TEST_ROLE_ARN:
required: false
Expand Down Expand Up @@ -59,6 +65,12 @@ jobs:
- name: Install Syne Tune with selected dependencies
if: ${{ inputs.extras-require != '' }}
run: python -m pip install -e '.[${{ inputs.extras-require }}]'
- name: Download artifact (must have been previously uploaded via actions/upload-artifact)
if: ${{ inputs.download-artifact-path != '' }}
uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2
with:
name: ${{ inputs.download-artifact-name }}
path: ${{ inputs.download-artifact-path }}
- name: Run optional custom command
if: ${{ inputs.additional-command != '' }}
run: ${{ inputs.additional-command }}
Expand Down
39 changes: 39 additions & 0 deletions .github/workflows/utils/notebooks2scripts.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import os
import json

from traitlets.config import Config
from nbconvert.exporters import PythonExporter

c = Config()
c.TagRemovePreprocessor.remove_cell_tags = "ci-skip-cell"
python_exporter = PythonExporter(config=c)


notebook_directory = "examples/notebooks"
files = [
f
for f in os.listdir(notebook_directory)
if os.path.isfile(os.path.join(notebook_directory, f))
]

converted_files = []

for file_name in files:

# convert to python script and write to disk
python_code, _ = python_exporter.from_filename(f"{notebook_directory}/{file_name}")
converted_file_path = f"{notebook_directory}/{file_name.split('.')[0]}.py"
with open(converted_file_path, "w") as f:
f.write(python_code)

converted_files.append(converted_file_path.split("/")[-1])

matrix_json = json.dumps(converted_files)
print(matrix_json)
with open("matrix.json", "w") as f:
f.write(matrix_json)

name = "matrix"
value = matrix_json
with open(os.environ["GITHUB_OUTPUT"], "a") as fh:
print(f"{name}={value}", file=fh)
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,6 @@ coverage.xml
.idea
.vscode
std.out
docs/build/*
docs/source/_apidoc/*
docs/source/notebooks/*
14 changes: 14 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,16 @@ projects, by default, use the default GitHub issue labels
(enhancement/bug/duplicate/help wanted/invalid/question/wontfix), looking at any
'help wanted' issues is a great place to start.

## Adding/updating Syne Tune examples

We are always interested in adding examples that demonstrate how to use Syne Tune.

Please add your example inside the `examples/` folder.

If you create an example notebook, please put it under the `examples/notebooks` folder.

Please ensure that your example assumes no prior knowledge of hyperparameter optimization, to ensure that the library remains accessible to new users.


## Contributing to the Documentation

Expand All @@ -95,6 +105,10 @@ hints:
(not the tall `View docs` link in the upper right).


Jupyter notebooks inside the `examples/notebooks` folder can be easily added as documentation pages.
See `tune_xgboost.ipynb` for an example showing how this can be done.


## Code of Conduct

This project has adopted the [Amazon Open Source Code of Conduct](https://aws.github.io/code-of-conduct).
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ Syne Tune is developed in collaboration with the team behind the [Automatic Mode
To install Syne Tune from pip, you can simply do:

```bash
pip install 'syne-tune[extra]'
pip install 'syne-tune[basic]'
```

or to install the latest version from source:
Expand All @@ -48,7 +48,7 @@ cd syne-tune
python3 -m venv st_venv
. st_venv/bin/activate
pip install --upgrade pip
pip install -e '.[extra]'
pip install -e '.[basic]'
```

This installs everything in a virtual environment `st_venv`. Remember to activate
Expand Down
12 changes: 12 additions & 0 deletions docs/source/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,22 @@
import os
import shutil
import sys
from pathlib import Path

import syne_tune


sys.path.insert(0, os.path.abspath("../../"))


def copy_notebooks_into_docs_folder(app):
# .ipynb files must be inside the docs/ folder for Jupyter to be able to convert them
source = Path(__file__).parent.parent.parent / "examples" / "notebooks"
destination = Path(__file__).parent / "notebooks"
print(f"Jupyter notebook source path: {source}; destination path: {destination}")
shutil.copytree(source, destination, dirs_exist_ok=True)


def run_apidoc(app):
"""Generate doc stubs using sphinx-apidoc."""
module_dir = os.path.join(app.srcdir, "../../")
Expand Down Expand Up @@ -61,6 +70,7 @@ def run_apidoc(app):

def setup(app):
"""Register our sphinx-apidoc hook."""
app.connect("builder-inited", copy_notebooks_into_docs_folder)
app.connect("builder-inited", run_apidoc)


Expand Down Expand Up @@ -92,6 +102,7 @@ def setup(app):
"sphinxcontrib.bibtex",
"myst_parser",
"sphinxcontrib.jquery", # can be removed as soon as the theme no longer depends on jQuery
"nbsphinx",
]

myst_heading_anchors = 2
Expand All @@ -109,6 +120,7 @@ def setup(app):
templates_path = ["_templates"]
exclude_patterns = []

nbsphinx_execute = "never"

# -- Options for HTML output -------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output
Expand Down
10 changes: 9 additions & 1 deletion docs/source/examples_toc.rst
Original file line number Diff line number Diff line change
@@ -1,9 +1,17 @@
Examples
========

.. toctree::
:name: Example Notebooks
:caption: Example Notebooks
:maxdepth: 1

notebooks/tune_xgboost.ipynb


.. toctree::
:name: Examples of Syne Tune
:name: Example Tuning Scripts
:caption: Example Tuning Scripts
:maxdepth: 1

examples
Loading
Loading