|
|
Subscribe / Log in / New account

Pyodide: Python for the browser

By Jake Edge
May 11, 2021

Python in the browser has long been an item on the wish list of many in the Python community. At this point, though, JavaScript has well-cemented its role as the language embedded into the web and its browsers. The Pyodide project provides a way to run Python in the browser by compiling the existing CPython interpreter to WebAssembly and running that binary within the browser's JavaScript environment. Pyodide came about as part of Mozilla's Iodide project, which has fallen by the wayside, but Pyodide is now being spun out as a community-driven project.

History

Iodide, introduced in 2019, was an effort to create an in-browser notebook for scientific exploration and visualization, akin to Jupyter and JupyterLab. In that introductory post, the mismatch between JavaScript and scientific computing was noted—most of the existing ecosystem is Python-based—which is where the idea for Pyodide came from:

When we started thinking about making the web better for scientists, we focused on ways that we could make working with Javascript better, like compiling existing scientific libraries to WebAssembly and wrapping them in easy to use JS APIs. When we proposed this to Mozilla’s WebAssembly wizards, they offered a more ambitious idea: if many scientists prefer Python, meet them where they are by compiling the Python science stack to run in WebAssembly.

Getting that working seemed like it would be a big project, but it took only two weeks for Mike Droettboom to get Python running in an Iodide notebook. Over the following months, he and others added support for the most popular Python scientific packages (many of which are implemented in C like the CPython interpreter), such as NumPy, Matplotlib, pandas, SciPy, and scikit-learn. There were concerns about the performance of Pyodide, but performance turned out not to be a barrier for the use case:

Running the Python interpreter inside a Javascript virtual machine adds a performance penalty, but that penalty turns out to be surprisingly small — in our benchmarks, around 1x-12x slower than native on Firefox and 1x-16x slower on Chrome. Experience shows that this is very usable for interactive exploration.

A month after the introduction of Iodide, Droettboom posted more details about Pyodide. It is built using Emscripten, which provides a way to compile C and C++ to WebAssembly, along with "a compatibility layer that makes the browser feel like a native computing environment". That layer is necessary for a tool like Python:

If you were to just take this WebAssembly and load it in the browser, things would look very different to the Python interpreter than they do when running directly on top of your operating system. For example, web browsers don’t have a file system (a place to load and save files). Fortunately, emscripten provides a virtual file system, written in JavaScript, that the Python interpreter can use. By default, these virtual “files” reside in volatile memory in the browser tab, and they disappear when you navigate away from the page. (emscripten also provides a way for the file system to store things in the browser’s persistent local storage, but Pyodide doesn’t use it.)

By emulating the file system and other features of a standard computing environment, emscripten makes moving existing projects to the web browser possible with surprisingly few changes.

In order to do useful work within the browser environment, programs need access to the Document Object Model (DOM) of the browser, which is provided by the JavaScript APIs available there. That means Python and JavaScript code need to work together in various ways. Most of the basic types (e.g. numbers, arrays, strings) can be relatively easily mapped between the languages, but Python treats the object and dict types as distinct, while JavaScript conflates them to a certain extent: all objects can be treated as dicts. To handle that difference, object types in both languages and dict types in Python are represented by proxies in the other language; that allows each language full access to the other's data types.

As an example of these proxies, the post talks about accessing the DOM object from Python as follows:

    from js import document
    x = document.getElementById("myElement")
The document object is a JsProxy type that handles the dispatch to the proper API call without Pyodide being directly involved:
All of this happens through proxies that look up what the document object can do on-the-fly. Pyodide doesn’t need to include a comprehensive list of all of the Web APIs the browser has.

Given the focus on large data sets in the kinds of processing often done by NumPy and the like, there is a need to provide an efficient multi-dimensional array type that can largely be shared between JavaScript and Python. Copying huge arrays between the two would be a major performance hit, but will also likely overtax the amount of memory available to the browser. So an array type that is stored on the heap shared between the two was created; the small, language-specific dab of metadata describing the array is all that needs to be copied.

Present

Fast-forward two years, and Pyodide has made a good deal of progress; it released version 0.17 on April 22. At the same time, it announced that the project is becoming independent, complete with a GitHub repository, a governance system that draws from that of CPython, and a code of conduct based on Rust's and incorporating pieces from others. Meanwhile, the Iodide project has been discontinued, but Pyodide is more than simply a part of Iodide at this point: "Pyodide has attracted a large amount of interest from the community, remains actively developed, and is used in many projects outside of Mozilla."

The 0.17 release has a number of interesting features. Support for Python asyncio has been added, so that Python coroutines can run in the browser event loop; a JavaScript Promise can be awaited in Python and vice versa with Python awaitables. Error handling has also been upgraded so that exceptions generated by Python can be caught in JavaScript; that can be done in the other direction, as well.

A new version of Emscripten has been adopted, which has helped shrink the size of the binaries needed ("the SciPy package shrank dramatically from 92 MB to 15 MB"). It has also helped on the performance side of things. Using the latest toolchain (including the LLVM backend) results in a 25-30% improvement in run times. Overall, 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."

As with most (all?) projects, Pyodide is looking for people interested in contributing in various ways. "There are many ways to contribute, including code contributions, documentation improvements, adding packages, and using Pyodide for your applications and providing feedback." There is a roadmap with some ideas of plans for the future.

As Mozilla's Dan Callahan said in a PyCon 2018 keynote, Python may be getting left behind because the platforms that people are using are changing. While laptops, desktops, and servers support Python just fine, many people are only using phones and tablets where Python is not really present. But there is a unifying platform across all of those devices (and, presumably, others that come down the road): the web. If Python wants to stay relevant, it needs a reasonable browser story; Pyodide may be part of the right path toward that end.


Index entries for this article
PythonWeb


to post comments

Pyodide: Python for the browser

Posted May 13, 2021 8:46 UTC (Thu) by jezuch (subscriber, #52988) [Link] (9 responses)

I have a vague recollection that Internet Explorer used to allow running scripts in other languages than JS, including Python. Obviously this was at a time when The Microsoft Way was to invent their own incompatible standard (JScript). A more generous way of looking at this was that "this was a time of experimentation and exploration" when it was not clear that Javascript would "win", so other languages seemed like a viable alternative.

But this recollection is very vague and may by completely untrue :)

Pyodide: Python for the browser

Posted May 13, 2021 9:49 UTC (Thu) by excors (subscriber, #95769) [Link] (8 responses)

My vague recollection (plus some brief fact-checking) of the IE6 era is that Internet Explorer shipped with support for JScript and VBScript. But the languages were implemented through the ActiveX Scripting system, which allowed third parties to add their own scripting engines that would run in IE and could access the DOM. ActiveState used that to provide PerlScript, and I think they also had PythonScript as part of their ActivePython distribution (though I can't find much evidence of that; but there is pywin32 which does similar nowadays). Then web sites could do <script language="perlscript">$window->document->write('Hello world!');</script> (assuming their users had installed the third party scripting engine).

That approach was relatively good for language diversity, but bad for browser diversity (because ActiveX Scripting was heavily tied into the Microsoft way of doing things and it was somewhere between infeasible and impossible for other browsers on other platforms to support those scripting engines). Then we swung the other way and everything was exclusively JavaScript. Now people have figured out how to compile other languages down into JS or WASM, so we get the best of both worlds - web developers can choose between multiple competing languages and pick whichever's best for their requirements, while browser developers still only have to implement one language in order to support every web site.

Pyodide: Python for the browser

Posted May 15, 2021 1:34 UTC (Sat) by rsidd (subscriber, #2582) [Link] (7 responses)

I think we do have Apple to thank for things like ActiveX dying. A small (at that time) but vocal community; a corporation that decided to push its own browser (Safari) with opensource engine (webkit) that lacked ActiveX etc but had so many other advantages. Meanwhile, in those days, Linux had a dying closed-source Netscape, a slow and bloated open-source Mozilla, a nascent Firefox (then called Phoenix), and KDE's Konqueror (whose engine, khtml, Apple adopted for webkit).

I'd date the slide of IE from that time. Apple built a better browser. Then Google came and built on top of webkit too, and eventually forked it. Independently, Firefox (my main browser) grew to be a solid alternative.

Apple is also to be credited for the death of Flash.

I don't use Apple products, but it's good to have a heavyweight alternative around.

Pyodide: Python for the browser

Posted May 15, 2021 7:06 UTC (Sat) by roc (subscriber, #30627) [Link] (2 responses)

Safari didn't matter until the iPhone became big after 2007. Mac market share was too low to matter and nobody used Safari for Windows. Mozilla and Firefox were almost solely responsible for preventing an IE/ActiveX hegemony from 2001 to at least 2008. I'm sad that this is apparently being forgotten; I still think I'll be lucky if I'm involved in anything that important again in the rest of my life.

(* Arguably Microsoft's near-abandonment of IE was even more responsible, but they would have gotten away with it if there had been no viable competitor.)

I think it's also fair to say that Firefox was a better browser than IE and Safari for quite a long time. The Webkit team prioritized performance over correctness, which was probably a good strategy, but for a long time it was pretty bad if you cared about standards compliance and Web compatibility. (The Webkit team managed to obscure this by gaming tests like the Acid tests.)

FWIW I don't think Apple qua Apple really cared about IE market share. Infamously, when Safari for Windows launched, Jobs showed a slide of projected market share where Safari had taken all of Firefox's market share and IE's share was unchanged.

Pyodide: Python for the browser

Posted May 15, 2021 12:01 UTC (Sat) by rsidd (subscriber, #2582) [Link] (1 responses)

Um, Firefox didn't exist in 2001 and didn't pick up steam until years later!

You probably meant the Mozilla integrated browser. I remember Mozilla in 2001. Used it in Linux because there was little option. It was bloated, slow, crashy. Used Konqueror, even Lynx heavily as much as I could.

Pyodide: Python for the browser

Posted May 17, 2021 3:55 UTC (Mon) by roc (subscriber, #30627) [Link]

I meant Mozilla and Firefox. The Mozilla Suite wasn't great but it was the only real competition until Mozilla switched to Firefox (which really happened in 2002 although it took till 2004 to reach Firefox 1.0, at which point it was clear that IE was in trouble).

Pyodide: Python for the browser

Posted May 17, 2021 16:30 UTC (Mon) by rgmoore (✭ supporter ✭, #75) [Link] (3 responses)

I don't think you overestimate the importance of the US government winning an antitrust lawsuit against Microsoft. It really opened up space for alternative browsers. In a real sense, the web of today is a result of that lawsuit. People back in the '90s saw the browser as an alternative platform, and Microsoft was trying to strangle that by having a Windows-only, IE-only scripting language. The lawsuit blocked that. It's hard to imagine today's JS apps being where they are if Microsoft had won.

Pyodide: Python for the browser

Posted May 17, 2021 22:37 UTC (Mon) by rodgerd (guest, #58896) [Link] (2 responses)

Now we have a Chrome monopoly. Hurray!

Pyodide: Python for the browser

Posted May 18, 2021 4:26 UTC (Tue) by rsidd (subscriber, #2582) [Link] (1 responses)

But Chrome's engine (Blink) is open source and used by various other browsers, including Edge. And we have at least one independent browser (Firefox) which, in my experience, works with nearly everything out there including all Google services. (For some reason, it doesn't work with MS Teams. On the other hand, Cisco Webex works with Firefox and not with Chrome, at least on Linux.)

Chrome's monopoly isn't ideal but it's a lot better than IE's monopoly.

Pyodide: Python for the browser

Posted May 18, 2021 16:14 UTC (Tue) by rgmoore (✭ supporter ✭, #75) [Link]

I have had problems using Firefox with Google Meet, but other than that it seems to work fine with Google's services. And even in the rare cases where there are problems using web apps on Firefox, at least I can run Chrome on numerous operating systems. It's miles better than the situation in 2000, where ActiveX plugins worked only with IE and only on Windows.

Pyodide: Python for the browser

Posted May 14, 2021 9:56 UTC (Fri) by sam.thursfield (subscriber, #94496) [Link]

This is going to be a fantastic teaching resource.

Pyodide: Python for the browser

Posted May 23, 2021 13:45 UTC (Sun) by mitzampt (guest, #115256) [Link]

There is also https://brython.info Python 3 implementation with BSD License

Pyodide: Python for the browser

Posted Feb 27, 2024 17:29 UTC (Tue) by mscolnick (guest, #169938) [Link]

marimo's browser-based notebook runs on Pyodide: https://marimo.app/


Copyright © 2021, Eklektix, Inc.
This article may be redistributed under the terms of the Creative Commons CC BY-SA 4.0 license
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds