File
Blob: build/python_metadata.bzl
| 1 | # After updating this file, make sure to run "bazel mod tidy" |
| 2 | load("@bazel_lib//lib:base64.bzl", "base64") |
| 3 | load("@bazel_lib//lib:strings.bzl", "chr") |
| 4 | load("//:build/python/packages_20240829_4.bzl", "PACKAGES_20240829_4") |
| 5 | load("//:build/python/packages_20250808.bzl", "PACKAGES_20250808") |
| 6 | |
| 7 | def _chunk(data, length): |
| 8 | return [data[i:i + length] for i in range(0, len(data), length)] |
| 9 | |
| 10 | def hex_to_b64(hex): |
| 11 | s = "" |
| 12 | for chunk in _chunk(hex, 2): |
| 13 | s += chr(int(chunk, 16)) |
| 14 | return "sha256-" + base64.encode(s) |
| 15 | |
| 16 | PYODIDE_VERSIONS = [ |
| 17 | { |
| 18 | "version": "0.26.0a2", |
| 19 | "sha256": "fbda450a64093a8d246c872bb901ee172a57fe594c9f35bba61f36807c73300d", |
| 20 | }, |
| 21 | { |
| 22 | "version": "0.28.2", |
| 23 | "sha256": "c9f6dd067d119e50850849f7428e3c636ecbc2684a0d2ff992f3bd48a1062b6c", |
| 24 | }, |
| 25 | ] |
| 26 | |
| 27 | # This is the list of all the package metadata that we use. |
| 28 | # |
| 29 | # IMPORTANT: packages that are present here should never be removed after the package version is |
| 30 | # released to the public. This is so that we don't break workers using those packages. |
| 31 | # |
| 32 | # ORDER MATTERS: the order of the keys in this dictionary matters, older package bundles should come |
| 33 | # first. |
| 34 | _package_lockfiles = [ |
| 35 | PACKAGES_20240829_4, |
| 36 | PACKAGES_20250808, |
| 37 | ] |
| 38 | |
| 39 | # The below is a list of pyodide-lock.json files for each package bundle version that we support. |
| 40 | # Each of these gets embedded in the workerd and EW binary. |
| 41 | PYTHON_LOCKFILES = [meta["info"] for meta in _package_lockfiles] |
| 42 | |
| 43 | # Used to generate the import tests, where we import each top level name from each package and check |
| 44 | # that it doesn't fail. |
| 45 | PYTHON_IMPORTS_TO_TEST = {meta["info"]["tag"]: meta["import_tests"] for meta in _package_lockfiles} |
| 46 | |
| 47 | # Each new package bundle should contain the same packages as the previous. We verify this |
| 48 | # constraint here. |
| 49 | def verify_no_packages_were_removed(): |
| 50 | for curr_info, next_info in zip(_package_lockfiles[:-1], _package_lockfiles[1:]): |
| 51 | curr_pkgs = curr_info["import_tests"] |
| 52 | next_pkgs = next_info["import_tests"] |
| 53 | missing_pkgs = [pkg for pkg in curr_pkgs if pkg not in next_pkgs] |
| 54 | if missing_pkgs: |
| 55 | fail("Some packages from version ", curr_info["info"]["tag"], " missing in version", next_info["info"]["tag"], ":\n", " ", ", ".join(missing_pkgs), "\n\n") |
| 56 | |
| 57 | verify_no_packages_were_removed() |
| 58 | |
| 59 | def _bundle_id(*, pyodide_version, pyodide_date, backport, **_kwds): |
| 60 | return "%s_%s_%s" % (pyodide_version, pyodide_date, backport) |
| 61 | |
| 62 | def _add_integrity(entry): |
| 63 | for key, value in entry.items(): |
| 64 | if not key.endswith("_hash"): |
| 65 | continue |
| 66 | newkey = key.removesuffix("_hash") + "_integrity" |
| 67 | entry[newkey] = hex_to_b64(value) |
| 68 | |
| 69 | def _make_vendored_packages(entry): |
| 70 | if entry["name"] == "development": |
| 71 | return |
| 72 | vendor_tests = {} |
| 73 | for e in entry["vendored_packages_for_tests"]: |
| 74 | vendor_tests[e["name"]] = e |
| 75 | entry["vendored_packages_for_tests"] = vendor_tests |
| 76 | |
| 77 | def _check_pyodide_versions(version_info): |
| 78 | pyodide_versions = {ver["version"]: 1 for ver in PYODIDE_VERSIONS} |
| 79 | pyodide_versions["dev"] = 1 |
| 80 | for entry in version_info.values(): |
| 81 | if entry["pyodide_version"] not in pyodide_versions: |
| 82 | fail("Version %s of Pyodide not in PYODIDE_VERSIONS" % entry["pyodide_version"]) |
| 83 | |
| 84 | def _make_bundle_version_info(versions): |
| 85 | result = {} |
| 86 | for entry in versions: |
| 87 | name = entry["name"] |
| 88 | if name != "development": |
| 89 | entry["id"] = _bundle_id(**entry) |
| 90 | entry["real_pyodide_version"] = entry["pyodide_version"] |
| 91 | entry["feature_flags"] = [entry["flag"]] |
| 92 | entry["feature_string_flags"] = [entry["enable_flag_name"]] |
| 93 | if "packages" in entry: |
| 94 | entry["packages"] = entry["packages"]["info"]["tag"] |
| 95 | _add_integrity(entry) |
| 96 | result[name] = entry |
| 97 | _make_vendored_packages(entry) |
| 98 | |
| 99 | dev = result["development"] |
| 100 | |
| 101 | # Uncomment to test with development = 0.26.0a2 |
| 102 | # dev["real_pyodide_version"] = "0.26.0a2" |
| 103 | result["development"] = result[dev["real_pyodide_version"]] | dev |
| 104 | _check_pyodide_versions(result) |
| 105 | return result |
| 106 | |
| 107 | VENDORED_VERSION_INDEPENDENT = [ |
| 108 | { |
| 109 | # Downloaded from https://pub-25a5b2f2f1b84655b185a505c7a3ad23.r2.dev/beautifulsoup4-vendored-for-ew-testing.zip |
| 110 | "name": "beautifulsoup4", |
| 111 | "abi": None, |
| 112 | "sha256": "5aa09c5f549443969dda260a70e58e3ac8537bd3d29155b307a3d98b36eb70fd", |
| 113 | }, |
| 114 | { |
| 115 | "name": "pytest-asyncio", |
| 116 | "abi": None, |
| 117 | "sha256": "be25b788392d124cbdfbb9b3d13541da69a7b6b977bc9474dddaddeaab6421b4", |
| 118 | }, |
| 119 | { |
| 120 | "name": "python-workers-runtime-sdk", |
| 121 | "abi": None, |
| 122 | "sha256": "fc4fb50f73973c257277155b3cb113aa2cf68e9da8ef424ecb049b41bc463183", |
| 123 | }, |
| 124 | ] |
| 125 | |
| 126 | BUNDLE_VERSION_INFO = _make_bundle_version_info([ |
| 127 | { |
| 128 | "name": "0.26.0a2", |
| 129 | "released": True, |
| 130 | "pyodide_version": "0.26.0a2", |
| 131 | "pyodide_date": "2024-03-01", |
| 132 | "packages": PACKAGES_20240829_4, |
| 133 | "backport": "79", |
| 134 | "integrity": "sha256-LO3jNW3PXEiwHm10GgnssxwKw+v37KMGZBiBwjUReVk=", |
| 135 | "flag": "pythonWorkers", |
| 136 | "enable_flag_name": "python_workers", |
| 137 | "emscripten_version": "3.1.52", |
| 138 | "python_version": "3.12.1", |
| 139 | "baseline_snapshot": "baseline-61eedf943.bin", |
| 140 | "baseline_snapshot_hash": "61eedf9432d635bdf091b26efece020b3543429a609fad7af9e8d4de2ec44f47", |
| 141 | "numpy_snapshot": "ew-py-package-snapshot_numpy-v2.bin", |
| 142 | "numpy_snapshot_hash": "5055deb53f404afacba73642fd10e766b123e661847e8fdf4f1ec92d8ca624dc", |
| 143 | "fastapi_snapshot": "ew-py-package-snapshot_fastapi-v2.bin", |
| 144 | "fastapi_snapshot_hash": "d204956a074cd74f7fe72e029e9a82686fcb8a138b509f765e664a03bfdd50fb", |
| 145 | "vendored_packages_for_tests": VENDORED_VERSION_INDEPENDENT + [ |
| 146 | { |
| 147 | # Downloaded from https://pub-25a5b2f2f1b84655b185a505c7a3ad23.r2.dev/fastapi-312-vendored-for-ew-testing.zip |
| 148 | "name": "fastapi", |
| 149 | "abi": "3.12", |
| 150 | "sha256": "5e6e21dbeda7c1eaadb99e6e52aa2ce45325b51e9a417198701e68e0cfd12a4c", |
| 151 | }, |
| 152 | { |
| 153 | "name": "scipy", |
| 154 | "abi": "3.12", |
| 155 | "sha256": "787e45be6969a5609093b3df9cc2dba2afec9e10bace977f5045697cc329aa7c", |
| 156 | }, |
| 157 | ], |
| 158 | }, |
| 159 | { |
| 160 | "name": "0.28.2", |
| 161 | "released": True, |
| 162 | "pyodide_version": "0.28.2", |
| 163 | "pyodide_date": "2025-01-16", |
| 164 | "packages": PACKAGES_20250808, |
| 165 | "backport": "10", |
| 166 | "integrity": "sha256-k37ELtvRw8fd3QHsMgja0Tl+4QKP1qGTnNdjxUiqb2E=", |
| 167 | "flag": "pythonWorkers20250116", |
| 168 | "enable_flag_name": "python_workers_20250116", |
| 169 | "emscripten_version": "4.0.9", |
| 170 | "python_version": "3.13.2", |
| 171 | "baseline_snapshot": "baseline-4569679fb.bin", |
| 172 | "baseline_snapshot_hash": "4569679fb78a3c5c8dbfa73d57c61c6a5394617632fbac7b5873ba322c85463d", |
| 173 | "numpy_snapshot": "package_snapshot_numpy-60c9cb28e.bin", |
| 174 | "numpy_snapshot_hash": "60c9cb28e6dc1ea6ab38b25471ddaa315b667637c9dd6f94aceb2acc6519c623", |
| 175 | "fastapi_snapshot": "package_snapshot_fastapi-a6ccb56fe.bin", |
| 176 | "fastapi_snapshot_hash": "a6ccb56fe9eac265d139727d0134e8d6432c5fe25c8c0b8ec95252b13493b297", |
| 177 | "dedicated_fastapi_snapshot": "snapshot_a6b652a95810783f5078b9a5dbd4a07c30718acb4ff724e82c25db7353dd7f2d.bin", |
| 178 | "dedicated_fastapi_snapshot_hash": "4af6f012a5fb32f31a426e6f109e88ae85b18ee3dd131e1caaaad989cd962bbe", |
| 179 | "vendored_packages_for_tests": VENDORED_VERSION_INDEPENDENT + [ |
| 180 | { |
| 181 | "name": "fastapi", |
| 182 | "abi": "3.13", |
| 183 | "sha256": "955091f1bd2eb33255ff2633df990bedc96e2f6294e78f2b416078777394f942", |
| 184 | }, |
| 185 | { |
| 186 | "name": "shapely", |
| 187 | "abi": "3.13", |
| 188 | "sha256": "2e5c462cb32ee8697b3647dfc9d5c88dcdfd0702da34a2d7dc6b07b8090dd321", |
| 189 | }, |
| 190 | ], |
| 191 | }, |
| 192 | { |
| 193 | "real_pyodide_version": "0.28.2", |
| 194 | "name": "development", |
| 195 | "pyodide_version": "dev", |
| 196 | "pyodide_date": "dev", |
| 197 | "id": "dev", |
| 198 | "flag": "pythonWorkersDevPyodide", |
| 199 | "enable_flag_name": "python_workers_development", |
| 200 | }, |
| 201 | ]) |