7

I have a Javascript code and wanted to implement python functions using Pyscript.

Simple Example:

let's say I have a function:

<py-script>
def addOne(a):
    value = int(a) + 1
    return(value)
</py-script>

and say I want to use this function in javascript:

<script>
let compute = addOne(12)
</script>

The issue here is that it will say "addOne()" function is not defined. I was wondering if there was a way to use pyscript python functions inside javascript?

Hanbin Go
  • 91
  • 4
  • 1
    Yes, and No. If you interface directly with Pyodide you can. However, Pyscript loads Pyodide for you, and I have not figured out how to get the Pyodide handle. More details on this page: https://pyodide.org/en/stable/usage/faq.html Once I have the solution, I will put that on my website. https://www.jhanley.com/category/pyscript/ – John Hanley May 17 '22 at 00:20

1 Answers1

1

PyScript use Pyodide for translating objects between JavaScript and Python. Such cross-call needs a proxy of the Python function in the JS scope. So, if you create a proxy of the Python function, you can set this proxy as a callback in an event listener in JS. See https://pyodide.org/en/stable/usage/type-conversions.html#call-js-from-py

Well, you cannot set arbitrary arguments to be passed in a JS event. However, the main point of calling Python is to handle some event, isn't it? E.g. you want to do something in Python when a button is clicked. If so, the event handler (your Python function through the proxy) gets the PointerEvent. Its currentTarget property tells you the clicked DOM element. By the attributes of the element, you can practically pass over any data you want.

<py-script>
import pyodide
import js

class myClass():
    def __init__(self):
        self.add_one_proxy = pyodide.create_proxy(self.add_one)
        js.document.getElementById('mybutton').addEventListener("click", self.add_one_proxy)
    
    def add_one(self, pointerEventObj):
        """Callback from JS when a button is clicked"""
        btn_elem = pointerEventObj.currentTarget
        data = btn_elem.getAttribute('data')
        js.document.getElementById('resultdiv').innerHTML = str(int(data)+1)
    
    def shutdown(self):
        self.add_one_proxy.destroy()

klass = myClass()
# Make sure in the program to keep holding a reference of klass ...
# do the whole program here
# When all done, call klass.shutdown()
</py-script>

<body>
    <button id="mybutton" data="12" />
    <div id="resultdiv">calculated data will come here on button click</div>
</body>
Netcreator
  • 104
  • 11