Advertisement

Tuesday, 22 March 2016

Use Flask to put your Pi data on the net - part 2


Part two of this tutorial begins with Flask templates and we are going to use them to make a simple web cam viewer. (Part one is here.)

We've already seen that we can generate a simple message from our Flask server but to build a more sophisticated web page we need to write some HTML and the simplest way to do this is with a template.

So let's dive in straight away with some code. Here is a slightly different version of out 'Hello' program:

import flask
app = flask.Flask(__name__)

@app.route("/")
def root():
 message = "Hello from Flask"
 return  render_template("index.html", msg=message)

if __name__ == "__main__":
 app.run()

You can type it in but don't run it yet, you'll just get a server error instead of a web page.

So what's the difference between this and the first program? Notice that firstly, we've assigned the message to be displayed to a variable called message. Next, the return statement has changed. Instead of simply returning the message we are calling the function render_template. The first parameter for this function is the name of a web page (which we now have to write!) and the second one is passing the variable message to the web page and saying that within the web page it will be called msg.

Here is the template:

<!DOCTYPE html>

<html>
   <head>
      <title>A Flask template</title>
   </head>
   <body>
      <h1>{{msg}}</h1>
   </body>
</html>

as you can see it's pretty much a standard HTML file. There is one small difference, inside the <h1> tags the are a pair of double curly braces and inside these is msg, the name of variable that contains our message string. The double curly braces simply mean insert the value of the variable (or expression) within them.

To create this template we first need to create a folder called templates. This is important.  Flask expects templates to be in this folder. Next, with your favourite editor, create a file called index.html inside that folder.

Now open your web browser, at the same address as before, and you'll see this:

Much the same as before but this time it's a proper web page and the message that we have passed into it is rendered as a header.

So that's fine, we can serve a web page of our own design and insert things into it from our Python program.

What we want to do now is make this page display the image from a webcam.

To make things simple we are going to assume that the latest image from the webcam is in a particular folder and the image itself is called image.jpg.

We will see how we get the image into be the folder, later. For now create a folder called static, copy any suitable jpeg image into it and rename that image image.jpg.

The following program will display the image in a web page template. When we've gone through it you'll see that it is remarkably simple.


import flask, os, time

app = flask.Flask(__name__)

IMAGEURL = "static/image.jpg"

@app.route("/")
def root():
 message = "Fishing Port Webcam"
 
 # get the time/date that the image was taken
 # first get the information about the file
 fileInfo = os.stat(IMAGEURL) 
 # find the last time it was modified
 lastMod = fileInfo.st_mtime 
 # change the time to local time
 localtime = time.localtime(lastMod)
 # and finally convert it to a string
 timeStr = time.asctime(localtime)
 
 return  flask.render_template \
 ("index.html", msg=message, imageURL=IMAGEURL, time=timeStr)

if __name__ == "__main__":
 app.run(debug=True)


The first thing that you'll notice is that we are importing a couple of extra libraries, os and time, you'll see why shortly.

The next new thing is that we have defined a global variable IMAGEURL to hold the path to the image in the static directory. You might wonder why it's in capitals - this is because we are using it as a constant (i.e. something that does not change it's value) and it is simply a convention that is used in many programming languages to name constants in capitals. Python doesn't actually have constants but by using this convention we will remember that we should not change it's value.

Next we've changed the message. If you look at the image of the program running on my system, you'll understand why!

Now we get some information about the file because we would like to show when the image was taken. This is where the os library comes in. os contains a lot of useful things for interacting with the operating system, or, in this case, with the file system. We use the function os.stat to get information about the image file and store it in the variable fileinfo. The thing that we are interested in is the time and date that the file was last modified. This is given in fileinfor.st_mtime. Now we use a couple of functions from the time library. Using functions from the time library, we first convert the time to the local time and then convert that into a string that can be displayed on our web page. That's quite a lot of fuss to get the time that we want but it is quite straightforward and could be condensed into much less code. I've coded it here step by step in order to make it clear what we are doing.

The next step is to call up the template to display our web page. We need to send it three pieces of data: a message, the url of the image file and the last modified time/date. You can see from the program listing that this is done in the same way that we sent the message to the template except that this time each of the values is listed one after the other and separated by commas.

Here is the template.

<!DOCTYPE html>
<html>
   <head>
      <title>Webcam</title>
   </head>
   <body>
      <h1>{{msg}}</h1>
      <p>This image was recorded on {{time}}</p>
      <img src={{imageURL}}></img>
   </body>
</html>



Again this is a simple web page that consists of a header that displays the message, and paragraph containing the time and a img tag that displays the image. The data that is sent from the Python code is msg, time and imageURL, and these are put in the appropriate places in the html, enclosed in double curly braces.

And that is about it.

This is just an introduction to Flask templates, they can be much more powerful that we have seen here. We have only used simple values to place in the templates but we include programming logic (loops, etc.) too. We'll see how to do this in a future tutorial.

Have I missed something? Oh, yes, I did say that the image that we are displaying comes from a web cam. I'm not going to go into detail about how to do this because someone else already has.

To get the image.jpg to be updated by either a usb webcam or a Raspberry Pi camera module, you need only look at the Raspberry Pi web site. Here you will find how to grab an image from a webcam with a simple shell script and update it by using crontab to call the script on a regular basis.

For a usb camera your shell script will use fswebcam, something like this:

fswebcam myproject/static/image.jpg

Follow this link for details:

And for a Picam this sort of thing:

raspistill -o myproject/static.jpg

Follow this link for details:

If you found this tutorial interesting, please share with your friends and please feel free to comment.


Just Enough Python
An brief introduction that will get you programming quickly

2 comments: