Pyodide: Python for the Browser
lwn.net
lwn.net
A sibling comment introduces JupyterLite and Brython, which are Jupyter-but-in-the-browser, whereas with Starboard I'm trying to create what Jupyter would have been if it were designed for the browser first.
As it's all static and in-browser, you can embed a notebook (or multiple) in a blog post, for instance to power interactive examples. The bundle size is a lot smaller than JupyerLite for the initial load - it's more geared towards fitting into existing websites than being a complete IDE like JupyterLab.
So roughly 1600x more clock cycles are consumed than is necessary.
I’m already jaded with the extreme bloat of JS frameworks as it is (how many times does my computer need to ramp up fans because of your React blog?). This could potentially be an order of magnitude worse.
Building a website or SPA entirely backed by Python seems like the wrong use of this technology. The same goes for crunching large amounts of data.
You wouldn't pull this in for a snappy, reactive UI driven by Python. You pull this in so that you can re-use a server-side module to perform some activity that isn't critical and so not worth re-writing in JavaScript. In another 5 years (assuming Python is still of interest and that this solution worked), it will have been refined and optimized where maybe you do reach for it by default.
There is very little boilerplate, and libraries are designed to hide what little there is.
So this means that mathematicians who hate verbosity can read and write their algorithms with little cognitive overhead.
Then you start to get the network effect where libraries are implemented or wrapped in Python, and people use those and start adding abstractions etc. The two main deep learning libraries (TensorFlow and PyTorch) are there, and those have huge gravity wells.
> performance since the 2019 announcement has improved greatly: "Performance ranges between near native to up to 3 to 5 times slower, depending on the benchmark."
In most places where performance matter Python packages would be using either C extension, Cython or numba to get near native performance. Pyodide is able to build those packages (except for numba). So overall it's currently 3 to 5 slower than native Python (which uses C extensions). See detailed benchmarks in https://hacks.mozilla.org/2021/04/pyodide-spin-out-and-0-17-...
(choose the pyolite option for Pyodide)
This project is actually quite impressive, I believe they've even gotten some pip install paths working??
Have you (any one else) succeeded?
Not being able to display plots seems a major limitation.
import matplotlib.pyplot as plt
plt.plot([1,2,3,4,5], [1,4,3,2,5])
plt.show()Try splitting cells on the first line and re-running the second.
I quickly get Recursion-Depth-Max errors.
PyOdide on GitHub: https://github.com/pyodide/pyodide
My motivation is that I’d like to run sandboxed Python scripts on the server, in a wasm runtime embedded in C.
AFAIU sandboxed embedded Python has been a bit of a Holy Grail for a long time. So if wasm gives an easy answer for it, that would be sweet!
I'm super excited about pyodide, although:
* I can't find a discord or IRC channel to ask questions, I guess the project is still young. Last time I've seen this project, it looked like a scientific software suite, which came with a lot of stuff I don't need.
* I wish there was more examples or samples, especially with events and the DOM.
* I've glanced at the doc and howtos, and it seems it requires a server, which I don't understand. Brython seems much more straightforward.
* I've read that memory leaks can happen in multiple places
* This example seems like misleading advertisement, in my view, at least for now:
from js import document
x = document.getElementById("myElement")
(Or I might need to read up more doc to understand how to get to that point)Yes, we are working on adding more examples.
Well you need to be able to serve static files. So if you are building locally you need to start a webserver, otherwise you can use the JsDelivr CDN.
Memory leaks can happen if you translate objects between Python and JS. So of it is unavoidable because it's difficult to know when to destroy Python objects from JS vice versa, but lots of work on it has been done in the 0.17 release with more to come in 0.18
Why do you find the example misleading?
I don't understand, can't I just use offline, static files ?
I would still expect to use my own webserver, unrelated to pyodine, like flask or whatever.
> Yes, we are working on adding more examples.
Glad to hear this :) !
> Why do you find the example misleading?
I haven't really seen that example in the doc or elsewhere, and I don't understand the steps required to make such example work offline or without a webserver.
EDIT:
Another cool thing of brython is that could "inline" a python script inside a html file, such as:
<script type="script/python">
or <script src="thing.py"></script>For inline code, yes it would be doable someone would need to continue https://github.com/pyodide/pyodide/pull/692
For examples, I'll respond in the Pyodide issue where you commented.
Thanks for the answers.
Cheers and good luck for this project, I can't wait for it to progress!
(although, python is my fav lang, and I wouldnt use brython either, 700ko to pay upfront before writing any code is too much)
I seriously question these benchmarks.
> performance since the 2019 announcement has improved greatly: "Performance ranges between near native to up to 3 to 5 times slower, depending on the benchmark."
edit: following some comments I want to add that the situation is symmetric IMO. I don't see the point in transpiling any of the two to the other.
You see more JS hate because it's a more common scenario that people happy with PHP/Python/Whatever would be exposed to JS later, than the other way around.
You see a bit more Python hate lately because ML is all the rage and Python is to ML what JS is to the web.
All mentioned languages having some weird backwards compatibility quirks doesn't help either.
I find it good that people are trying to port their favorite languages, although personally I'd stay on the happy path for the target platform. Especially the browser, as it already has weird APIs, JS or not.
Specifically, now that I'm very much OK with both python and JS I find transpiling one to the other kind of pointless in terms of any language property (can make sense in terms of ecosystem).
16 == [16]
true in js
false in python >>> a = 5
>>> b = 5
>>> a is b
True
>>> a = -4
>>> b = -4
>>> a is b
True
>>> a = 300
>>> b = 300
>>> a is b
False
Every language has these, JS a bit more (because mostly impossible to fix thanks to backward compatibility). I don't understand why you would do that anyway.Most linters would display errors even if you did (in both languages).
The is operator checks to see if both point to the same area in memory. Small numbers are preallocated in python so they point to the same memory.
>>>a=300
>>>b=a
>>>a is b
True
The point was that both languages have pitfalls.
It is a pitfall. It's not about what python developers think about it. It is about what people from other languages experience when they learn the language.
(Though it's not my main point, I want to add as (also) a python developer, that I think this is a terrible design choice, which could easily be avoided. In this case python doesn't "threat everything as object" it treats small int literals differently than bigger int literals)
Regardless, if, as you said, the operational semantics of the language is inconsistent among implementations and depends on internal caching, it only makes it worse.
false
https://github.com/adsharma/py2many/
Made a new release earlier today:
personally, i think pythons object model is extremely similar to js -- down to python essentially having prototypal inheritance
if you want to inherit from an object, just construct a class object from it using type().
Eg., at least, for any given object `me`,
type('ChildOfMe', (type(me),), vars(me))
But if you wanted a more literal dispatch to `me` you could create a proxy class which dispatched to a reference to `me`. type('ChildOfMe', (proxyclass(me),), {})
Where `proxyclass` is a function of the form, def proxyclass(obj):
class Proxy:
... dispatch to obj ...
return ProxyI suppose you could just say that classes are a particularly restricted sort of prototypes, and thus any class-based language is effectively prototype-based. But at that point "<OOP language> has prototype inheritance" is just tautological based on the set of definitions you've chosen.
Python is prototypal in just the same way js is: inheritance is a daisy-chain of references between objects.
JS is "maximally prototypal" if you like, where any object may be refernced. In python, only objects of type "type": but that isn't a big restriction, as shown.
- you can replace builtins in python. - you have __dunder__ methods and multiple inheritance. - JS has an ever running event loop and is async by default. - python is more strickly typed.
It's not impossible (see brython), but it's not easy either.
However, much appreciated.
It's perhaps interesting to note that browsers pretty much already implement this behaviour for js, ie., by spec everything is a float -- but vms don't start with a float type for much of the numeric data stored; and transparently move to it when needed.
Python descriptors are extremely flexible though, and I _guess_ you could emulate almost all of it through Javascript proxies, but I can't imagine the performance of that being great. Hash tables would also not be re-usable between JS and Python (since Python hash tables allow many more varieties of objects), and Python has a distinction between attributes and keyed access (which JS lacks).
Python exposes much more of the global environment and internals than JS does, and doesn't have some of the requirements JS has put on itself for security reasons. I'm not super sure you could emulate Python blocking style with a JS transformation statically. Blocking Python for something that is only available in a non-blocking JS environment would require effectively wrapping every Python operation (since almost every Python operation can have arbitrary side-effects).
I think there are people who write sort of syntax-y transpilers, but that's not really going to lead you down to nice code re-use.
(I'm one of the maintainers)
Pyodine => the cpython implementation, but compiled to wasm. It's very heavy (10Mo), but it brings the real, whole cpython implementation in the browser so it will behave the same and have the entire stdlib. It also comes with optional NumPy, Matplotlib, pandas, SciPy, and scikit-learn. Use it if you want people to write python in the browser, but don't want to expose your server to their code.
I feel Blazor WASM is a better choice in every way.
To elaborate : Blazor uses C#, is more performant, .NET 6 is bringing AOT for even better performance, has an ecosystem of tools to build sites with, integrated well into the .NET ecosystem, has a great set of libraries to choose from.
The main use case for pyiodine is running python without having to setup python.
If you don't want python, there is not need for it.
If you do want python, there is no replacement for it.
import sys
print(sys.version)
in each produced,https://www.programiz.com/python-programming/online-compiler...
"A module you have imported isn't available at the moment. It will be available soon." Really? sys?
https://www.online-python.com/
3.8.5 (default, Jul 20 2020, 23:11:29) [GCC 9.3.0]
https://replit.com/languages/python3
3.8.9 (default, May 3 2021, 02:40:41) [GCC 7.5.0]
The latter two, certainly, are adequate for class exercises and demonstrations. No idea if they are good enough for production of course, which Pyodide seems to be claiming.