Downloader#
We don’t want to download Pyodide every time we run a test or open a page. Let’s write a little downloader script and register it as a console app.
The Theory#
We want Pyodide locally. It’s cumbersome to download and extract, so we’ll automate it with a script.
We’ll store this in src/pyodide_components/pyodide
with an entry in .gitignore
to ensure it doesn’t get checked in.
Why under src
?
We’ll explain in a bit.
The Code#
We add the code to src/pyodide_components/downloader.py
:
"""Downloads Pyodide and extracts to correct place."""
from pyodide_components import HERE
"""Automation scripts for getting setup."""
import os
import tarfile
from pathlib import Path
from shutil import copytree, rmtree
from tempfile import TemporaryDirectory
from urllib3 import PoolManager
def get_pyodide():
print("Getting Pyodide")
base_url = "https://github.com/pyodide/pyodide/releases/download"
url = f"{base_url}/0.22.0a1/pyodide-0.22.0a1.tar.bz2"
http = PoolManager()
r = http.request('GET', url)
with TemporaryDirectory() as tmp_dir_name:
os.chdir(tmp_dir_name)
tmp_dir = Path(tmp_dir_name)
temp_file = tmp_dir / "pyodide.tar.bz2"
temp_file.write_bytes(r.data)
tar = tarfile.open(temp_file)
tar.extractall()
target = HERE / "pyodide"
if target.exists():
rmtree(target)
copytree(tmp_dir / "pyodide", target)
if __name__ == '__main__':
get_pyodide()
That code depends on HERE
.
Let’s add it to src/pyodide_components/__init__.py
:
from pathlib import Path
HERE = Path(__file__).parent
Running it#
It’s a function that is run from a __main__
block when you execute this in a virtual environment:
$ python -m pyodide_components.downloader
When run, it creates a directory at src/pyodide_components/pyodide
.
We should also add that directory to our .gitignore
:
src/pyodide_components/pyodide
Add node-fetch
dependency#
If you fire up the dev
server in package.json
, you’ll see a warning:
The following dependencies are imported but could not be resolved:
node-fetch (imported by /somepath/pyodide-components/src/pyodide_components/pyodide/pyodide.mjs)
Vite is doing some static analysis and notices that Pyodide’s JS depends on a package called node-fetch
.
We can silence this by installing it:
$ npm install -S node-fetch
Places for improvement#
We won’t spend too much time “hardening” this, as it is a just a means to an end. We could though:
Add these instructions to a README
Write a test with some mocks to prove the logic works
Not hard-coding the URL path and version