Skip to content

Commit 9647098

Browse files
committed
Add script to build a standalone browser dist
1 parent 9072b4d commit 9647098

1 file changed

Lines changed: 98 additions & 0 deletions

File tree

build-browser-dist.sh

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
#!/bin/bash
2+
set -e
3+
4+
OPENFISCA_CORE_VERSION=43.2.1
5+
PACKAGE_NAME=openfisca_browser_dist
6+
PACKAGE_VERSION=0.1.0
7+
COUNTRY_PKG_PATH=openfisca_germany
8+
DIST_DIR=dist/browser
9+
10+
rm -rf vendored ${DIST_DIR}
11+
mkdir -p vendored ${DIST_DIR}
12+
13+
pip install --no-deps --target=vendored openfisca-core==${OPENFISCA_CORE_VERSION}
14+
cp -r ${COUNTRY_PKG_PATH} vendored/
15+
pip install --no-binary :all: --no-deps --target=vendored dpath pendulum strenum
16+
17+
# Minimal numexpr and psutil stubs for Pyodide as they don't have official builds but are needed for imports to work
18+
mkdir -p vendored/numexpr
19+
cat > vendored/numexpr/__init__.py <<EOF
20+
import numpy as np
21+
def evaluate(expr, local_dict=None, **kwargs):
22+
return eval(expr, {"np": np}, local_dict or {})
23+
EOF
24+
mkdir -p vendored/psutil
25+
cat > vendored/psutil/__init__.py <<EOF
26+
virtual_memory = lambda: None
27+
cpu_percent = lambda *a, **k: 0
28+
EOF
29+
30+
# Exclude web api as it is not needed for the purpose of this standalone server-free browser distribution
31+
cat > vendored/setup.py <<EOF
32+
from setuptools import setup, find_packages
33+
setup(
34+
name="${PACKAGE_NAME}",
35+
version="${PACKAGE_VERSION}",
36+
packages=[pkg for pkg in find_packages() if not pkg.startswith("openfisca_web_api")],
37+
include_package_data=True,
38+
)
39+
EOF
40+
41+
cat > vendored/MANIFEST.in <<EOF
42+
recursive-include openfisca_germany *.yaml
43+
recursive-include openfisca_germany *.json
44+
EOF
45+
46+
(cd vendored && python3 -m build --wheel --outdir ../${DIST_DIR})
47+
rm -rf vendored
48+
49+
cat > ${DIST_DIR}/index.html <<EOF
50+
<!DOCTYPE html>
51+
<html lang="en">
52+
<head>
53+
<meta charset="UTF-8" />
54+
<title>OpenFisca Standalone Browser</title>
55+
<script src="https://cdn.jsdelivr.net/pyodide/v0.28.0/full/pyodide.js"></script>
56+
</head>
57+
<body>
58+
<h2>OpenFisca Standalone Browser Demo</h2>
59+
<pre id="sim_code">
60+
from openfisca_core.simulation_builder import SimulationBuilder
61+
from openfisca_germany import CountryTaxBenefitSystem
62+
system = CountryTaxBenefitSystem()
63+
population = {
64+
"persons": {
65+
"Alice": {
66+
"salary": { "2025-07": 4000 },
67+
"age": { "2025-07": 30 }
68+
}
69+
}
70+
}
71+
sim = SimulationBuilder().build_from_entities(system, population)
72+
result = sim.calculate("basic_income", "2025-07")[0]
73+
f"Basic income for Alice in 2025-07: {result}"
74+
</pre>
75+
76+
<button id="run">Run</button>
77+
<pre id="output" style="background: lightyellow">Click to start</pre>
78+
<script>
79+
document.getElementById("run").onclick = async () => {
80+
const out = document.getElementById("output")
81+
out.textContent = "Loading Pyodide"
82+
const pyodide = await loadPyodide({ indexURL: "https://cdn.jsdelivr.net/pyodide/v0.28.0/full/" })
83+
out.textContent = "Preloading core packages"
84+
await pyodide.loadPackage([ "micropip", "numpy", "pyyaml", "typing-extensions", "sortedcontainers", "python-dateutil", "tzdata"])
85+
out.textContent = "Installing wheel"
86+
let code = \`
87+
import micropip
88+
await micropip.install("/dist/browser/openfisca_browser_dist-0.1.0-py3-none-any.whl")\`
89+
await pyodide.runPythonAsync(code.trim())
90+
out.textContent = "Running simulation"
91+
code = document.getElementById("sim_code").textContent
92+
const result = await pyodide.runPythonAsync(code.trim())
93+
out.textContent = result
94+
}
95+
</script>
96+
</body>
97+
</html>
98+
EOF

0 commit comments

Comments
 (0)