Unable to import a python package in Pyodide

Question:

I am trying to import a custom package in Pyodide but it is not working.

The directory structure is

index.html
package/
    __init__.py

And my index.html looks like this

<!DOCTYPE html>
<html>
  <head>
    <script src="https://cdn.jsdelivr.net/pyodide/v0.19.1/full/pyodide.js"></script>
  </head>
  <body>
    Pyodide test page <br />
    Open your browser console to see Pyodide output
    <script type="text/javascript">
      async function main() {
        let pyodide = await loadPyodide({
          indexURL: "https://cdn.jsdelivr.net/pyodide/v0.19.1/full/",
        });

        let mypkg = pyodide.pyimport("package");
        mypkg.main();
      }
      main();
    </script>
  </body>
</html>

Does anyone know why this might be happening?

I am getting the error

ModuleNotFoundError: No module named 'package'

Asked By: Sanskar Jethi

||

Answers:

I’m curious about the indexURL argument within the await loadPyodide() statement. You have already included the URL within your index.html’s head. Is it necessary to include it again within the call to await loadPyodide? The documentation shows loadPyodide() being called without any arguments at all, like this:

let pyodide = await loadPyodide();

https://pyodide.org/en/stable/usage/quickstart.html

Answered By: Amanda Woods

In the case of Pyodide, Python runs directly in the browser and as such, it cannot see files in your local file system. It can only import modules in the virtual file system provided by Emscripten.

As described in the Pyodide documentation, you would need to copy your files into the virtual file system for it to work. There are two possibilities,

  • Assuming it’s pure Python,
    1. create a Python wheel wheel out of your package
    2. make it accessible via web server. For instance, by placing the wheel in some local folder, and starting the Python web server with python -m http.server in this folder.
    3. Finally, install it with micropip by providing the URL,
    import micropip
    await micropip.install('<url-to-the-wheel.whl>')
    import your_package
    
  • The other solution is to
    1. to create a tar or zip archive with your package,
    zip -r package.zip package/
    
    1. serve it via some HTTP server (same as above)
    2. Downloading and extracting the archive as described in the documentation,
      await pyodide.runPythonAsync(`
         from pyodide.http import pyfetch
         response = await pyfetch("https://.../your_package.tar.gz") # .zip, .whl, ...
         await response.unpack_archive() # by default, unpacks to the current dir
      `)
      pkg = pyodide.pyimport("your_package");
      pkg.do_something();
      

      If you extract this archive to a different folder than the local folder, you would need to add it to sys.path for Python to find it.

Answered By: rth
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.