An Overview of MicroPython

There are a lot of options available when one starts exploring the exciting field of the Internet of Things, or IoT. Not only are there many choices of micro-controllers, there are also a variety of languages in which to program these devices. Many times the micro-controllers are sold as being dependent on C or C++ as a language. That’s great, but I don’t know either of those. There is some great and amazing working being led by Andrew Chalkley around using the JavaScript language for micro-controllers over at thingsSDK. If JavaScript is your language, I’d highly recommend checking out their work. There are also lots of resources for using Java for IoT, Nathan Tippy, for example, is an excellent resource.

All those are great languages. What if you are a beginning developer just interested in playing around in IoT? Or what if you are a Pythonista and don’t want to pick up another programming language? Well, for many micro-controllers there is a Python option which is, arguably easier to learn in many ways than Java, JavaScript, C or C++. That option being MicroPython. You can see that project’s website here.

Overview of MicroPython

MicroPython is a tiny, open source Python programming language interpreter that runs on embedded boards. It was originally developed in 2013 and released in 2014 by Dr. Damian P. George of Cambridge University. It implements Python 3 and is designed specifically to run on devices with limited resources.

As with many things in the IoT world, the use of a particular language is greatly influenced by the tools, libraries, and packages one has available. MicroPython comes with an interactive read-evaluate-print-loop (REPL) for quick prototyping. It also fully supports loading MicroPython scripts onto a device to run as well. It supports an extensive Python based library and for lower level operations can be extended with C/C++ functions as needed.

Many of the tasks that beginning IoT folks start off with, such as blinking lights, reading switches, driving servos, etc. are all easy to do in MicroPython. Further, it is often incredibly easy to read as well, as it is all Python based. For example, if one has MicroPython installed on a NodeMCU ESP8266 board, a popular and inexpensive board to start working in IoT, with a basic LED light connected to GPIO Pin 5 it is pretty simple to get the light to turn on (high state) and off (low state).

import machine

led = machine.Pin(5, machine.Pin.OUT)
# Turn on LED
led.high()
# Turn off LED
led.low()

The machine module is included with MicroPython and handles many of the hardware connections from software.  It allows access to things like GPIO pins, CPU frequency, I2C busses, etc. If it is low-level on the hardware, the machine module is the way to go!

Platform Support

There are many devices that support MicroPython. The NodeMCU is one of them. But several other options are available such as the LoPy or similar PyCom devices, the PyBoard, and many others.

Differences from Python 3

As one can imagine, cramming everything from Python 3 into a micro-controller isn’t possible. But, core data types and modules which make sense for embedded systems are included. Another limitation is that since Python is a high-level programming language it isn’t as fast or lean as C or C++. Many operations aren’t impacted by this. However, if your application requires tight timing or performance is of utmost importance, using MicroPython can be an issue. However, as stated earlier, one can extend MicroPython to use C/C++ in these circumstances.

Since MicroPython is open source, check it out on GitHub, one can further extend or adapt it specific use case scenarios. For example, if you need something specific to run at boot time you can include it in the package that is flashed to the device. Pretty handy and convenient.

Conclusion

Hopefully I have at least sparked your interest enough in using MicroPython for IoT to take a further look at it. The development site actually has a live, interactive device where you can try out some code and see it run on a real world device. Give it a try and leave a comment below to share with others what you’ve done and built!

Follow me on Twitter @kenwalger to get the latest updates on my postings.

Facebooktwitterredditlinkedinmail

Python Bottle Framework Basics

Python offers several popular web frameworks such as Django, TurboGears, Flask, and Pyramid, to name a few. In this post I want to take a look at the Bottle framework. Actually, I’ll be spending a couple of posts using Bottle before jumping into Django.

Bottle

From the Bottle website, Bottle is described as:

Bottle is a fast, simple and lightweight WSGI micro web-framework for Python.

Fast… great. Simple… awesome. Lighweight… sounds good. WSGI??? What is that? WSGI is an acronym for Web Server Gateway Interface and comes from the PEP 333 standard. Which, in a nutshell, means that Bottle is going to be compliant with and capable of supporting all (or most) interactions between a Web server and a Web framework. Cool, that sounds reasonable.

Now what about that last part, the micro web-framework? Well, that typically means that the web-framework isn’t as full features as an enterprise level framework, such as Django, and by default doesn’t include some features expected in a full fledged web framework. While Bottle can indeed be deployed to a server and have full functioning applications, I find Bottle, and other micro web-frameworks, to be great for prototyping of ideas.

What I’d like to build out as a prototype in Bottle, then switch it over to Flask, is a very basic blood sugar tracking and logging application for those dealing with Type I Diabetes. We’ll get more into the data that we need to keep track of and the database schema in another post. In this post, we will concern ourselves simply with getting familiar with Bottle, routes, templates, and static files.

Routing

As stated in Bottle’s project description, it is fast and simple to get things running. We, of course, need to install it first using

pip install bottle

At the time of this writing, the current version is 0.12.13.

I’m going to assume for this discussion that HTTP methods such as GET and POST are something with which you are familiar. If not you can see an explanation of them here.  For starters we need to see how to establish a basic route in Bottle, so let’s do one for the every popular “Hello World!” example.

app.py

import bottle

# Site Index
@bottle.route('/')
def index():
    return "Hello World!"

if __name__ == '__main__':
    bottle.run('localhost', 8082, debug=True, reloader=True)

Now, if we run our application and go to http://localhost:8082 on our local machine we should see an HTML page with the text “Hello World!”. As promised, pretty quick and easy to get a page up and running with Bottle. It would be great if we could return some generated information as well. What about just adding a name to our route and have that name displayed on the screen? We’ll use the cgi module, or Common Gateway Interface to obtain that information from our URL.

app.py

import bottle
import cgi


# Site Index
@bottle.route('/')
def index():
    return "Hello World!"

# Index with name
@bottle.route('/<name>')
def get_name(name="Nobody"):
    name = cgi.html.escape(name)
    return "Hello {}".format(name)


if __name__ == '__main__':
    bottle.run('localhost', 8082, debug=True, reloader=True)

This is pretty cool and super simple to get pages out and displayed on a web page, but they don’t look great and just returning strings is still pretty limiting.

Template Engine

Fortunately Bottle comes with and utilizes a basic template engine called SimpleTemplate. This will allow us to write HTML files, use CSS, and include Python code inside our templates. Our template files will be of the file type .tpl. Let’s see about changing our name route to use a template and pass the template our URL information. Let’s call our template name.tpl.

app.py

import bottle
import cgi


# Site Index
@bottle.route('/')
def index():
    return "Hello World!"

# Index with name
@bottle.route('/<name>')
def get_name(name="Nobody"):
    name = cgi.html.escape(name)
    return bottle.template('name.tpl', name=name)


if __name__ == '__main__':
    bottle.run('localhost', 8082, debug=True, reloader=True)

name.tpl

<!DOCTYPE html>
<html>
    <head>
        <title>Name Page</title>
    </head>

    <body>
        Hello {{name}}!
    </body>
</html>

Great, we are passing our name variable information from our route in app.py to our template and, using the {{...}} syntax we are able to capture and display information. We can pass many different arguments into the return statement of our route such as data coming back from a database, data for regarding errors, user names, page titles, etc.

One thing that is always nice to be able to do in a web framework is to not have to repeat ourselves in every template file for things such as the HTML head information and page footer information. Once again, Bottle and SimpleTemplate makes this easy with the % include() feature. Let’s see this in action by creating a header.tpl file, include it inside our name.tpl file, and pass in title data from our route.

header.tpl

    
<!DOCTYPE html>
<html>
    <head>
        <title>{{title or 'No title'}}</title>
    </head>

    <body>   

name.tpl

% include('header.tpl', title=title)

        Hello {{name}}!
    </body>
</html>

And let’s not forget to update our route information as well…

app.py Snippet

# Index with name
@bottle.route('/<name>')
def get_name(name="Nobody"):
    name = cgi.html.escape(name)
    return bottle.template('name.tpl', name=name, title="Name Page")

Fantastic! Now we can see how we can utilize information from our Python code in app.py and display it in our templates.

Static Files

One other think I would like to mention in this post is how to setup Bottle for including static files like CSS. Again, Bottle makes this easy by simply having us define the path to our static files and by importing static_file from bottle and returning a static_file. This is the recommended way to serve static files and it provides some extra security protection to the files. We can define a new route for static CSS files like so:

from bottle import static_file

# Static CSS Files
@bottle.route('/static/css/<filename:re:.*\.css>')
def send_css(filename):
    return static_file(filename, root='static/css')

With the exception of the regular expression filter in the link name, that should look pretty familiar. The regular expression is simply telling Bottle that any file name with a .css extension should be looked for, in this case, in the static/css directory.

Now, inside our header.tpl file we can include a <link type="text/css" href="/static/css/styles.css" rel="stylesheet"> line and have our CSS files safely included and if they are missing Bottle will provide some convenient error messages.

Wrap Up

I think that is a pretty decent start for our knowledge of Bottle, how to create some routes in general, some basic templates, and serving some static files. In another post, I’ll show a basic site that will have the necessary routes and templates in place for our Blood Sugar Tracker application. From there I’ll show how we can utilize MongoDB as a data store for the application and include session and user signup information so we can provide some basic authentication with sessions and cookies, which Bottle provides some great and amazingly simple tools to enable that functionality.

See you next time and Happy Coding!


Follow me on Twitter @kenwalger to get the latest updates. If you enjoyed this article, or have questions, leave comments below.

Facebooktwitterredditlinkedinmail