Python in the browser?

I like Python and dislike JavaScript.

Unfortunately it seems like you can’t avoid JS if you want
your code to run in the browser.

I want to do some simple HTML/DOM/CSS fun, and it would
be very cool if I could use Python for it.

Do you have a solution?

1 Like

What have you tried?

https://duckduckgo.com/?q=python+in+the+browser

The first two links look good to me.

Do you mean simply running Python in a web-page, or do you mean running Python as your client-side web scripting?

The first link (Trinket) is a commercial service.

I am looking for an open source solution.

The second one (skulpt) tranlates to JavaScript. I will have a look at this.
But me feeling is that a wasm based solution would make more sense today.

I would like to do simple HTML/DOM manipulation, like jquery.

Sure, but please answer first the question of Laurie O first , (or your Private messages) , where will Python run and more specifically where is hosted the source code ?

manipulating the DOM can be done via websockets when python is remote eg https://github.com/amirouche/beyondjs, but if python is running inside the browser it needs an async framework + async RPC.
These are totally different ways and the last is quite complicated, why not then just use a web GUI framework like https://github.com/dddomodossola/remi/ ?

What private messages are you talking about?

Where is hosted the source code? The source code should be hosted where the developer wants it it. For example on github. I don’t care if python code gets transmitted from the server to the client. For example a wasm based solution would not transmit python code to the client. As long as I can execute my code inside the browser.

I see two ways: wasm or transpiling from Python to JS.

beyondjs: this transmits every dom event over the network from the client to the server. I think this will be much too slow.

remi: Python gets executed on the server side and creates HTML. This is roughly like django forms library. That’s cool, but not what I am looking for.

transpiling from Python to JS

that may lead to problems with refcounting when using python libraries that were designed with c-api. It happened here for example __del__ is not called · Issue #275 · brython-dev/brython · GitHub so asm.js (python2) and later wasm(py3) were choosen instead of transpilation.

if you are thinking of a bytecode only solution like eg only keep cpython VM, then it would not be Python but a subset of it because you would loose compile and eval : that’s good for size but …

But bytecode opcode map ( ceval.c ) is subject to change anytime each version so it’s a risky way with possibly multiple runtime maintenance ( for ever ?). I would choose to embed code in page or get it from a server like js but please without minifying :wink:

beyondjs

Right it is slow for remote dom, also probably very slow for webgl/canvas in a notebook as questionned there Status of WebGL port? · Issue #887 · panda3d/panda3d · GitHub

but maybe not if running Python client side, problem is running a worker or async and communicating with js host is not standardized yet.
One could hope for a decent -fast- serialization module both side first ( may CBOR - RFC 7049 ? ), and perhaps direct access to utf-8 strings in wasm heap.

I see you have found the privmsg, so please try and elaborate on what you need or would like to achieve first with a Python in the browser : it’s uncharted territory and each player on the field may have different objectives.

1 Like

Yes, I agree. It is the first time I see someone like OP that wants to (really?) do Python in the browser. Most people think Python in the browser will have the same properties as Qt or GTK dev. That is unlikely to happen and people have already tried. That is, even with a good Python implementation that runs in the browser, you will still need to learn CSS and browser API. Another misguided idea, is that Python in the browser must have a broad compatibility with existing Python packages and stdlib. That is wrong on some many ways, to get started most of the stdlib is backend specific, second even things like urllib would need to be re-implemented to make use of, again, browsers apis.

You could try pyodide, though as mentioned above you still would need to be aware of JS aspects in any case when running in the browser.

Another misguided idea, is that Python in the browser must have a broad compatibility with existing Python packages and stdlib. That is wrong on some many ways, to get started most of the stdlib is backend specific, second even things like urllib would need to be re-implemented to make use of, again, browsers apis.

I guess there are several ways of looking at it. For instance, pyodide mostly passes the CPython test suite, aside from tests involving threading, multiprocessing, sockets and other unsupported things in the WASM environment. Similarly one can install pure Python packages from PyPi and they would work assuming they don’t use too much of the above unsupported functionality. urllib etc yes would need re-implementing with browser APIs but potentially this could be done?

Thank you all for your answers.

Some days later I ask myself: Thomas, why not use JavaScript?

I use Python since 2001 (19 years). Of course Python is simpler and more clean…

But I think you can’t avoid JS at the moment, if you want to work with HTML in the browser.

I think I will have a look at JavaScript, TypeScript and React.

In the case of urllib it is not possible to re-implement it in the browser without performance trade-off via web workers or introducing something like call/cc that would allow to use an async API like browser’s fetch, like a sync API as it is the case of urllib that does not rely on async / await.

IIRC @pmp-p has a prototype implementation that allows to make “async look sync” without async / await (and without call/cc).

Again, looking up the top 10 or 20 or even 100 projects on pypi, I see nothing that would be useful in browser setting.

That includes numpy et al. I still do not understand what is the point of compiling numpy to wasm to run it the browser. Also, having the same API is very neat, but we can not just pile up compilation steps and call it day. Every day hardware improves, but software eats twice the improvement. That is to say, performance matters, if numpy is needed browser side, it would be best to implement the same API with a dedicated web assembly implementation. :green_heart: There is plenty of time to re-implement numpy, but there is a limited set of natural ressource, not mentioning other performance benefits.

Good call as software engineering practioner that wants to learn the way of the craft and produce working and maintainable software today. But ultimatly, nothing will beat the ability to use the same language for frontend, backend and beyond.

What we need is a good implementation of Python language with very good Foreign Function Interface with javascript and / or web assembly. This is a lot of work, but future ourselfs will be thankful.

1 Like

BTW, I discovered htmx, now I realized that JS is overrated. I sent html fragements over the wire now, and keep the state on the server. Works fine up to now, and this way I can avoid JS, and work with the things I like (Python, HTML, CSS).

history note: htmx is how XHR aka. AJAX was used before JSON was cool.

What about dragndrop, what about image editing, what about realtime discussion that is anything that requires low latency.

What about dragndrop, what about image editing, what about realtime discussion that is anything that requires low latency.

dragndrop: Don’t need it at the moment

realtime discussion: htmx supports websockets, should work fine.

low latency: Do you think it is slow to transfer html fragments over the wire? Why should json be faster?

One use case is teaching. For instance, if you have to teach Python with numpy to more than a few 1k to 10k users, without them having to install anything, it’s going to be both challenging and costly to run that infrastructure. There is Binder but someone has to pay the compute time. With Python + numpy in the browser you can do that at low cost and effort. For instance, Pyodide is getting used more frequently in high school education lately for this reason (for now without numpy).

i like pyodide but
@rth ( you know i do) but it’s still a cpython “vm in a vm in the browser” and so suggest Minifying the stdlib (in Pyodide)

Honestly i think jslinux can load x86 or riscv cpython from vfsync faster than pyodide-wasm alone, it’s not “Python in the browser” as straight as possible but more “get cPython there” at any cost.

1 Like

@pmp-p jslinux is certainly an impressive project! Loading – possibly, it does feel quite fast. For Python performance though I’m not sure. With the following very basic code (which is by no means a trustworthy benchmark, and Python versions are not exactly the same either),

>>> from time import time
>>> t0 = time(); len([el**2 for el in range(100_000)]); time() - t0

I get (lower is better),

so running Linux in WASM does seem to a significant amount of overhead. I agree that the whole situation with VM in VM is not ideal in any case.

That’s indeed for the loading part i gave you the hint for, definitively not execution :wink: but i did not want to pollute the other thread where the question was quite clear. but I mean it’s the initial loading times that troubles you not really the size ? addressing data inside a compressed archive is quite difficult so why not just address uncompressed stdlib randomly via ranges + index or at worst with xmlhttp requests ( i did that for Panda3D ). from what i’ve seen VFSync happens to just do it better than i think i did/could

edit/ i think browserfs library has a ready-made synchronous indexed-fs via XHR.

Well the idea so far so far was that reducing size would be good by itself (faster download, reduced CDN bandwidth) and it should benefit load time to some extent as well.

But you are right that there are likely smarter and more specific actions possible to do to improve the load time. Thanks for the pointers!