PyScript <py-config> packages: offline wheel resolution missing
0 reputation · 30 Mar 2023, 19:54 UTC
0 reputation · 30 Mar 2023, 19:54 UTC
Goal: create a fully repeatable PyScript development environment that works without network access by pinning the PyScript runtime and declaring required pure‑Python packages in a <py-config> block.
Constraint: micropip, which resolves the packages list, can only fetch wheels from PyPI and requires an active connection; the current documentation does not describe an offline wheel cache, lockfile, or vendor directory that would allow the same package set to be installed in an air‑gapped setting.
Uncertainty: whether PyScript can be directed to a local directory of pre‑downloaded wheels or to use a lockfile to guarantee identical versions when offline.
<py-config> to pin versions for offline install?<py-config> can operate without network?<py-config> block does not accept a lockfile or a requirements.txt with exact hashes to pin versions for offline installs.<py-config> operates without network access.PyScript’s package installation is handled by micropip, which is designed to fetch pure‑Python wheels exclusively from the public PyPI index. The <py-config> schema exposes a packages array of package names (optionally with version specifiers) but provides no parameters for:
index-url or find-links style alternate repositoriesoffline, vendor, or cache-dir flags--require-hashes or a lockfileConsequently, every micropip.install() call requires a live connection to PyPI (or a compatible index that micropip knows how to query). The current PyScript documentation (as of the 2024‑2025 releases) does not describe any offline‑first workflow.
If you control the build pipeline, you can download the required wheels ahead of time and serve them alongside your HTML. Then, at runtime, use a custom micropip call that points to those local files:
<py-script>
import micropip
await micropip.install([
"./wheels/requests-2.31.0-py3-none-any.whl",
"./wheels/pydantic-2.5.3-py3-none-any.whl",
])
</py-script>Caveats: The wheel filenames must match PyPI naming conventions exactly. You must also include all transitive dependencies. This approach bypasses <py-config> entirely and requires you to manage the dependency graph yourself.
Run a lightweight PyPI mirror on the same air‑gapped network. Configure the browser to trust the mirror’s certificate (if HTTPS) and point micropip at it by monkey‑patching micropip.PYPI_URL before any install:
<py-script>
import micropip
micropip.PYPI_URL = "https://local-mirror.example.com/simple/"
await micropip.install(["requests", "pydantic"])
</py-script>This keeps the <py-config> declaration intact but still requires a network service inside the air‑gapped environment.
Build a custom Pyodide distribution that includes your required packages. The Pyodide project documents adding packages at build time. The resulting pyodide.js and .wasm files contain the packages, so no runtime installation is needed. This is the most robust offline strategy but requires maintaining a forked Pyodide build.
micropip.install('--help') (or check the micropip source) to confirm no --find-links or --index-url options exist.<py-config> TypeScript definitions (@types/pyscript or the PyScript repo) for any offline, vendor, or lockfile properties—none are present in the 2024‑2025 releases.Do you control the PyScript/Pyodide build pipeline, or must you use the official CDN releases? If you can build a custom Pyodide, option 3 (pre‑baked distribution) is the only fully supported offline path. If you are locked to the CDN, you must use the unofficial workarounds above and accept the maintenance burden.
Use comments to ask for clarification. Post a solution as an answer.
34,775 reputation · 30 Mar 2023, 23:33 UTC
As of PyScript 2024.x, the <py-config> [[fetch]] directive only stages files into the virtual filesystem — it does not register them as a micropip package index. The documented offline pattern is to pre-download pure-Python wheels (py3-none-any) with pip download --python-version 3.11 --platform py3-none-any --only-binary :all: -r requirements.txt, serve them from a local HTTP server, then call micropip.install(["http://localhost:8000/wheels/pkg-1.0.whl", ...]) from a <py-script type="module"> bootstrap block. This requires manual dependency ordering since micropip won't resolve transitive deps from local URLs. No lockfile or find-links support exists in <py-config> as of mid-2025; track pyscript/pyscript#1200 for updates.