Open aghasemi opened 2 years ago
I see, yes, probably making stlite run on the main thread instead of the worker is possible, so I would like to keep the discussion.
However, it is not much easy too. I mean, it takes some efforts because we probably need to implement 2 types of the Python code runner. See, for example in the source code of Shinylive, there are 2 separate classes; NormalPyodideProxy and WebWorkerPyodideProxy, which must take additional and maintenance efforts. So I would like to know what is the benefit if it become possible. Can you provide concrete examples about what is good if it is possible in Streamlit usage?
Consider the following example scenarios:
In all the above examples, all we need to do is to run one or a few lines of JS code, and get the results back into our Python script.
So how does Streamlit handle these scenarios? The only way I could find is to write a custom component to do these stuff, with a little bit of hacking. But that involves creating at least an extra HTML file with boilerplate and stuff, just to run one line JS.
So why not just use what is provided by Pyodide as a "Python" interface and have the JS interoperability in a seamless manner.?
Btw I just checked Panel's PyScript port and Pyodide's js
also works there. They may have done something simpler to achieve that. Here is an example:
<html>
<head>
<title>Panel Example</title>
<meta charset="iso-8859-1">
<link rel="icon" type="image/x-icon" href="./favicon.png">
<script type="text/javascript" src="https://cdn.bokeh.org/bokeh/release/bokeh-2.4.2.js"></script>
<script type="text/javascript" src="https://cdn.bokeh.org/bokeh/release/bokeh-widgets-2.4.2.min.js"></script>
<script type="text/javascript" src="https://cdn.bokeh.org/bokeh/release/bokeh-tables-2.4.2.min.js"></script>
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/@holoviz/panel@0.13.1/dist/panel.min.js"></script>
<link rel="stylesheet" href="https://pyscript.net/alpha/pyscript.css" />
<script defer src="https://pyscript.net/alpha/pyscript.js"></script>
<script src="https://unpkg.com/ml5@latest/dist/ml5.min.js"></script>
<style>
table { width: 500px;}
h1 {font-size: 30px}
</style>
</head>
<py-env>
- bokeh
- numpy
- panel==0.13.1
- paths:
- ./LICENSE
</py-env>
<body>
<div id="simple_app"></div>
<!--py-script src="panel.py" /-->
<py-script>
import js
print(f"Window width is {js.JSON.stringify(js.window.screen.width)}. ML5 version is {js.ml5.version}")
</py-script>
</body>
</html>
The only way I could find is to write a custom component to do these stuff,
That's true. I don't think it's a hack, but a "standard" way of Streamlit apps - Streamlit provides this versatile API to cover such a wide variety of usage.
I understand your point from kind of a practical/quick-use perspective, but my position is a bit more dogmatic; When developers need to do these things on Streamlit, they have to use the custom components, so I think if they need them on stlite, they should do the same too. There are some realistic reasons as follow;
Yet, as I wrote above, I understand your opinion is also persuasive. It's just a difference on what we put values. Let's keep this issue open. Anyway this takes some efforts and maintenance costs as written at https://github.com/whitphx/stlite/issues/152#issuecomment-1229487480 apart from my ideological statement above.
Pyodide's js also works there.
It looks like PyScript executes Pyodide in the main script, without creating a separate worker ( https://github.com/pyscript/pyscript/blob/f3157b377f843be4777124e591d1469723b5ec9f/pyscriptjs/src/components/pyconfig.ts#L65 ).
As you said, it's simpler architecture allowing accessing the js
module, but I wonder if there are performance problems.
With this design, the Pyodide process blocks the main UI thread.
Actually, there are already some components that meet these needs. For example, this post introduced a custom component to access the cookie.
Indeed, I had this specific problem (accessing cookies) and the solution you mentioned above didn't work.
I wrote a simple custom component to run arbitrary JS code and get the result. It solves cokkie access issues and many other use cases (GeoLocation, Sharing API, Clipboard copying,...). It also works with STLite.
I recently put it on PyPI. Hope it helps someone else too. Feedback largely appreciated: https://github.com/aghasemi/streamlit_js_eval
Hi, Running stlite on the main thread instead of the web worker makes the Pyodide
js
module usable, hence enabling interoeration between JavaScript and Python code. It can be assimple
as an argument to thestlite.mount(..)
function.