Skip to content

Commit b621f9c

Browse files
DOC add pyodide-http to enable fetch_openml in jupyterlite (#177)
* DOC add pyodide-http to enable fetch_openml in jupyterlite
1 parent 05533fd commit b621f9c

File tree

9 files changed

+1983
-2074
lines changed

9 files changed

+1983
-2074
lines changed

.gitignore

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,4 +34,7 @@ doc/sg_execution_times.rst
3434
doc/.jupyterlite.doit.db
3535
doc/jupyterlite_contents/
3636
doc/_contents/
37-
emsdk/
37+
doc/_output/
38+
emsdk/
39+
packages/
40+
pyodide/

doc/conf.py

Lines changed: 47 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
import importlib.metadata
1111
from datetime import datetime
1212

13+
from sphinx_gallery.notebook import add_code_cell
14+
1315
# General information about the project.
1416
project = "fastcan"
1517
copyright = f"2024 - {datetime.now().year}, fastcan developers (MIT License)"
@@ -44,7 +46,7 @@
4446
# For PlantUML diagrams
4547
"sphinxcontrib.plantuml",
4648
# For interactive examples via JupyterLite
47-
'jupyterlite_sphinx',
49+
"jupyterlite_sphinx",
4850
]
4951

5052
# List of patterns, relative to source directory, that match files and
@@ -77,11 +79,6 @@
7779
"sklearn": ("https://scikit-learn.org/stable", None),
7880
}
7981

80-
sphinx_gallery_conf = {
81-
"examples_dirs": ["../examples"],
82-
"gallery_dirs": ["auto_examples"],
83-
}
84-
8582
# -----------------------------------------------------------------------------
8683
# Interactive documentation examples via JupyterLite
8784
# -----------------------------------------------------------------------------
@@ -92,3 +89,47 @@
9289
"If you encounter any issues, please report them on the"
9390
" [fastcan issue tracker](https://github.com/scikit-learn-contrib/fastcan/issues)."
9491
)
92+
93+
94+
def notebook_modification_function(notebook_content, notebook_filename):
95+
notebook_content_str = str(notebook_content)
96+
dummy_notebook_content = {"cells": []}
97+
code_lines = []
98+
99+
if "fetch_" in notebook_content_str:
100+
code_lines.extend(
101+
[
102+
"import pyodide_http",
103+
"pyodide_http.patch_all()",
104+
]
105+
)
106+
# always import matplotlib and pandas to avoid Pyodide limitation with
107+
# imports inside functions
108+
code_lines.extend(
109+
[
110+
"import matplotlib",
111+
"import pandas",
112+
]
113+
)
114+
115+
if code_lines:
116+
code_lines = ["# JupyterLite-specific code"] + code_lines
117+
code = "\n".join(code_lines)
118+
add_code_cell(dummy_notebook_content, code)
119+
120+
notebook_content["cells"] = (
121+
dummy_notebook_content["cells"] + notebook_content["cells"]
122+
)
123+
124+
125+
# -----------------------------------------------------------------------------
126+
suppress_warnings = [
127+
# Ignore new warning in Sphinx 7.3.0 while pickling environment:
128+
# WARNING: cannot cache unpickable configuration value: 'sphinx_gallery_conf'
129+
"config.cache",
130+
]
131+
sphinx_gallery_conf = {
132+
"examples_dirs": ["../examples"],
133+
"gallery_dirs": ["auto_examples"],
134+
"jupyterlite": {"notebook_modification_function": notebook_modification_function},
135+
}

doc/environment.yml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,7 @@ channels:
55
dependencies:
66
- xeus-python
77
- matplotlib
8-
- fastcan
8+
- pandas
9+
- fastcan
10+
- pip:
11+
- pyodide-http

examples/plot_forecasting.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,6 @@
55
66
.. currentmodule:: fastcan.narx
77
8-
.. note::
9-
This example can NOT be run with JupyterLite so far.
10-
118
In this examples, we will demonstrate how to use :func:`make_narx` to build (nonlinear)
129
AutoRegressive (AR) models for time-series forecasting.
1310
The time series used isthe monthly average atmospheric CO2 concentrations

fastcan/narx/tests/test_narx.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -647,6 +647,7 @@ def test_auto_reg_error():
647647
with pytest.raises(ValueError, match=r"X should be an array-like of shape.*"):
648648
model.predict(len(y), y_init=y[: model.max_delay_])
649649

650+
650651
def test_predict_ndim():
651652
"""Test the ndim of predict output"""
652653
X = np.random.rand(10, 2)

pixi.lock

Lines changed: 1910 additions & 2051 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pyproject.toml

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
[project]
22
name = "fastcan"
33
version = "0.4.1"
4-
description = "A fast canonical-correlation-based feature selection method"
4+
description = "A fast canonical-correlation-based greedy search algorithm"
55
authors = [
66
{ name = "Matthew Sikai Zhang", email = "[email protected]" },
77
]
@@ -59,7 +59,7 @@ channels = ["conda-forge"]
5959
platforms = ["win-64", "linux-64", "osx-64", "osx-arm64", "linux-aarch64"]
6060

6161
[tool.pixi.dependencies]
62-
python = ">=3.12.0,<3.13"
62+
python = ">=3.10"
6363
scikit-learn = ">=1.7.0,!=1.7.1"
6464

6565
[tool.pixi.pypi-dependencies]
@@ -81,6 +81,7 @@ plantuml = "*"
8181
[tool.pixi.feature.wasm.dependencies]
8282
pip = "*"
8383
pyodide-build = "*"
84+
prettier = "*"
8485

8586
[tool.pixi.feature.asv.dependencies]
8687
asv = "*"
@@ -156,19 +157,23 @@ spell = "codespell"
156157

157158
[tool.pixi.feature.docs.tasks]
158159
doc = { cmd = "{{ SPHINXBUILD }} -M {{ CMD }} {{ SOURCEDIR }} {{ BUILDDIR }} {{ SPHINXOPTS }} --fail-on-warning", cwd = "doc", args = [{ arg = "SPHINXBUILD", default = "sphinx-build" }, { arg = "CMD", default = "html" }, { arg = "SOURCEDIR", default = "." }, { arg = "BUILDDIR", default = "_build" }, { arg = "SPHINXOPTS", default = "" }] }
159-
doc-clean = { cmd = "rm -rf {{ BUILDDIR }} generated auto_examples jupyterlite_contents .jupyterlite.doit.db _contents", cwd = "doc", args = [{ arg = "BUILDDIR", default = "_build" }] }
160+
doc-clean = { cmd = "rm -rf {{ BUILDDIR }} generated auto_examples jupyterlite_contents .jupyterlite.doit.db _contents _output .cache", cwd = "doc", args = [{ arg = "BUILDDIR", default = "_build" }] }
160161
doc-deploy = { cmd = "python -m http.server" , cwd = "doc/_build/html" }
161162

162163
[tool.pixi.feature.nogil.tasks]
163164
nogil-h = "python -Xgil=0 -m timeit -n 5 -s 'import numpy as np; from fastcan import FastCan; X = np.random.rand(3000, 100); y = np.random.rand(3000, 20)' 's = FastCan(100, verbose=0).fit(X, y)'"
164165
nogil-eta = "python -Xgil=0 -m timeit -n 5 -s 'import numpy as np; from fastcan import FastCan; X = np.random.rand(3000, 100); y = np.random.rand(3000, 20)' 's = FastCan(100, eta=True, verbose=0).fit(X, y)'"
165166

166167
[tool.pixi.feature.wasm.tasks]
167-
wasm-clone-emsdk = "bash -c '[ -d emsdk ] || git clone https://github.com/emscripten-core/emsdk.git emsdk'"
168-
wasm-compatible = "pyodide xbuildenv search -a"
169-
wasm-toolchain = { cmd = "LATEST_COMPATIBLE=$(pyodide xbuildenv search -a | grep '│ Yes' | head -n 1 | awk -F '│' '{print $2}' | xargs) && pyodide xbuildenv install $LATEST_COMPATIBLE" }
170-
wasm-setup-emsdk = { cmd = "PYODIDE_EMSCRIPTEN_VERSION=$(pyodide config get emscripten_version) && ./emsdk install $PYODIDE_EMSCRIPTEN_VERSION && ./emsdk activate $PYODIDE_EMSCRIPTEN_VERSION", cwd = "emsdk", depends-on = ["wasm-clone-emsdk", "wasm-toolchain"] }
171-
wasm-build = { cmd = "bash -c 'source emsdk/emsdk_env.sh && pyodide build'", depends-on = ["wasm-setup-emsdk"] }
168+
emsdk-clone = "bash -c '[ -d emsdk ] || git clone https://github.com/emscripten-core/emsdk.git emsdk'"
169+
pyodide-compatible = "pyodide xbuildenv search -a"
170+
pyodide-toolchain = { cmd = "LATEST_COMPATIBLE=$(pyodide xbuildenv search -a | grep '│ Yes' | head -n 1 | awk -F '│' '{print $2}' | xargs) && pyodide xbuildenv install $LATEST_COMPATIBLE" }
171+
emsdk-setup = { cmd = "PYODIDE_EMSCRIPTEN_VERSION=$(pyodide config get emscripten_version) && ./emsdk install $PYODIDE_EMSCRIPTEN_VERSION && ./emsdk activate $PYODIDE_EMSCRIPTEN_VERSION", cwd = "emsdk", depends-on = ["emsdk-clone", "pyodide-toolchain"] }
172+
pyodide-build = { cmd = "bash -c 'source emsdk/emsdk_env.sh && pyodide build'", depends-on = ["emsdk-setup"] }
173+
pyodide-create-recipe = "rm -rf packages && pyodide skeleton pypi fastcan"
174+
pyodide-build-recipe = { cmd = "rm -rf dist && bash -c 'source emsdk/emsdk_env.sh && pyodide build-recipes fastcan --install'", depends-on = ["emsdk-setup"] }
175+
pyodide-download = '''bash -c "[ -d pyodide ] || (LATEST_TAG=$(curl -s https://api.github.com/repos/pyodide/pyodide/releases/latest | grep \"tag_name\" | cut -d \" -f4) && curl -L https://github.com/pyodide/pyodide/releases/download/${LATEST_TAG}/pyodide-${LATEST_TAG}.tar.bz2 | tar -xjf -)"'''
176+
pyodide-test-recipe = { cmd = "mv ../dist/* . && python -m http.server --directory .", cwd = "pyodide", depends-on = ["pyodide-download", "pyodide-build-recipe"] }
172177

173178
[tool.pixi.environments]
174179
dev = ["docs", "test", "build", "jupyter", "asv"]

rtd-environment.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,13 @@ dependencies:
55
- micromamba
66
- pip
77
- furo
8-
- matplotlib
9-
- pandas
108
- sphinx-gallery
119
- sphinx-design
1210
- sphinxcontrib-plantuml
1311
- jupyterlite-sphinx
1412
- plantuml
13+
- matplotlib
14+
- pandas
1515
- pip:
1616
- .
17-
- jupyterlite-xeus >=2.1.2
17+
- jupyterlite-xeus

tests/test_fastcan.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ def test_select_kbest_classif():
5252
ssc = correlation_filter.scores_.sum()
5353
# Test whether the ssc from the fastcan is consistent
5454
# with the mcc from the linear regression
55-
assert_almost_equal(actual=ssc, desired=gtruth_ssc)
55+
assert abs(ssc - gtruth_ssc) < 1e-5
5656

5757
support = correlation_filter.get_support()
5858
gtruth = np.zeros(n_features)

0 commit comments

Comments
 (0)