PyScript et al: Web-enabled Python

I know about the PyScript project for a while already. This end-of-year post is going to be about it and other lovely software pieces which enable Python on the Web these days ❤️

What is PyScript?

In a nutshell it’s a CSS + JS you can add to a webpage which will allow you to add Python code to the same web page. Seriously, it just works like magic:

PyScript in action

It’s possible to pass info back & forth between JS & Python as well as use JS APIs from Python code, e.g. do some DOM manipulations. Lovely, isn’t it?

Technically the primary enabler for the magic is WebAssembly aka Wasm: binary format which can be a portable compilation target. Basically it allows all kinds of programs created in various programming languages to be executed in browser at native speeds. It’s a fantastic piece of technology and I anticipate Wasm to be a key driver for interesting applications on the Web in upcoming years.

Next enabler is Pyodide: a port of CPython to Wasm. It makes execution of Python in browser possible as well as to install and run Python packages. <py-script> is a custom HTML element which acts as a bridge between browser and Pyodide.

PyScript is under heavy development but it’s already obvious that it has a great potential. What interesting stuff we can do with it right away?

What I hoped to achieve with PyScript

While I quit gaming for at least 1.5 years as of now I’ve been a gamer throughout a good part of my life. I also experimented with indie game development but without any significant success. Anyways I’m definitely not unindifferent to video games 🎮

Not long ago I bumped into a video guide on YouTube about making a game similar to DOOM. What was especially lovely about it is the fact that game was written in Python! Obviously a lot of heavy lifting was shifted to a gaming framework – PyGame. Here’s what the final result looks like:

DOOM via PyGame

Not bad, huh? And when I bumped into PyScript once again it clicked 💡

Video games traditionally were problematic to distribute via Web due to a few key problems:

  • Computational intensiveness what usually leads to the direct as possible access to hardware for the best performance. That contradicts sandboxed nature of code execution in browsers.
  • Large download size due to tons & tons of various assets (textures, sounds etc).
  • Limited support of OS APIs in browsers in general and access to video cards APIs (DirectX / OpenGL) in particular.

Wasm was a game-changer here as it enabled engines previously targeting native-only setup. By using tools like Emscripten even mighty Unreal Engine made it to the web! WebGL helped a lot on this front too. It’s a separate topic in regards to why we don’t see a wide adoption of web distribution for games yet, though.

Anyways I decided to try running the DOOM clone on the web as PyScript promised something like that, right?

How to make it work

Well, not quite =) Actually I anticipated problems right from the start. Due to the complexity of gaming projects and how hardware demanding they are there could be all kinds of hoops to jump through along the way.

I haven’t had to jump a lot, though. It was straightforward that PyGame isn’t supported by Pyodide yet. However, PyGame contributors made their own way with pygbag and python-wasm-sdk!

This toolchain is already pretty decent and with a few hiccups I arrived here:

pygbag in action

The framerate was terrible, though, in comparison to executing directly on host. I’m pretty sure there should be ways to optimize that, however, for the purpose of this research just making it work was a big deal!

Hope you enjoyed a bit of Web-enabled Python with me. Merry Christmas & Happy New Year! 🎄