Always a nice surprise to find my stuff on the front page. If you have any questions about Microdot, I'm here to answer them!
Tepix · 9m ago
I looked at your benchmark article. I would like to see how many requests per second these SoCs with your server can manage on a simple task (printing the current time) - both with http and https.
Cheers!
xrd · 5h ago
I really love this post. The author did a great job with their writeup, and that probably came from a clear presentation.
I'm fascinated by your approach where you used your own temperature and humidity monitors. Apologies if this is in the links in the article, but I wondered how you controlled your heating unit. The reason I ask is that I have a nest device talking to my AC unit, which means I'm locked into the Google ecosystem. It works well, but it doesn't connect to the Home Assistant system for everything else in the house. I would like to remove the Nest dependency, or at least have multiple ways I could start optimizing the power utilization of my AC unit.
miguelgrinberg · 5h ago
Thanks. The smart heating device in question is one that is fairly popular in Ireland, but I believe it isn't sold elsewhere. The brand is Climote (https://www.climote.ie/).
As part of the service, this controller gives you the option to send commands through an app, or by sending SMS (the device comes with a SIM card and gets its own mobile number). The commands would allow you to ask if the heating is running or not, to turn the heating on or off, and so on.
I first implemented the SMS interface with Twilio, but then found that the number of texts you can send to the device is capped. I don't remember what was the monthly allowance, but I reached it in a few days after querying the device every 15 minutes or so 24/7.
I then found a project on GitHub with the reverse-engineered API that the phone app used to send commands. So I then reimplemented the command logic using this API to be able to talk to the controller without limitations.
I'm not familiar with the Nest devices, but I'd suggest you do a search on GitHub to see if someone figured how to reverse-engineer its API.
xrd · 3h ago
Nest devices do integrate, sort-of, with Home Assistant. But, the process is to create an "app" inside the Nest + Google home automation ecosystem. It is an absolute mess and there is nothing to be gained by going into that Mordor. I tried to get it working, and gave up, but I would much rather use a device that is "hackable." That device you mentioned looks great, and does not appear to be available outside of Ireland, as you noted. But, I'm going to use that as an inspiration point and see if I can find something similar. Maybe that manufacturer has awareness of a US-based device provider, I'll contact them.
Really appreciate you sharing this work, really fun stuff!
HexDecOctBin · 3h ago
Why did you want the server to use Python? It seems simple enough to be easily be done in bare C.
miguelgrinberg · 3h ago
I wanted to use MicroPython for this. I have nothing against C, it is a language that I actually know and use for other projects, but I wanted the challenge to try to build something similar to Flask or FastAPI that could run well on small devices.
stavros · 4h ago
All these years later, and I can't get over the fact that Flask began as an April fool's joke, making fun of Bottle and other microframeworks. I guess the joke failed completely.
larodi · 4h ago
Joke is Python never made it a front end web language given how easy it was for JS to become a backend and how many of these Python frameworks actually copy off JS, even though Python is older and from a perspective - neater…
stavros · 4h ago
This makes no sense. Of course it's easier for a language in a browser to release an executable than a language with an executable to be embedded in a browser. Also, why are we even talking about JS?
NeutralForest · 4h ago
there are some efforts to compile python to webassembly so let's see who will have the last laugh!
high_priest · 3h ago
WebAssembly in a browser, is still JS.
cout · 5h ago
Sounds like this framework is comparable in size to the original Rails, which clocked in at under 1000 lines of code (microdot is 765 lines per the article).
I don't know if the original Rails would have run on mruby though (if it had existed at the time), and Rails certainly did a lot of things the author of microdot would have considered "dark magic".
Having pulled down a copy just now, the framework itself is 526 lines of PHP, and the sample site (a newsfeed that pulls from the BBC) is perhaps 300 lines in models and controllers. I use the framework to this day to serve out my blog and other small sites, seems to work well without getting in the way.
I would love to try this on my ESP32-C3 Super Mini, the small web framework on the small WiFi-capable microcontroller.
emil-lp · 6h ago
Microdot is apparently a Python web framework that runs on both CPython and MicroPython.
It is a single 765-line file with routing, JSON handling, cookies, streaming, and TLS. Created to provide a web server for IoT devices.
enkrs · 5h ago
It’s great on esp32 with MicroPython. Even has support for server sent events (SSE). Paired with htmx, SSE gives some fun intetactive web experience for iot devices - instant GPIO status indicators etc. Loved tinkering with it. The source code is very readable too.
I'm not sure there's anything "impossible" about how small this is. You don't really need a lot of lines of code to support routes, request and response and nothing else. If anything, 765 lines of code for this is quite a lot.
It also uses libraries for most "extensions" that are available, defeating the purpose and bending the claim that it's 1,700 lines of code including the extensions. Just jinja, one of the dependencies, is 18,000 lines of code. If that counts my Nanodot server which calls flask.app.run() is one line...
miguelgrinberg · 4h ago
To clarify this, note that the extensions are entirely optional, and unlike what you are saying, most do not require any dependencies.
The only two extensions that use dependencies are the one that adds template rendering, and the one that implements secure user sessions.
For templates, you can use Jinja on CPython (where you wouldn't normally have space issues), or the uTemplate library (https://github.com/pfalcon/utemplate) on MicroPython, which is quite small.
For secure sessions, on CPython you have to add PyJWT. On MicroPython you need to add the HMAC and JWT modules from the MicroPython standard library, which are not installed by default. These are also very small.
motorest · 4h ago
> I'm not sure there's anything "impossible" about how small this is. You don't really need a lot of lines of code to support routes, request and response and nothing else. If anything, 765 lines of code for this is quite a lot.
How do you explain why virtually all frameworks end up requiring an order of magnitude more LoC?
iLoveOncall · 4h ago
Because they support a lot more features?
I made a similar "framework" in PHP years back as an experiment and it was a couple hundred lines AT MOST.
motorest · 31m ago
> Because they support a lot more features?
Not necessarily. For example, some minimal web frameworks actually provide multiple routing strategies because different implementation strategy have tradeoffs.
illegally · 5h ago
Yeah, it's an over exaggeration to say "impossibly small", it's a pretty normal size for a minimal routing class...
Cheers!
I'm fascinated by your approach where you used your own temperature and humidity monitors. Apologies if this is in the links in the article, but I wondered how you controlled your heating unit. The reason I ask is that I have a nest device talking to my AC unit, which means I'm locked into the Google ecosystem. It works well, but it doesn't connect to the Home Assistant system for everything else in the house. I would like to remove the Nest dependency, or at least have multiple ways I could start optimizing the power utilization of my AC unit.
As part of the service, this controller gives you the option to send commands through an app, or by sending SMS (the device comes with a SIM card and gets its own mobile number). The commands would allow you to ask if the heating is running or not, to turn the heating on or off, and so on.
I first implemented the SMS interface with Twilio, but then found that the number of texts you can send to the device is capped. I don't remember what was the monthly allowance, but I reached it in a few days after querying the device every 15 minutes or so 24/7.
I then found a project on GitHub with the reverse-engineered API that the phone app used to send commands. So I then reimplemented the command logic using this API to be able to talk to the controller without limitations.
I'm not familiar with the Nest devices, but I'd suggest you do a search on GitHub to see if someone figured how to reverse-engineer its API.
Really appreciate you sharing this work, really fun stuff!
I don't know if the original Rails would have run on mruby though (if it had existed at the time), and Rails certainly did a lot of things the author of microdot would have considered "dark magic".
Having pulled down a copy just now, the framework itself is 526 lines of PHP, and the sample site (a newsfeed that pulls from the BBC) is perhaps 300 lines in models and controllers. I use the framework to this day to serve out my blog and other small sites, seems to work well without getting in the way.
> Migrating to Microdot 2
You gotta be kidding...
[1] https://bottlepy.org/docs/dev/
It is a single 765-line file with routing, JSON handling, cookies, streaming, and TLS. Created to provide a web server for IoT devices.
It also uses libraries for most "extensions" that are available, defeating the purpose and bending the claim that it's 1,700 lines of code including the extensions. Just jinja, one of the dependencies, is 18,000 lines of code. If that counts my Nanodot server which calls flask.app.run() is one line...
The only two extensions that use dependencies are the one that adds template rendering, and the one that implements secure user sessions.
For templates, you can use Jinja on CPython (where you wouldn't normally have space issues), or the uTemplate library (https://github.com/pfalcon/utemplate) on MicroPython, which is quite small.
For secure sessions, on CPython you have to add PyJWT. On MicroPython you need to add the HMAC and JWT modules from the MicroPython standard library, which are not installed by default. These are also very small.
How do you explain why virtually all frameworks end up requiring an order of magnitude more LoC?
I made a similar "framework" in PHP years back as an experiment and it was a couple hundred lines AT MOST.
Not necessarily. For example, some minimal web frameworks actually provide multiple routing strategies because different implementation strategy have tradeoffs.