How to use my own python packages/modules with PyScript?
Question:
Question
I came across pyscript hoping to use it to document python code with mkdocs. I have looked into importing my own module. Individual files work. How do I import my own module using pyscript instead?
- Requirements for running the example:
- python package
numpy
($ pip install numpy
)
- python package
matplotlib
($ pip install matplotlib
)
- local webserver for live preview on localhost (eq.
$ npm install -g live-server
)
-
Below is an example that works with the ‘just import a python file’ approach, see line from example import myplot
.
-
When I change the line to from package.example import myplot
it is not working and I get the following error in firefox/chromium:
JsException(PythonError: Traceback (most recent call last): File "/lib/python3.10/site-packages/_pyodide/_base.py", line 429, in eval_code .run(globals, locals) File "/lib/python3.10/site-packages/_pyodide/_base.py", line 300, in run coroutine = eval(self.code, globals, locals) File "", line 1, in ModuleNotFoundError: No module named 'package' )
Any help is appreciated. I found this discussion on github, but I am lost when trying to follow.
Example
Folder structure
├── index.html
└── pycode/
├── example.py
└── package/
├── example.py
└── __init__.py
index.html
<!doctype html>
<html>
<head>
<script defer src="https://pyscript.net/alpha/pyscript.js"></script>
<link rel="stylesheet" href="https://pyscript.net/alpha/pyscript.css"/>
<py-env>
- numpy
- matplotlib
- paths:
- ./pycode/example.py
- ./pycode/package
</py-env>
</head>
<body>
<div id="lineplot"></div>
<py-script>
from example import myplot
import matplotlib.pyplot as plt
theta,r = myplot(4)
fig, ax = plt.subplots(
subplot_kw = {'projection': 'polar'}
)
ax.plot(theta, r)
ax.set_rticks([0.5, 1, 1.5, 2])
ax.grid(True)
pyscript.write('lineplot',fig)
</py-script>
</body>
</html>
example.py
import numpy as np
def myplot(val:int):
r = np.arange(0, 2, 0.01)
theta = val * np.pi * r
return theta,r
__init__.py
__all__ = [ 'example.py' ]
Intended result in the webbrowser
Answers:
The folder structure you want to achieve wasn’t possible in PyScipt Alpha – <py-env>’s paths
functionality was fairly limited. Thankfully, it is possible in PyScript 2022.12.1, the latest version at time of writing.
First, you’ll want want to point your <script> and <link> tags at the newest release:
<script defer src="https://pyscript.net/releases/2022.12.1/pyscript.js"></script>
<link rel="stylesheet" href="https://pyscript.net/releases/2022.12.1/pyscript.css"/>
<py-env> has been renamed <py-config> and its syntax is quite different. To load packages, the keyword is packages
:
<py-config>
packages = ['numpy', 'matplotlib']
</py-config>
Finally, to load your files into the in-browser file system in a structured way, you can make use of a fetch configuration, another new feature of <py-config>. Check out the use cases section of the py-config docs, in in particular example #6, which is similar to your situation:
<py-config>
packages = ['numpy', 'matplotlib']
[[fetch]]
files = ['__init__.py', 'example.py']
from = 'package'
to_folder = 'package'
</py-config>
So finally, your full working example looks like:
<!doctype html>
<html>
<head>
<script defer src="https://pyscript.net/releases/2022.12.1/pyscript.js"></script>
<link rel="stylesheet" href="https://pyscript.net/releases/2022.12.1/pyscript.css"/>
</head>
<body>
<py-config>
packages = ['numpy', 'matplotlib']
[[fetch]]
files = ['__init__.py', 'example.py']
from = 'package'
to_folder = 'package'
</py-config>
<div id="lineplot"></div>
<py-script>
from package.example import myplot
import matplotlib.pyplot as plt
theta,r = myplot(4)
fig, ax = plt.subplots(
subplot_kw = {'projection': 'polar'}
)
ax.plot(theta, r)
ax.set_rticks([0.5, 1, 1.5, 2])
ax.grid(True)
pyscript.write('lineplot',fig)
</py-script>
</body>
</html>
For more context on fetch configurations and how they work, see this writeup from the 2022.12.1 release blog post.
https://realpython.com/pyscript-python-in-browser/#modules-missing-from-the-python-standard-library
This page has in depth analysis of modules within pyscript
<body>
<py-env>
- matplotlib
- numpy
- paths:
- src/waves.py
</py-env>
<py-script>
import matplotlib.pyplot as plt
import numpy as np
import waves
time = np.linspace(0, 2 * np.pi, 100)
plt.plot(time, waves.wave(440)(time))
plt
</py-script>
</body>
You will need something as above with your own filenames.
The file path is relative to your HTML page
You also can’t import a package directly only modules, you may be able to use the above code and figure out a solution, or you could do:
You can’t load Python packages using paths, only modules. If you have a pure-Python package, then build a wheel distribution and host it with your other files or upload it to PyPI.
Question
I came across pyscript hoping to use it to document python code with mkdocs. I have looked into importing my own module. Individual files work. How do I import my own module using pyscript instead?
- Requirements for running the example:
- python package
numpy
($ pip install numpy
) - python package
matplotlib
($ pip install matplotlib
) - local webserver for live preview on localhost (eq.
$ npm install -g live-server
)
- python package
-
Below is an example that works with the ‘just import a python file’ approach, see line
from example import myplot
. -
When I change the line to
from package.example import myplot
it is not working and I get the following error in firefox/chromium:JsException(PythonError: Traceback (most recent call last): File "/lib/python3.10/site-packages/_pyodide/_base.py", line 429, in eval_code .run(globals, locals) File "/lib/python3.10/site-packages/_pyodide/_base.py", line 300, in run coroutine = eval(self.code, globals, locals) File "", line 1, in ModuleNotFoundError: No module named 'package' )
Any help is appreciated. I found this discussion on github, but I am lost when trying to follow.
Example
Folder structure
├── index.html
└── pycode/
├── example.py
└── package/
├── example.py
└── __init__.py
index.html
<!doctype html>
<html>
<head>
<script defer src="https://pyscript.net/alpha/pyscript.js"></script>
<link rel="stylesheet" href="https://pyscript.net/alpha/pyscript.css"/>
<py-env>
- numpy
- matplotlib
- paths:
- ./pycode/example.py
- ./pycode/package
</py-env>
</head>
<body>
<div id="lineplot"></div>
<py-script>
from example import myplot
import matplotlib.pyplot as plt
theta,r = myplot(4)
fig, ax = plt.subplots(
subplot_kw = {'projection': 'polar'}
)
ax.plot(theta, r)
ax.set_rticks([0.5, 1, 1.5, 2])
ax.grid(True)
pyscript.write('lineplot',fig)
</py-script>
</body>
</html>
example.py
import numpy as np
def myplot(val:int):
r = np.arange(0, 2, 0.01)
theta = val * np.pi * r
return theta,r
__init__.py
__all__ = [ 'example.py' ]
Intended result in the webbrowser
The folder structure you want to achieve wasn’t possible in PyScipt Alpha – <py-env>’s paths
functionality was fairly limited. Thankfully, it is possible in PyScript 2022.12.1, the latest version at time of writing.
First, you’ll want want to point your <script> and <link> tags at the newest release:
<script defer src="https://pyscript.net/releases/2022.12.1/pyscript.js"></script>
<link rel="stylesheet" href="https://pyscript.net/releases/2022.12.1/pyscript.css"/>
<py-env> has been renamed <py-config> and its syntax is quite different. To load packages, the keyword is packages
:
<py-config>
packages = ['numpy', 'matplotlib']
</py-config>
Finally, to load your files into the in-browser file system in a structured way, you can make use of a fetch configuration, another new feature of <py-config>. Check out the use cases section of the py-config docs, in in particular example #6, which is similar to your situation:
<py-config>
packages = ['numpy', 'matplotlib']
[[fetch]]
files = ['__init__.py', 'example.py']
from = 'package'
to_folder = 'package'
</py-config>
So finally, your full working example looks like:
<!doctype html>
<html>
<head>
<script defer src="https://pyscript.net/releases/2022.12.1/pyscript.js"></script>
<link rel="stylesheet" href="https://pyscript.net/releases/2022.12.1/pyscript.css"/>
</head>
<body>
<py-config>
packages = ['numpy', 'matplotlib']
[[fetch]]
files = ['__init__.py', 'example.py']
from = 'package'
to_folder = 'package'
</py-config>
<div id="lineplot"></div>
<py-script>
from package.example import myplot
import matplotlib.pyplot as plt
theta,r = myplot(4)
fig, ax = plt.subplots(
subplot_kw = {'projection': 'polar'}
)
ax.plot(theta, r)
ax.set_rticks([0.5, 1, 1.5, 2])
ax.grid(True)
pyscript.write('lineplot',fig)
</py-script>
</body>
</html>
For more context on fetch configurations and how they work, see this writeup from the 2022.12.1 release blog post.
https://realpython.com/pyscript-python-in-browser/#modules-missing-from-the-python-standard-library
This page has in depth analysis of modules within pyscript
<body>
<py-env>
- matplotlib
- numpy
- paths:
- src/waves.py
</py-env>
<py-script>
import matplotlib.pyplot as plt
import numpy as np
import waves
time = np.linspace(0, 2 * np.pi, 100)
plt.plot(time, waves.wave(440)(time))
plt
</py-script>
</body>
You will need something as above with your own filenames.
The file path is relative to your HTML page
You also can’t import a package directly only modules, you may be able to use the above code and figure out a solution, or you could do:
You can’t load Python packages using paths, only modules. If you have a pure-Python package, then build a wheel distribution and host it with your other files or upload it to PyPI.