Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
holoviz
GitHub Repository: holoviz/panel
Path: blob/main/scripts/build_pyodide_wheels.py
2004 views
1
"""
2
Script that removes large files from bokeh wheel and repackages it
3
to be included in the NPM bundle.
4
"""
5
6
import argparse
7
import os
8
import pathlib
9
import shutil
10
import subprocess
11
import zipfile
12
13
try:
14
import tomllib
15
except ModuleNotFoundError:
16
# Can be removed after 3.11 is the minimum version
17
import tomli as tomllib
18
19
from packaging.requirements import Requirement
20
21
PANEL_BASE = pathlib.Path(__file__).parent.parent
22
PACKAGE_INFO = tomllib.loads((PANEL_BASE / "pyproject.toml").read_text())
23
bokeh_requirement = next(p for p in PACKAGE_INFO['build-system']['requires'] if "bokeh" in p.lower())
24
bokeh_dev = Requirement(bokeh_requirement).specifier.prereleases
25
26
parser = argparse.ArgumentParser()
27
parser.add_argument("out", default="panel/dist/wheels", nargs="?", help="Output dir")
28
parser.add_argument(
29
"--no-deps",
30
action="store_true",
31
default=False,
32
help="Don't install package dependencies.",
33
)
34
parser.add_argument(
35
"--verify-clean",
36
action="store_true",
37
default=False,
38
help="Check if panel folder is clean before running.",
39
)
40
args = parser.parse_args()
41
42
if args.verify_clean:
43
# -n dry run, -d directories, -x remove ignored files
44
output = subprocess.check_output(["git", "clean", "-nxd", "panel/"])
45
if output:
46
print(output.decode("utf-8"))
47
msg = "Please clean the panel folder before running this script."
48
raise RuntimeError(msg)
49
else:
50
print("panel folder is clean.")
51
52
command = ["pip", "wheel", "."]
53
if bokeh_dev:
54
command.append("--pre")
55
56
if args.no_deps:
57
command.append("--no-deps")
58
command.extend(["-w", str(PANEL_BASE / "build")])
59
print("command: ", " ".join(command))
60
61
out = PANEL_BASE / args.out
62
out.mkdir(exist_ok=True)
63
print("out dir: ", out)
64
65
sp = subprocess.Popen(command, env=dict(os.environ, PANEL_LITE="1"))
66
sp.wait()
67
68
69
panel_wheels = list(PANEL_BASE.glob("build/panel-*-py3-none-any.whl"))
70
if not panel_wheels:
71
raise RuntimeError("Panel wheel not found.")
72
panel_wheel = sorted(panel_wheels)[-1]
73
74
with (
75
zipfile.ZipFile(panel_wheel, "r") as zin,
76
zipfile.ZipFile(out / os.path.basename(panel_wheel).replace(".dirty", ""), "w") as zout,
77
):
78
for item in zin.infolist():
79
filename = item.filename
80
if filename.startswith("panel/tests"):
81
continue
82
buffer = zin.read(filename)
83
if bokeh_dev and filename.startswith("panel-") and filename.endswith("METADATA"):
84
lines = buffer.decode("utf-8").split("\n")
85
lines = [
86
f"Requires-Dist: {bokeh_requirement}"
87
if line.startswith("Requires-Dist: bokeh")
88
else line for line in lines
89
]
90
buffer = "\n".join(lines).encode('utf-8')
91
zout.writestr(item, buffer)
92
93
bokeh_wheels = PANEL_BASE.glob("build/bokeh-*-py3-none-any.whl")
94
95
if not bokeh_wheels:
96
raise RuntimeError("Bokeh wheel not found.")
97
bokeh_wheel = sorted(bokeh_wheels)[-1]
98
99
zin = zipfile.ZipFile(bokeh_wheel, "r")
100
101
zout = zipfile.ZipFile(out / os.path.basename(bokeh_wheel), "w")
102
exts = [".js", ".d.ts", ".tsbuildinfo"]
103
for item in zin.infolist():
104
filename = item.filename
105
buffer = zin.read(filename)
106
if not filename.startswith("bokeh/core/_templates") and (
107
filename.endswith("bokeh.json") or any(filename.endswith(ext) for ext in exts)
108
):
109
continue
110
elif filename.startswith("bokeh-") and filename.endswith("METADATA"):
111
# Remove tornado dependency
112
buffer = "\n".join(
113
[
114
line for line in buffer.decode("utf-8").split("\n")
115
if "Requires-Dist: tornado" not in line
116
]
117
).encode("utf-8")
118
zout.writestr(item, buffer)
119
120
zout.close()
121
zin.close()
122
123
print(f"\nWheels where successfully written to {out}")
124
125