Interactive shells on Python.org


We’re really proud to announce that we’re providing a “Launch interactive shell” feature for the newly-redesigned Python.org website. We hope that the ease of just clicking on something on the site to try it out will help bring even more people over to The World’s Best Programming Language!

Light technical details after the pretty picture…

Drawing

PythonAnywhere is a platform as a service for Python developers. One of our neat features is that you can work on your code from anywhere, from a computer or a tablet, by starting up a Python or Bash command line inside your web browser. So it was easy for us to roll out a simplified version of the system that just provided a simple Python 3 console (using IPython) for anyone who wanted one, and make that available to Python.org.

So, how does it work?

Getting started

When your browser loads the main Python.org front page, a small bit of JavaScript runs. This pings a URL on the PythonAnywhere servers to check that our service is up and running – this allows us to rate-limit things if the number of visitors to the page gets beyond our abilities to handle new consoles. So far we’ve not had to do that, but it’s good for our peace of mind to have a way of pulling the plug in an emergency.

Assuming that the response says that all systems are go, the JavaScript displays a button above the code sample on the front page that says “Launch interactive shell”. That’s all for now. Starting a new console takes a certain amount of machine resources, so we don’t start one for every hit on the Python.org front page.

onclick=”…”

When you click the interactive shell, a bit more JavaScript is run. This injects an iframe into the document, sized to cover the code sample. The src of the iframe is a URL on PythonAnywhere’s servers. Without going into too much detail, hitting this URL creates a new “unregistered” user on our server cluster (one with very limited capabilities) and returns a load of HTML and JavaScript that displays a vt100 terminal emulator, and connects back using SockJS (which normally uses WebSockets) to one of our cluster of console servers.

The console server

Our console servers run Tornado. Specifically, they run a Tornado application that listens on port 443 for incoming TLS SockJS connections. When one comes in, it and the JavaScript on the front end do a short authentication exchange to make sure it’s from a real user (not super-important for the publicly-accessible consoles on Python.org, but much more important for our normal site). After the auth, the console server constructs a sandbox for the user. This involves setting up a filesystem, and enabling the various limitations for the user. The Tornado process then forks off a new Python process, runng as that user, chrooted into the filesystem. (For a more in-depth look at the Tornado server, check out this EuroPython talk by Giles Thomas).

And off and running

Once the chrooted Python process is up and running, the Tornado server just works to forward keystrokes from the browser down to the process, and results back from the process to the browser. The JavaScript vt100 in the browser handles all of the formatting.

That’s pretty much it for the overview! If there’s anything you’d like more details on, leave a comment below and we’ll respond there – or we’ll update the blog post if enough people are interested in the same bits.

comments powered by Disqus