OpenWrt & Python - a tale from a maintainer (part 1)
Tags: python, openwrt
Published: 2020-11-09 09:05:25

So, this is a sketch article I wrote for a blogger job I applied for. Thing is: I didn't try blogging all that much; no idea why... well I could probably identify a few ideas, but it would be too much work for this.

Anyway, I didn't get the job, nor do I know whether the job actually got filled, or whether it [probably] got lost/forgotten-about within that organization.

And now, the article itself:

---------------------------------

So, you've probably heard of OpenWrt... or probably you haven't and now your googling for it.

If you haven't heard of OpenWrt, you should know that it runs Python, and if you have heard of it [or you've googled it], you're probably wondering: "really?".

You may also be one of those people thinking "pfff, of course it runs Python, Python runs everywhere".

Well, the short answer is  "no, Python doesn't/can't [really] run everywhere", because, unfortunately it's too big for some systems.

OpenWrt can run on systems that run at about 200-400 Mhz and 32+ MB or RAM and 4-8 MB of flash storage. Admittedly, I haven't tried to validate all this recently; I do have an old router running OpenWrt from 2-4 years ago, and it's within these specs.

Like this one here, which I use on my desk [ TP-Link WR740N v4 ]:
You can read more about these on https://openwrt.org/toh/tp-link/tl-wr740n
This is running OpenWrt now, but it has 4 MB of flash, so CPython won't fit on this.
I used it to connect it to the ISP's WiFi in the living room, so that I have some ethernet cables around.
![IMG_0436](https://dev-to-uploads.s3.amazonaws.com/i/79gwt7jtjs8y4dqz2jzs.jpg)

I'm actually planning to setup the Linksys WRT1200AC, which has 128 MB of flash and 512 MB of RAM (w00h00).
Link: https://openwrt.org/toh/linksys/linksys_wrt1200ac
Python is definitely going to run on this :D
![IMG_0437](https://dev-to-uploads.s3.amazonaws.com/i/eblthrskzf4n4m8icrk7.jpg)
 

Quite possibly, someone reading this will jump-up quickly and say: "but there's micropython, and you can run Python on slower/smaller systems with it". And I'll say: "yeah, but that's an open debate". MicroPython is a really neat project for such small systems (even for microcontrollers) to run the Python language, but you'll find that a language can be closely tied to the interpreter you're using.

And MicroPython is not CPython [which is the reference for the language], hence the open debate: what is Python? is it the language? is it the interpreter? how much do you correlate the language with the interpreter ?...... and so on; this article won't cover this part.

So then, you're wondering: "why [C]Python on OpenWrt?".
Well, I was also wondering the same thing at some point in time.
Now I don't wonder about this anymore, I just try to be a good maintainer [on OpenWrt].
I've accepted the fact that there are things in life which are difficult to explain, and many of them exist because someone wanted them to exist.
And: people like Python, and want to run it on these systems.

So now the question is more like: "how do you get CPython running on these system?".
Python [2 or 3] is around ~15 MB for the interpreter with all Python standard libraries. And [like I said before] a router has 8 MB of flash storage; you could also consider putting it on 4 MB, but that's an extreme experiment.
Also, let's remember, you still need the OS and some basic shell + commands to fit along side CPython.

Well, the answer is: "you just package what you need from CPython + you compress it to store it on the flash".
Firstly, OpenWrt's filesystems are a bit special: stuff is stored in a compressed format. And the filesystems are pretty flat, they don't offer much information as desktop/server filesystems do.
Even the kernel is compressed. A typical compressed Linux kernel [nowadays] ranges around 2-4 MB.
[ If you're an embedded guy reading this, and already know this stuff already, and are probably bored about this part, you're in luck: I'm also wondering why you are reading this stuff and being bored by it ].

Also, you don't need everything in CPython to run it. Out of 15 MB of interpreter + libraries, you only need 2 - 3.5 MB [depending on version] to actually start it, and be able to do some minor operations with lists, dictionaries, loops, some basic math, etc.
If you compress that, you get ~750 KB - 1.1 MB.

Doing the math a bit: on an 8 MB flash, you get ~5 MB of used flash.
[ I obviously did some rounding here, so don't take these numbers too accurately. The math I did won't cure cancer or anything, so I can squeeze in some number rounding. ]

Now, usually what happens when the system boots up [with 5 MB of stuff on flash], all this gets uncompressed into RAM, and lives in RAM.
As you can probably guess, 32 MB or RAM is a really tight limit to fit an OS (like Linux) and CPython, but you can do it.
But, if you want to run a Python app without many worries, I'd recommend routers with 64+ MB or RAM.
[ At this point, I'm a reminded of my first computer
that had 1.2 GB of HDD, and that seemed a lot compared to older computers that had 3 MB of HDD, and now I sound like I'm old: ¯\_(ツ)_/¯ ]

But, size of CPython [or other Python interpreters] is not the only thing that matters here. Speed is also something to consider [in another article, if I get around to write it].