I wish to load SciPy on Pyodide without using a CDN.
For that, I installed the pyodide package using npm, and within a webworker I ran
pyodide.loadPackage('/wheels/scipy-1.14.1-cp313-cp313-pyodide_2025_0_wasm32.whl')
The pyodide version on the node project was pinned to 0.28.2 and the wheel was extracted from the full 0.28.2 zip.
All other packages (e.g. numpy and others) load successfully, yet on scipy it seems to try and dynamically load libopenblas.so.
I suspected that it is the same as libopenblas-0.3.26.zip within the full package, and transfered it to the same /wheels path (even though it is not a wheel) and it doesn't seem to work.
How do I load libopenblas using pyodide so scipy can find it?
Full error for reference:
The following error occurred while loading scipy:
Failed to load dynamic library /lib/python3.13/site-packages/scipy/integrate/_dop.cpython-313-wasm32-emscripten.so: 'Could not load dynamic lib: /lib/python3.13/site-packages/scipy/integrate/_dop.cpython-313-wasm32-emscripten.so
Error: Failed to find dynamic library "libopenblas.so"
PythonError: Traceback (most recent call last):
File "/lib/python313.zip/_pyodide/_base.py", line 597, in eval_code_async
await CodeRunner(
...<9 lines>...
.run_async(globals, locals)
File "/lib/python313.zip/_pyodide/_base.py", line 411, in run_async
coroutine = eval(self.code, globals, locals)
File "<exec>", line 22, in <module>
File "/lib/python3.13/site-packages/proj/__init__.py", line 3, in <module>
from scipy.signal import firwin
File "/lib/python3.13/site-packages/scipy/signal/__init__.py", line 307, in <module>
from . import _sigtools, windows
File "/lib/python3.13/site-packages/scipy/signal/windows/__init__.py", line 42, in <module>
from ._windows import *
File "/lib/python3.13/site-packages/scipy/signal/windows/_windows.py", line 7, in <module>
from scipy import linalg, special, fft as sp_fft
File "/lib/python3.13/site-packages/scipy/__init__.py", line 134, in __getattr__
return _importlib.import_module(f'scipy.{name}')
~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^
File "/lib/python313.zip/importlib/__init__.py", line 88, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/lib/python3.13/site-packages/scipy/linalg/__init__.py", line 203, in <module>
from ._misc import *
File "/lib/python3.13/site-packages/scipy/linalg/_misc.py", line 3, in <module>
from .blas import get_blas_funcs
File "/lib/python3.13/site-packages/scipy/linalg/blas.py", line 213, in <module>
from scipy.linalg import _fblas
ImportError: Could not load dynamic lib: /lib/python3.13/site-packages/scipy/linalg/_fblas.cpython-313-wasm32-emscripten.so
Error: bad export type for 'srotg_': undefined
1 Answer 1
Alongside your scipy-1.14.1-....whl file, you need to serve the packages.json file and the libopenblas-0.3.26.zip archive. These should be the exact versions from the Pyodide 0.28.2 release you are using
Place these files in a directory accessible to your web worker (e.g., /wheels/).
Update your loadPyodide configuration to point to this directory:
const pyodide = await loadPyodide({
indexURL: "/wheels/", // or the correct path to your directory
});
This tells Pyodide where to find the package metadata. Now you can simply use await pyodide.loadPackage("scipy");
micropip.install("scipy")) it works. When loading from my own http sever I receive the error.