user6669602
user6669602

Reputation:

How do I call a python script when clicking a button (using pyscript)

I would like to run an Python script on Browser when clicking a button (on a html file). Something close to this:

<!DOCTYPE html>
<html>

<head>
<link rel="stylesheet" href="https://pyscript.net/alpha/pyscript.css" />
<script defer src="https://pyscript.net/alpha/pyscript.js"></script>
<py-env>
</py-env>
</head>

<body>

<button type="button" onclick="runPython()">run Python</button>

<script>
function runPython() { 

<py-script>
print("you clicked me")
</py-script>

}
</script>

</body>
</html>

Upvotes: 3

Views: 14808

Answers (3)

Iuri Guilherme
Iuri Guilherme

Reputation: 461

You can do it without the javascript's <script> and function. You already have pyscript. Change the onClick property of the button to pys-onClick and add an id property to the button, which you will then use in the python function pyscript.write('element-id', 'element-value', append=False):

<!DOCTYPE html>
<html>

<head>
<link rel="stylesheet" href="https://pyscript.net/alpha/pyscript.css" />
<script defer src="https://pyscript.net/alpha/pyscript.js"></script>
<py-env>
</py-env>
</head>

<body>

<button id="thebuttonid" type="button" pys-onClick="runPython">run Python</button>

<py-script>
def runPython(*args):
    pyscript.write("thebuttonid", "you clicked me")
</py-script>

</body>
</html>

This only works if the button with the pys-onClick has an id. The id provided to the pyscript.write function is the id of the element you want to write into. In this particular case it happened to be the same element you're calling the function from. The function needs to receive arguments (hence *args) because it is receiving a pyodide javascript proxy as argument. A full annotated version would be:

<py-script>
from pyodide import JsProxy
def runPython(proxy: JsProxy) -> None:
    """
    Writes 'you clicked me' in the html element with the id 'thebuttonid'.
    This function must be called from an element with the property pys-onClick='runPython'.
    """
    pyscript.write("thebuttonid", "you clicked me")
</py-script>

Now since you're using pyscript you can replace the regular html button with a py-button:

<py-button id="thebuttonid" label="run Python" type="button" pys-onClick="runPython"></py-button>

It'll get styled by tailwind css because you imported the css file at the header. Notice that you have to move the label to a property instead of using it as the value of the button.

Upvotes: 3

Nimit Gupta
Nimit Gupta

Reputation: 141

<html>
    <head>
      <link rel="stylesheet" href="https://pyscript.net/alpha/pyscript.css" />
      <link rel = 'stylesheet' href = "https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css">
      <script defer src="https://pyscript.net/alpha/pyscript.js"></script>
    </head>

  <body>
    <button id = "show_output" class = "btn btn-primary" type = "submit" pys-onClick="show_output">Show Output</button>
    <div id="output_div" style="margin-top: 10px;margin-bottom: 10px;"></div>
   
    <py-script> 
             
             def show_output(*args, **kwargs):
                output = Element("output_div")
                output.write("You Clicked Me!")
    </py-script>
  </body>
</html>

Upvotes: 4

John Hanley
John Hanley

Reputation: 81336

To call Python code from JavaScript requires creating a proxy. This proxy handles type (data) translation to and from JavaScript.

To create a proxy:

from js import document 
from pyodide import create_proxy

function_proxy = create_proxy(runPython)

Change your HTML element declaration to declare an ID and remove the onClick:

<button type="button" id="button">run Python</button>

Assign the proxy to an event listener for the button:

e = document.getElementById("button")
e.addEventListener("click", function_proxy)

This style is very similar to how JavaScript also assigns event listeners.

Put this together:

<body>

<button type="button" id="button">run Python</button>

<py-script>
from js import document 
from pyodide import create_proxy

def runPython():
    print("you clicked me")

function_proxy = create_proxy(runPython)

document.getElementById("button").addEventListener("click", function_proxy)
</py-script>

</body>

I wrote several articles on JavaScript and Python:

Upvotes: 11

Related Questions