Noggin: A simple web framework that will run on your esp8266 boards.

Discussion about programs, libraries and tools that work with MicroPython. Mostly these are provided by a third party.
Target audience: All users and developers of MicroPython.
Post Reply
larsks
Posts: 22
Joined: Mon Feb 13, 2017 5:27 pm

Noggin: A simple web framework that will run on your esp8266 boards.

Post by larsks » Wed Nov 15, 2017 10:29 pm

I was asking the other day (viewtopic.php?f=2&t=4036) about minimal http servers for MicroPython, but I didn't get any responses and I wasn't able to find anything suitable...so I've written my own, and I've made it available in case someone else finds it useful:

https://github.com/larsks/micropython-noggin

It supports both "Expect: 100-continue" headers from clients and chunked encoding, which means it will interoperate nicely with e.g., "curl".

It uses a simple and hopefully not surprising interface for mapping request URIs to functions using regular expressions, and it maps match groups in your routes to positional parameters in your functions:

Code: Select all

from noggin import Noggin

app = Noggin()

@app.route('/')
def index(request):
    return 'Here is some content for you'

@app.route('/doc/([^/]+)')
def get_doc(request, docid):
    if docid in documents:
        return documents[docid]
    else:
        raise HTTPError(404)

app.serve()
I've tried as much as possible to use memory-efficient i/o, so that you can serve and receive large files without running out of memory.

There is some simple demonstration code available at https://github.com/larsks/micropython-n ... es/demo.py that shows off most of the features. There is a slightly more involved demo available at https://github.com/larsks/micropython-n ... fileops.py that implements a simple http fileserver, with support for getting, putting, renaming, and deleting files. It also provides access to filesystem, memory, and network configuration information.

I'm running this on a Wemos D1 mini (clone), https://wiki.wemos.cc/products:d1:d1_mini, where it seems to be working fine so far.

SpotlightKid
Posts: 463
Joined: Wed Apr 08, 2015 5:19 am

Re: Noggin: A simple web framework that will run on your esp8266 boards.

Post by SpotlightKid » Wed Nov 15, 2017 11:21 pm

Seems very nice an clean!

A minor comment: instead of 'mimetype' I think 'content_type' (e.g. as a Response kwarg) would be more appropriate, given the example set by other similar APIs, since you're sending the value unmodified as the "Content-type" header:

http://werkzeug.pocoo.org/docs/0.12/wra ... seResponse

larsks
Posts: 22
Joined: Mon Feb 13, 2017 5:27 pm

Re: Noggin: A simple web framework that will run on your esp8266 boards.

Post by larsks » Wed Nov 15, 2017 11:28 pm

A minor comment: instead of 'mimetype' I think 'content_type' (e.g. as a Response kwarg) would be more appropriate, given the example set by other similar APIs, since you're sending the value unmodified as the "Content-type" header:
I went with "mimetype" because that's what the Flask Response object uses :). I don't really feel strongly about this, though, so if anyone else chimes in I will consider myself persuaded.

SpotlightKid
Posts: 463
Joined: Wed Apr 08, 2015 5:19 am

Re: Noggin: A simple web framework that will run on your esp8266 boards.

Post by SpotlightKid » Wed Nov 15, 2017 11:43 pm

flask.Response is just a thin wrapper for werkzeug.Response and doesn't override its init Method, so the comment I linked to in the API docs also applies to Flask: the mime_type argument gets special treatment for 'text/*' types, where the charset is appended. Your code doesn't do that.

https://github.com/pallets/flask/blob/3 ... ers.py#L12
https://github.com/pallets/flask/blob/3 ... rs.py#L177

larsks
Posts: 22
Joined: Mon Feb 13, 2017 5:27 pm

Re: Noggin: A simple web framework that will run on your esp8266 boards.

Post by larsks » Thu Nov 16, 2017 3:24 pm

I've made the change suggested in the previous comments.

I've also added a compatibility shim so that Noggin will run under CPython 3 in addition to MicroPython. This makes testing much easier, so there is now a small suite of tests included in the repository.

SpotlightKid
Posts: 463
Joined: Wed Apr 08, 2015 5:19 am

Re: Noggin: A simple web framework that will run on your esp8266 boards.

Post by SpotlightKid » Thu Nov 16, 2017 7:04 pm

I was playing around a bit with noggin under the unix port. Here are a few observations/tips:

1. You need to install the "socket" module from micropython-lib:

Code: Select all

micropyrthon -u upip micropython-socket
(The usocket module from the unix port does not support passing addresses as (host, port) tuples, so you need the wrapper from the micropython-socket module.)

2. In noggin/app.py replace the first line with:

Code: Select all

try:
    import json
except ImportError:
    import ujson as json
3. Install noggin with:

Code: Select all

mkdir -p "$HOME/.micropython/lib"
cp -r noggin "$HOME/.micropython/lib"
4. To make it easier to run the demos, you could add the following to the end of examples/demo.py:

Code: Select all

if __name__ == '__main__':
    import sys
    try:
        app.serve(80 if not sys.argv[1:] else int(sys.argv[1]))
    except KeyboardInterrupt:
        pass
Then start it with:

Code: Select all

micropython examples/demo.py 8000
... and open http://localhost:8000/help.

Have fun!

larsks
Posts: 22
Joined: Mon Feb 13, 2017 5:27 pm

Re: Noggin: A simple web framework that will run on your esp8266 boards.

Post by larsks » Fri Nov 17, 2017 2:36 am

1. You need to install the "socket" module from micropython-lib:
That's interesting! I didn't realize that different ports would have different modules installed by default. I also learned that at some point in the past I installed all of micropython-lib into ~/.micropython/lib on my development system, which is why I didn't run into that issue when using the unix port myself.

SpotlightKid
Posts: 463
Joined: Wed Apr 08, 2015 5:19 am

Re: Noggin: A simple web framework that will run on your esp8266 boards.

Post by SpotlightKid » Fri Nov 17, 2017 7:22 pm

Not so much different modules, but the standard modules have - unfortunately - slight API differences, e.g. in signatures, where the number or types of arguments differ.

The point in case here is the usocket module, where on the esp8266 and the wipy (I think), the socket functions, which take an address (connect(), bind(), etc.), accept (host, port) tuples, whereas on the unix port, the address is expected as an opaque binary type, as returned by socket.getaddrinfo().

This is further confused by the scheme, where on bare-metal ports (stm32, esp8266, etc.), but not the unix port, when you do "import mod" and no module "mod" is found, it imports "umod". The rationale behind this, I think, is that on the bare-metal ports you generally want to use the minimal implementation of a standard module, provided by the built-in "u*" modules, whereas on the unix port, it shouldn't be a problem (disk space and memory wise) to install a wrapper (with optionally enhanced functionality over the built-in minimal version), which is importable under the normal name (i.e. without the "u" prefix).

The problem with this is approach is, that on the unix port, you either:

1) have to do all your imports of the built-in modules like this:

Code: Select all

try:
    import mod
except Import Error:
    import umod as mod
2) or you just use:

Code: Select all

import umod as mod
... but that then breaks compatibility with CPython.

3) or tell your users to install the appropriate wrapper modules from micropython-lib, but then the module you get when you do e.g. "import json" might not behave exactly as you would expect from looking at the documentation for the minimal "ujson" implementation, because it might be a totally different implementation and/or require other wrapper modules to be installed as well.

Hrmpf.

User avatar
pythoncoder
Posts: 5956
Joined: Fri Jul 18, 2014 8:01 am
Location: UK
Contact:

Re: Noggin: A simple web framework that will run on your esp8266 boards.

Post by pythoncoder » Sat Nov 18, 2017 9:48 am

SpotlightKid wrote:
Fri Nov 17, 2017 7:22 pm
...Hrmpf...
I agree. It seems to me that a major use case for the Unix build is to enable people to test code before porting it to a baremetal target. This particularly comes into its own for web-based coding (because unlike many firmware applications it may have few - or zero - hardware interfaces). In fact a realistic development scenario is to develop in Python 3.x perhaps using pdb or some IDE, re-test under MicroPython, then port to baremetal.

For that to be painless it would be good if the interfaces were consistent. As an example, while I appreciate the argument of @pfalcon in favour of using an opaque datatype from getaddrinfo() in the name of efficiency, my personal view is that the efficiency of the Unix port should take second place to its consistency with CPython and baremetal ports.
Peter Hinch
Index to my micropython libraries.

SpotlightKid
Posts: 463
Joined: Wed Apr 08, 2015 5:19 am

Re: Noggin: A simple web framework that will run on your esp8266 boards.

Post by SpotlightKid » Sat Nov 18, 2017 11:08 am

I wonder wether it would be possible to create a general compatibility wrapper script for micropython on unix, which mimics the import behaviour of the bare metal ports...

Post Reply