PyScript: is it possible to execute an uploaded Python script? - python

Is it possible to have a user upload an arbitrary Python script (that uses built-ins only, no external packages) and then execute it using PyScript?

You can use an HTML <input> element to upload the file, and use await file.txt() to get the source. Then there are a couple ways to execute the code.
Using Python's exec() method:
<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">
<input type="file" id="file-upload">
<py-script>
import js
from pyodide.ffi.wrappers import add_event_listener
async def upload_and_run(event):
file_list = event.target.files
first_item = file_list.item(0)
src = await first_item.text()
exec(src)
input_elem = js.document.getElementById("file-upload")
add_event_listener(input_elem, "change", upload_and_run);
</py-script>
Or, if you want the script to behave like a <py-script> tag, with pretty error handling and such, you could add source to a new <py-script> tag:
<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">
<input type="file" id="file-upload">
<py-script>
import js
from pyodide.ffi.wrappers import add_event_listener
async def upload_as_script_tag(event):
file_list = event.target.files
first_item = file_list.item(0)
src = await first_item.text()
newTag = js.document.createElement("py-script")
newTag.innerText = src
js.document.body.appendChild(newTag)
input_elem = js.document.getElementById("file-upload")
add_event_listener(input_elem, "change", upload_as_script_tag);
</py-script>
</body>

Related

Unable to import pypyodbc in pyenv

I made a python script that goes throught a sql serve gets presciption records then after cleaning up the data I query it based on two parameters, all of this works by itself but now I wanted to make this into a application that others can interact. So, I tried to make a py-script application.
The problem:
When I try to import the pypyodbc module which is what I use to access the sql server I get an error ValueError: Couldn't find a pure Python 3 wheel for 'pypyodbc'. You can use 'micropip.install(..., keep_going=True)' to get a list of all packages with missing wheels.
To solve this I tried the micropip method and install a pure python library but was not able to.
Here is the code:
<html>
<head>
<!--<link rel="stylesheet" href="https://pyscript.net/alpha/pyscript.css" />-->
<script defer src="https://pyscript.net/alpha/pyscript.js"></script>
<script type="text/javascript">
</script>
</head>
<body>
<py-env>
- pypyodbc
- pandas
</py-env>
<div>Type an sample input here</div>
<input type="text" id="test-input"/>
<input type="text" id="test-input2"/>
<button id="submit-button" type="submit" pys-onClick="my_function">OK</button>
<p id="test-output"></p>
<py-script>
def my_function(*args, **kwargs):
import pypyodbc
import pandas as pd
DRIVER_NAME='SQL SERVER'
SERVER_NAME=''
DATABASE_NAME=''
text = Element('test-input').element.value
text2=Element('test-input2').element.value
connection_string=f"""
DRIVER={{{DRIVER_NAME}}};
SERVER={SERVER_NAME};
DATABASE={DATABASE_NAME};
Trust_Connection=yes;
uid=;
pwd=;
"""
conn = pypyodbc.connect(connection_string)
sql_query="""
SELECT * FROM Visit_Prescription
"""
df_pres=pd.read_sql(sql_query,conn)
DRIVER_NAME='SQL SERVER'
SERVER_NAME=''
DATABASE_NAME=''
connection_string=f"""
DRIVER={{{DRIVER_NAME}}};
SERVER={SERVER_NAME};
DATABASE={DATABASE_NAME};
Trust_Connection=yes;
uid=;
pwd=;
"""
conn = pypyodbc.connect(connection_string)
sql_query="""
SELECT * FROM Visit_Diagnosis
"""
df_Dia=pd.read_sql(sql_query,conn)
df_pres=df_pres.drop(['drug_tradername','drug_form_package', 'scientific_code'], axis=1)
df_pres=df_pres.groupby(['permanent_visit_no','patient_visit_registered_date_time'])['drug_package_information'].apply(','.join).reset_index()
inner = pd.merge(left=df_Dia, right=df_pres, left_on='permanent_visit_no', right_on='permanent_visit_no')
inner=inner.drop(['patient_visit_basic_details_serial_no','permanent_visit_no','patient_visit_registered_date_time_x','diagdate','patient_visit_registered_date_time_y'],axis=1)
inner.drop_duplicates(inplace = True)
inner=inner.drop(['icd_principal_secondary','icd_code_description'],axis=1)
contain_values = inner[inner['icd_code'].str.contains('test-input')]
contain_values=contain_values[contain_values['drug_package_information'].str.contains('test-input2')]
pyscript.write('test-output',contain_values)
</py-script>
</body>
</html>
So, I need help in trying to figure out a way to import the pypyodbc library or even a new library that can access the microsoft sql server. I am very new to this and with pyscript being relatively new I am unable to find much information online. So, any and all help is welcome and much appreciated.

HTML Output in Pyscript

I was experimenting in Pyscript and I tried to print an HTML table, but it didn't work. It seems to delete the tags and mantain just the plain text.
Why is that? I tried to search online, but being a new technology i didn't find much.
This is my code:
<py-script>
print("<table>")
for i in range (2):
print("<tr>")
for j in range (2):
print("<td>test</td>")
print("</tr>")
print("</table>")
</py-script>
And this is the output I get:
I tried to replace the print() method with the pyscript.write() method, but it didn't work too.
I dig in source code pyscript.py
and at this moment works for me only code similar to JavaScript
For example this adds <h1>Hello</h1>
<div id="output"></div>
<py-script>
element = document.createElement('h1')
element.innerText = "Hello"
document.getElementById("output").append(element)
</py-script>
Full working code
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>PyScript Demo</title>
<!--<link rel="stylesheet" href="https://pyscript.net/alpha/pyscript.css" />-->
<script defer src="https://pyscript.net/alpha/pyscript.js"></script>
</head>
<body>
<div id="output"></div>
<py-script>
element = document.createElement('h1')
element.innerText = "Hello"
document.getElementById("output").append(element)
</py-script>
</body>
</html>
EDIT:
After digging in source code I found that pyscript.js runs function htmlDecode() which removes all tags from code in <py-script> (and probably it also removes tags when you load code from file) and this makes problem.
See Pyscript issue: [BUG] print() doesn't output HTML tags. · Issue #347 · pyscript/pyscript
Some workaround is to use some replacement - ie. {{ }} instead of < > in code - and later use code to replace it back to < >
print( "{{h1}}Hello{{/h1}}".replace("{{", "<").replace("}}", ">") )
or more universal - using function for this
def HTML(text):
return text.replace("{{", "<").replace("}}", ">")
print( HTML("{{h1}}Hello{{/h1}}") )
pyscript.write(some_id, HTML("{{h1}}Hello{{/h1}}") )
document.getElementById(some_id).innerHTML = HTML("{{h1}}Hello{{/h1}}")
Sometimes problem can be also pyscript.css which redefines some items and ie. <h1> looks like normal text.
One solution is to remove pyscript.css.
Other solution is to use classes from pyscript.css like in examples/index.html
<h1 class="text-4xl font-bold">Hello World</h1>
which means
print( HTML('{{h1 class="text-4xl font-bold"}}Hello{{/h1}}') )

Correct way of hard-coding html code in python script?

I have developed a web-based tool, and currently trying to make it python-launchable. I figured using CEFpython is probably the way to do it. I followed the tutorial here and wrote the following code:
from cefpython3 import cefpython as cef
import base64
import platform
import sys
import threading
import os
HTML_code = """
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<link href="static/css/main.css" rel="stylesheet" />
</head>
<body>
<div id="UI">
</div>
<div id="container"></div>
<script src="static/main.js"></script>
<script type="text/javascript">
function defineData(datainput){
console.log("start")
data = datainput;
var loc = window.location.pathname;
var dir = loc.substring(0, loc.lastIndexOf('/'));
console.log(loc);
console.log(dir);
Main();
}
</script>
</body>
</html>
"""
def html_to_data_uri(html):
html = html.encode("utf-8", "replace")
b64 = base64.b64encode(html).decode("utf-8", "replace")
ret = "data:text/html;base64,{data}".format(data=b64)
return ret
def main(config):
sys.excepthook = cef.ExceptHook # To shutdown all CEF processes on error
settings = {}
cef.Initialize(settings=settings)
browser = cef.CreateBrowserSync(url=html_to_data_uri(HTML_code),window_title="Test")
browser.SetClientHandler(LoadHandler(config))
cef.MessageLoop()
cef.Shutdown()
return
class LoadHandler(object):
def __init__(self, config):
self.config = config
def OnLoadingStateChange(self, browser, is_loading, **_):
"""Called when the loading state has changed."""
if not is_loading:
# Loading is complete. DOM is ready.
browser.ExecuteFunction("defineData", self.config)
unfortunately, unlike in the tutorial, my tool has to load a local .js file where the main function is defined (), and it seems if I code the html file this way, my working directory is not actually the directory where I call the script, but some strange place
the output of these lines are:
var loc = window.location.pathname;
var dir = loc.substring(0, loc.lastIndexOf('/'));
console.log(loc);
console.log(dir);
output:
text/html;base64,CjwhRE9DVFlQRSBodG1sPgo8aHRtbCBsYW5nPSJlbiI+Cgk8aGVhZD4KCQk8bWV0YSBjaGFyc2V0PSJ1dGYtOCI+CgkJPG1ldGEgbmFtZT0idmlld3BvcnQiIGNvbnRlbnQ9IndpZHRoPWRldmljZS13aWR0aCwgdXNlci1zY2FsYWJsZT1ubywgbWluaW11bS1zY2FsZT0xLjAsIG1heGltdW0tc2NhbGU9MS4wIj4KCQk8bGluayBocmVmPSJzdGF0aWMvY3NzL21haW4uY3NzIiByZWw9InN0eWxlc2hlZXQiIC8+CgkJPHN0eWxlIHR5cGU9InRleHQvY3NzIj4KCQkJKiB7CgkJCQkuYm9yZGV....
text
Could you help me finding the correct way of hard coding html code in python with the correct path? maybe I need to somehow set the path?
PS: I did try including the html code in a separate .html file, and it worked on Windows machines, but it seems MacOS doesn't like it. Since this tutorial did work on MAC, I'm trying to hard code the html part into the python script and hope it would work on both Windows and Mac
Well, the HTML document has been converted to the body of a data URI by html_to_data_uri, so the U[niversal]R[esource]L[ocator] (window.location) of the document isn't a location on a server, but the data URI itself (the "strange place" you mention).
Remember that URLs are a subset of URIs, and you passed the URI as a URL to CEF with:
browser = cef.CreateBrowserSync(url=html_to_data_uri(HTML_code),window_title="Test")
So, as long as you are using a data URI/URL, I don't think that window.location will be helpful. Instead, you could extract the HTML code into a separate .html file, and change that line to:
browser = cef.CreateBrowserSync(url="/path/to/that_html_file.html", window_title="Test")

How to redirect/render Pyodide output in browser?

I have recently come across the Pyodide project.
I have built a little demo using Pyodide, but although I've spent a lot of time looking at the source, it is not obvious (yet) to me how to redirect print output from python (other than modifying the CPython source), and also, how to redirect output from matplotlib.pyplot to the browser.
From the source code, FigureCanvasWasm does have a show() method with the appropriate backend for plotting to the browser canvas - however, it is not clear to me how to instantiate this class and invoke it's show() method or indeed, if there is another more obvious way of redirecting plots to canvas.
My questions therefore are:
How do I redirect print() messages
How do I force pyodide to plot matplotlib figures in the browser?
Here is my test page:
<!doctype html>
<meta charset="utf-8">
<html lang="en">
<html>
<head>
<title>Demo</title>
<script src="../../pyodide/build/pyodide.js"></script>
</head>
<body>
</body>
<script type="text/javascript">
languagePluginLoader.then(() => {
pyodide.loadPackage(['matplotlib']).then(() => {
pyodide.runPython(`
import matplotlib.pyplot as plt
plt.plot([1, 2, 3, 4])
plt.ylabel('some numbers')
#fig = plt.gcf()
#fig.savefig(imgdata, format='png')
print('Done from python!')`
);
//var image = pyodide.pyimport('imgdata');
//console.log(image);
});});
</script>
<html>
First of all let's see if we can get just anything to show up in the browser; e.g. a normal string. Python variables are stored in the pyodide.globals attribute. Hence we can take the python object from there and place it into a <div> element on the page.
<!doctype html>
<meta charset="utf-8">
<html>
<head>
<title>Demo</title>
<script src="../pyodide/pyodide.js"></script>
</head>
<body>
</body>
<script type="text/javascript">
languagePluginLoader.then(() => {
pyodide.runPython(`my_string = "This is a python string." `);
document.getElementById("textfield").innerText = pyodide.globals.my_string;
});
</script>
<div id="textfield"></div>
<html>
Now I guess we can do the same with a matplotlib figure. The following would show a saved png image in the document.
<!doctype html>
<meta charset="utf-8">
<html lang="en">
<html>
<head>
<title>Demo</title>
<script src="../pyodide/pyodide.js"></script>
</head>
<body>
</body>
<script type="text/javascript">
languagePluginLoader.then(() => {
pyodide.loadPackage(['matplotlib']).then(() => {
pyodide.runPython(`
import matplotlib.pyplot as plt
import io, base64
fig, ax = plt.subplots()
ax.plot([1,3,2])
buf = io.BytesIO()
fig.savefig(buf, format='png')
buf.seek(0)
img_str = 'data:image/png;base64,' + base64.b64encode(buf.read()).decode('UTF-8')`
);
document.getElementById("pyplotfigure").src=pyodide.globals.img_str
});});
</script>
<div id="textfield">A matplotlib figure:</div>
<div id="pyplotdiv"><img id="pyplotfigure"/></div>
<html>
I haven't looked into the backends.wasm_backend yet, so that may allow for a more automated way of the above.
When using the wasm backend, the canvas property of a figure is an instance of FigureCanvasWasm. Calling the show() method of the canvas should be sufficient to display the figure in the browser. Unfortunately a minor bug in the create_root_element() method of the canvas prevents the figure from being displayed. This method creates a div element that will contain the figure. It tries first to create an iodide output div element. If that fails a plain HTML div element is created. This element however is never appended to the document and remains therefore invisible.
Below are the lines of code from FigureCanvasWasm were it happens
def create_root_element(self):
# Designed to be overridden by subclasses for use in contexts other
# than iodide.
try:
from js import iodide
return iodide.output.element('div')
except ImportError:
return document.createElement('div')
The comment suggests the non-iodide code is a stub that needs to be extended, by overriding the method. This would require subclassing FigureCanvasWasm, installing it as a pyodide module and configuring matplotlib to use that backend.
There is a shortcut however, because python allows overriding a method of an instance, without modifying the class, as per question 394770. Putting the following code in your HTML document gives a figure in the browser
import numpy as np
from matplotlib import pyplot as plt
from js import document
x = np.linspace(0, 2*np.pi, 100)
y = np.sin(x)
f = plt.figure()
plt.plot(x,y)
# ordinary function to create a div
def create_root_element1(self):
div = document.createElement('div')
document.body.appendChild(div)
return div
#ordinary function to find an existing div
#you'll need to put a div with appropriate id somewhere in the document
def create_root_element2(self):
return document.getElementById('figure1')
#override create_root_element method of canvas by one of the functions above
f.canvas.create_root_element = create_root_element1.__get__(
create_root_element1, f.canvas.__class__)
f.canvas.show()
Initially the toolbar did not show icons. I had to download, unzip and install fontawesome alongside pyodide and include the following line in the header to get those
<link rel="stylesheet" href="font-awesome-4.7.0/css/font-awesome.min.css">
Edit:
About the first part of your question, redirecting the output stream to the browser, you could take a look at how it is done in pyodide's console.html.
It replaces sys.stdout by a StringIO object
pyodide.runPython(`
import sys
import io
sys.stdout = io.StringIO()
`);
Then run the python code (that can be completely oblivious to the fact that it is running in a wasm context)
pyodide.runPython(`
print("Hello, world!")
`);
Finally, send the contents of the stdout buffer to an output element
var stdout = pyodide.runPython("sys.stdout.getvalue()")
var div = document.createElement('div');
div.innerText = stdout;
document.body.appendChild(div);
To show print() calls form pyodide you can use the parameters on loadPyodide to redirect stdout:
var paragraph = document.getElementById("p");
pyodide = await loadPyodide({
indexURL : "https://cdn.jsdelivr.net/pyodide/v0.18.1/full/",
stdin: window.prompt,
stdout: (text) => {paragraph.textContent += text;},
stderr: (text) => {paragraph.textContent += text;}
});
https://github.com/pyodide/pyodide/blob/main/src/js/pyodide.js
I created a simple interactive shell for Python. Read my tutorial if you need more detailed information.
const output = document.getElementById("output")
const code = document.getElementById("code")
code.addEventListener("keydown", function (event) {
if (event.ctrlKey && event.key === "Enter") {
evaluatePython()
}
})
function addToOutput(s) {
output.value += `>>>${code.value}\n${s}\n`
output.scrollTop = output.scrollHeight
code.value=''
}
output.value = 'Initializing...\n'
// init pyodide
languagePluginLoader.then(() => { output.value += 'Ready!\n' })
function evaluatePython() {
pyodide.runPythonAsync(code.value)
.then(output => addToOutput(output))
.catch((err) => { addToOutput(err) })
}
<!DOCTYPE html>
<head>
<script type="text/javascript">
// this variable should be changed if you load pyodide from different source
window.languagePluginUrl = 'https://pyodide-cdn2.iodide.io/v0.15.0/full/';
</script>
<script src="https://pyodide-cdn2.iodide.io/v0.15.0/full/pyodide.js"></script>
</head>
<body>
Output:
</div>
<textarea id='output' style='width: 100%;' rows='10' disabled></textarea>
<textarea id='code' value='' rows='2'></textarea>
<button id='run' onclick='evaluatePython()'>Run</button>
<p>You can execute any Python code. Just enter something in the box above and click the button (or Ctrl+Enter).</p>
<div><a href='https://github.com/karray/truepyxel/demo.html'>Source code</a></div>
</body>
</html>
Here is the example for matplotlib. Note that this will load a bunch of dependencies which will take up to several minutes.
let python_code = `
from js import document
import numpy as np
import scipy.stats as stats
import matplotlib.pyplot as plt
import io, base64
def generate_plot_img():
# get values from inputs
mu = int(document.getElementById('mu').value)
sigma = int(document.getElementById('sigma').value)
# generate an interval
x = np.linspace(mu - 3*sigma, mu + 3*sigma, 100)
# calculate PDF for each value in the x given mu and sigma and plot a line
plt.plot(x, stats.norm.pdf(x, mu, sigma))
# create buffer for an image
buf = io.BytesIO()
# copy the plot into the buffer
plt.savefig(buf, format='png')
buf.seek(0)
# encode the image as Base64 string
img_str = 'data:image/png;base64,' + base64.b64encode(buf.read()).decode('UTF-8')
# show the image
img_tag = document.getElementById('fig')
img_tag.src = img_str
buf.close()
`
languagePluginLoader.then(()=>pyodide.runPythonAsync(python_code).then(()=>document.getElementById('status').innerHTML='Done!'))
<!DOCTYPE html>
<head>
<script type="text/javascript">
// this variable should be changed if you load pyodide from different source
window.languagePluginUrl = 'https://pyodide-cdn2.iodide.io/v0.15.0/full/';
</script>
<script src="https://pyodide-cdn2.iodide.io/v0.15.0/full/pyodide.js"></script>
</head>
<body>
Status: <strong id='status'>Initializing...</strong>
<br><br>
mu:
<input id='mu' value='1' type="number">
<br><br>
sigma:
<input id='sigma' value='1' type="number">
<br><br>
<button onclick='pyodide.globals.generate_plot_img()'>Plot</button>
<br>
<img id="fig" />
</body>
</html>

How to import library using Brython

I wish to import my own library in Brython. This page of the documentation purports to show how, by adding the appropriate directory to the python path, but I can't make it work because I can't make Brython import sys.
Here's the simplest example code from the first page of the Brython documentation:
<html>
<head>
<script src="../src/Brython3.2.8/brython.js"></script>
</head>
<body onload="brython()">
<script type="text/python">
from browser import document, alert
def echo(ev):
alert(document["zone"].value)
document['mybutton'].bind('click', echo)
</script>
<input id="zone"><button id="mybutton">click !</button>
</body>
</html>
And that works fine.
But if I try to import sys:
<html>
<head>
<script src="../src/Brython3.2.8/brython.js"></script>
</head>
<body onload="brython()">
<script type="text/python">
import sys
from browser import document, alert
def echo(ev):
alert(document["zone"].value)
document['mybutton'].bind('click', echo)
</script>
<input id="zone"><button id="mybutton">click !</button>
</body>
</html>
Then the html will display but the button will not do anything.
The Console on Chrome shows the following error:
brython.js:6929 XMLHttpRequest cannot load file:///C:/Users/XXXXXXXXX/XXXXXX/src/Brython3.2.8/Lib/sys.py?v=1476283159509. Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https, chrome-extension-resource.
$download_module # brython.js.6929
import_py # brython.js.6929
exec_module # brython.js.6929
etc etc
So, how can I import sys in brython, and/or how can I import my own library in python?
Thanks.
You need to include brython_stdlib.js in your html code. So your html should look like this:
<html>
<head>
<script src="../src/Brython3.2.8/brython.js"></script>
<script src="../src/Brython3.2.8/brython_stdlib.js"></script>
</head>
<body onload="brython()">
<script type="text/python">
import sys
from browser import document, alert
def echo(ev):
alert(document["zone"].value)
document['mybutton'].bind('click', echo)
</script>
<input id="zone"><button id="mybutton">click !</button>
</body>
</html>
Source Code : https://github.com/imvickykumar999/Brython/blob/master/index.html#L36
Deployed Code : https://imvickykumar999.github.io/Brython/
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Brython</title>
<script
type="text/javascript"
src="https://cdn.jsdelivr.net/npm/brython#3.8.9/brython.min.js">
</script>
<script
type="text/javascript"
src="https://cdn.jsdelivr.net/npm/brython#3.8.9/brython_stdlib.js">
</script>
<link
rel="stylesheet"
href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css"
integrity="sha384-9aIt2nRpC12Uk9gS9baDl411NQApFmC26EwAOH8WgZl5MYYxFfc+NcPb1dKGj7Sk"
crossorigin="anonymous">
</head>
<body onload="brython()">
<style>
body {
/* background-color: yellow; */
background-image: url(https://images.unsplash.com/photo-1573196872258-41425124bf5d?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1050&q=80);
/* background-repeat: no-repeat; */
}
</style>
<script type="text/python">
from browser import document
def calc(a, b, o):
d = { '+' : a+b,
'-' : a-b,
'*' : a*b,
'/' : a/b,
'%' : a%b
}
return f"({a}{o}{b})=({d[o]})"
a = float(input('Enter first number : '))
b = float(input('Enter second number : '))
o = input('Enter the Operator (+,-,*,/,%) : ')
document <= calc(a, b, o)
</script>
</body>
</html>
Brython cannot import from any Python package that is part of any Python installation on the user's computer. It works by transpiling to JavaScript and running in the browser's Javascript engine. It has no knowledge of any local Python installations, and does not require any such installations to exist.
To use Python's standard library
Add a script tag to include brython_stdlib.js as well as the base brython.js. Several CDNs provide this already.
The Brython implementation of the Python standard library does not match the reference implementation exactly. See the documentation for details on what is included and how it is organized.
Importing your own code from within the document
For organizational purposes, Python code within the HTML document can be split across multiple <script> tags. The id attribute for the tag gives a "module name" that can be used in import statements in other scripts, as long as that script has already executed. The documentation includes an example:
<script type="text/python" id="module">
def hello():
return "world"
</script>
<script type="text/python">
from browser import document
import module
document.body <= module.hello()
</script>
The browser will have loaded the first <script> tag first, creating a (JavaScript representation of) a Python module named module that contains the hello function. The second script tag will be able to import that module and use the function as usual in Python.
Importing your own code from the server
Make the files available in the appropriate place as described in the documentation. Brython's implementation of the import statement (equivalently, __import__ builtin function) will attempt to find the code on the server using AJAX.
Importing your own code as a compiled Brython package
As explained in the documentation, use the Brython package (pip install brython) to create a JavaScript file that represents the Python code. (For third-party libraries, also check if such a JavaScript file is already available from a CDN.)
Suppose we have a project that creates a package named example. Navigate to the folder that contains that package (either src or the project folder, according to how the project is organized), then run brython-cli make_package example.
This should generate a example.brython.js file. Put it somewhere on the server, and configure the server to host that file at a specific URL. Then add the corresponding tag to the client page source (or the template that generates that page).
After that it should be possible to import example, from example import ... etc. in the Brython code.
Alternately, use brython-cli modules, as described in the 'Optimization' section, to create a combined library JavaScript file representing the entire server-side part of the project.

Categories

Resources