Skip to content

Commit daaad30

Browse files
Merge pull request #53 from Vitens/emscripten
Support for WASM with Emscripten
2 parents 6c9eee1 + db0f2eb commit daaad30

13 files changed

Lines changed: 349 additions & 109 deletions

File tree

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# This workflow installs dependencies, lints, and runs tests across OS runners
2+
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-python
3+
4+
name: Python package
5+
6+
on:
7+
push:
8+
branches: [ "master" ]
9+
pull_request:
10+
branches: [ "master" ]
11+
12+
jobs:
13+
build:
14+
strategy:
15+
fail-fast: false
16+
matrix:
17+
os: [ubuntu-latest, windows-latest, macos-14]
18+
runs-on: ${{ matrix.os }}
19+
20+
steps:
21+
- uses: actions/checkout@v4
22+
- name: Set up Python 3.12
23+
uses: actions/setup-python@v5
24+
with:
25+
python-version: "3.12"
26+
architecture: ${{ matrix.os == 'macos-14' && 'arm64' || 'x64' }}
27+
- name: Install dependencies
28+
run: |
29+
python -m pip install --upgrade pip setuptools wheel
30+
python -m pip install flake8 pytest
31+
python -m pip install numpy scipy periodictable
32+
python -m pip install .
33+
- name: Lint with flake8
34+
run: |
35+
# stop the build if there are Python syntax errors or undefined names
36+
flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
37+
# exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide
38+
flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics
39+
- name: Test with pytest
40+
run: |
41+
pytest

.github/workflows/wheels.yml

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
name: Build wheels
2+
3+
on:
4+
workflow_dispatch:
5+
push:
6+
branches: ["master", "emscripten"]
7+
tags: ["v*"]
8+
9+
jobs:
10+
native-wheels:
11+
name: Native wheels (${{ matrix.os }})
12+
runs-on: ${{ matrix.os }}
13+
strategy:
14+
fail-fast: false
15+
matrix:
16+
os: [ubuntu-latest, windows-latest, macos-14]
17+
18+
steps:
19+
- uses: actions/checkout@v4
20+
21+
- uses: actions/setup-python@v5
22+
with:
23+
python-version: "3.12"
24+
25+
- name: Install build tooling
26+
run: python -m pip install --upgrade pip cibuildwheel
27+
28+
- name: Build wheels
29+
run: python -m cibuildwheel --output-dir dist
30+
env:
31+
CIBW_BUILD: cp312-*
32+
CIBW_SKIP: pp* *-musllinux_*
33+
CIBW_ARCHS_MACOS: arm64
34+
CIBW_ENVIRONMENT_MACOS: MACOSX_DEPLOYMENT_TARGET=26.0
35+
36+
- name: Upload native wheel artifacts
37+
uses: actions/upload-artifact@v4
38+
with:
39+
name: wheels-${{ matrix.os }}
40+
path: dist/*.whl
41+
42+
wasm-wheel:
43+
name: WASM wheel (Pyodide)
44+
runs-on: ubuntu-latest
45+
env:
46+
PYODIDE_EMSCRIPTEN_TAG: emscripten_3_1_58_wasm32
47+
48+
steps:
49+
- uses: actions/checkout@v4
50+
51+
- uses: actions/setup-python@v5
52+
with:
53+
python-version: "3.12"
54+
55+
- name: Install build tooling
56+
run: python -m pip install --upgrade pip build wheel
57+
58+
- name: Build wasm wheel
59+
run: python -m build --wheel
60+
env:
61+
PHREEQPYTHON_TARGET: wasm
62+
63+
- name: Retag wheel for Pyodide
64+
shell: bash
65+
run: |
66+
set -euo pipefail
67+
WHEEL_PATH=$(ls dist/*.whl)
68+
python -m wheel tags \
69+
--python-tag cp312 \
70+
--abi-tag cp312 \
71+
--platform-tag "${PYODIDE_EMSCRIPTEN_TAG}" \
72+
"${WHEEL_PATH}"
73+
rm -f "${WHEEL_PATH}"
74+
75+
- name: Upload wasm wheel artifact
76+
uses: actions/upload-artifact@v4
77+
with:
78+
name: wheels-wasm
79+
path: dist/*.whl
80+
81+
sdist:
82+
name: Source distribution
83+
runs-on: ubuntu-latest
84+
steps:
85+
- uses: actions/checkout@v4
86+
87+
- uses: actions/setup-python@v5
88+
with:
89+
python-version: "3.12"
90+
91+
- name: Install build tooling
92+
run: python -m pip install --upgrade pip build
93+
94+
- name: Build sdist
95+
run: python -m build --sdist
96+
97+
- name: Upload sdist artifact
98+
uses: actions/upload-artifact@v4
99+
with:
100+
name: sdist
101+
path: dist/*.tar.gz
102+
103+
pypi-publish:
104+
name: Publish to PyPI
105+
needs: [native-wheels, wasm-wheel, sdist]
106+
runs-on: ubuntu-latest
107+
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v')
108+
permissions:
109+
id-token: write
110+
steps:
111+
- name: Download wheel artifacts
112+
uses: actions/download-artifact@v4
113+
with:
114+
pattern: wheels-*
115+
path: dist
116+
merge-multiple: true
117+
118+
- name: Download sdist artifact
119+
uses: actions/download-artifact@v4
120+
with:
121+
name: sdist
122+
path: dist
123+
124+
- name: Show artifacts
125+
shell: bash
126+
run: ls -la dist
127+
128+
- name: Publish package distributions to PyPI
129+
uses: pypa/gh-action-pypi-publish@release/v1
130+
with:
131+
packages-dir: dist

.travis.yml

Lines changed: 0 additions & 11 deletions
This file was deleted.

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,9 @@ For more examples, take a look at the `examples` folder.
4242
* Using PhreeqPython on Windows requires installing [Visual C++ Redistributable 2015](https://www.microsoft.com/en-us/download/details.aspx?id=48145)
4343

4444
## Unit Tests
45-
| **Mac/Linux** | **Windows** | **Coverage** |
46-
|---|---|---|
47-
| [![Build Status](https://travis-ci.com/Vitens/phreeqpython.svg?branch=master)](https://travis-ci.com/Vitens/phreeqpython) | [![Build status](https://ci.appveyor.com/api/projects/status/lr1jwspxdkgo85bv?svg=true)](https://ci.appveyor.com/project/abelheinsbroek/phreeqpython) | [![codecov](https://codecov.io/gh/Vitens/phreeqpython/branch/master/graph/badge.svg)](https://codecov.io/gh/Vitens/phreeqpython) |
45+
| **Mac/Linux** and **Windows** | **Coverage** |
46+
|---|---|
47+
| [![Python package](https://github.com/DocMT/phreeqpython/actions/workflows/python-package.yml/badge.svg)](https://github.com/DocMT/phreeqpython/actions/workflows/python-package.yml)| [![codecov](https://codecov.io/gh/Vitens/phreeqpython/branch/master/graph/badge.svg)](https://codecov.io/gh/Vitens/phreeqpython) |
4848

4949

5050
## Acknowledgements

appveyor.yml

Lines changed: 0 additions & 19 deletions
This file was deleted.

phreeqpython/lib/viphreeqc.dylib

-259 KB
Binary file not shown.

phreeqpython/lib/viphreeqcwasm.so

2.06 MB
Binary file not shown.

phreeqpython/solution.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
from .equilibriumphase import EquilibriumPhase
77
from .gas import Gas
88

9-
from scipy.integrate import odeint
109
import numpy as np
1110

1211
class Solution(object):
@@ -160,6 +159,13 @@ def end(self):
160159

161160

162161
def kinetics(self, element, rate_function, time, m0=0, args=(), units='mmol'):
162+
try:
163+
from scipy.integrate import odeint
164+
except ImportError as exc:
165+
raise ImportError(
166+
"kinetics requires scipy. Install with "
167+
"'pip install phreeqpython[kinetics]' or install scipy manually."
168+
) from exc
163169

164170
def calc_rate(y, t, m0, *args):
165171
temp = self.copy()

phreeqpython/viphreeqc.py

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ def bytes(str_, encoding): #pylint: disable-msg=W0613
1515
"""Compatibilty function for Python 3.
1616
"""
1717
return str_
18-
range = xrange #pylint: disable-msg=C0103
18+
range = xrange #pylint: disable-msg=C0103 # noqa: F821
1919
#pylint: enable-msg=W0622
2020

2121

@@ -39,15 +39,27 @@ def __init__(self, dll_path=None):
3939
"""
4040
if not dll_path:
4141
if sys.platform == 'win32':
42-
dll_name = './lib/VIPhreeqc.dll'
42+
dll_names = ['./lib/viphreeqc.dll', './lib/VIPhreeqc.dll']
4343
elif 'linux' in sys.platform:
44-
dll_name = './lib/viphreeqc.so'
44+
dll_names = ['./lib/viphreeqc.so']
4545
elif sys.platform == 'darwin':
46-
dll_name = './lib/viphreeqc.dylib'
46+
dll_names = ['./lib/viphreeqc.dylib']
47+
elif 'emscripten' in sys.platform:
48+
dll_names = ['./.libs/viphreeqc.so', './lib/viphreeqcwasm.so']
4749
else:
4850
msg = 'Platform %s is not supported.' % sys.platform
4951
raise NotImplementedError(msg)
50-
dll_path = os.path.join(os.path.dirname(__file__), dll_name)
52+
53+
module_dir = os.path.dirname(__file__)
54+
dll_path = None
55+
for dll_name in dll_names:
56+
candidate = os.path.join(module_dir, dll_name)
57+
if os.path.exists(candidate):
58+
dll_path = candidate
59+
break
60+
61+
if dll_path is None:
62+
dll_path = os.path.join(module_dir, dll_names[0])
5163
phreeqc = ctypes.cdll.LoadLibrary(dll_path)
5264
self.debug = False
5365
self.dll = phreeqc

setup.cfg

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
[bdist_wheel]
2+
root_is_pure = false

0 commit comments

Comments
 (0)