Book Image

Flask By Example

By : Gareth Dwyer
Book Image

Flask By Example

By: Gareth Dwyer

Overview of this book

This book will take you on a journey from learning about web development using Flask to building fully functional web applications. In the first major project, we develop a dynamic Headlines application that displays the latest news headlines along with up-to-date currency and weather information. In project two, we build a Crime Map application that is backed by a MySQL database, allowing users to submit information on and the location of crimes in order to plot danger zones and other crime trends within an area. In the final project, we combine Flask with more modern technologies, such as Twitter's Bootstrap and the NoSQL database MongoDB, to create a Waiter Caller application that allows restaurant patrons to easily call a waiter to their table. This pragmatic tutorial will keep you engaged as you learn the crux of Flask by working on challenging real-world applications.
Table of Contents (20 chapters)
Flask By Example
Credits
About the Author
Acknowledgements
About the Reviewers
www.PacktPub.com
Preface
Index

Deploying our application to production


It's great to have an application that runs, but inherent to the idea of a web application is the idea that we want others to be able to use it. As our application is Python-based, we are a bit limited in how we can run our application on a web server (many traditional web hosts are only configured to run PHP and/or .NET applications). Let's consider how to serve Flask applications using a Virtual Private Server (VPS) running Ubuntu Server, Apache, and WSGI.

From this point on, we'll maintain two environments. The first is our development environment, which we just set up and where we'll write code and view its results using the Flask server running on localhost (as we just did). The second will be a production environment. This will be a server to which we can deploy our web applications and make them accessible to the world. When we install new Python libraries or other software on our development environment, we'll normally want to mirror our actions in the production environment.

Setting up a Virtual Private Server

Although you could, in theory, host your web application on your local machine and allow others to use it, this has some severe limitations. First of all, every time you turned off your computer, your app would not be available. Also, your computer probably connects to the Internet via an Internet Service Provider (ISP) and possibly a wireless router. This means that your IP address is dynamic and changes regularly, which makes it difficult for your applications' users to keep up! Finally, chances are that you have an asymmetrical connection to the Internet, which means that your upload speed is slower than your download speed.

Hosting your application on a server solves all of these problems. Before "the cloud" became popular, the traditional way to host a web application was to buy a physical server and find a data center to host it. These days, things are far simpler. In a few minutes, you can fire up a virtual server, which to you seems just like a physical server—you can log in to it, configure it, and enjoy full control over it—but it is actually just a virtual "piece" of a machine owned and controlled by a cloud provider.

At the time of writing, major players in the cloud provider field include Amazon Web Services, Microsoft Azure, Google Cloud Compute, and Digital Ocean. All of these companies allow you to hire a virtual server or servers upon paying by the hour. If you are learning Flask as a hobby and are unwilling to pay anyone to host your web applications, you'll probably find a free trial at one of the providers quite easily. The smallest offering by any provider is fine to host all the applications that we'll run.

Select one of the preceding providers or another of your choosing. If you've never done anything similar before, Digital Ocean is often cited to have the simplest process of signing up and creating a new machine. Once you select a provider, you should be able to follow their respective instructions to fire up a VPS that runs Ubuntu Server 14.04 and SSH into it. You'll have full control over the machine with one slight difference: you won't have a display or a mouse.

You'll enter commands on your local terminal, which will in fact be run on the remote machine. Detailed instructions on how to connect to your VPS will be given by the provider, but if you use Ubuntu, it should be as simple as running the following:

Alternatively, if you set it up with a public-private key authentication, where yourkey.pem is the full path to your private key file, here's the command to run:

ssh [email protected] –i yourkey.pem

Here, user is the default user on the VPS, and yourkey is the name of your private key file.

SSH from other operating systems:

Tip

SSH from OS X should be the same as Ubuntu, but if you're using Windows, you'll have to download PuTTY. Refer to http://www.putty.org/ to download and for full usage instructions. Note that if you use key files for authentication, you'll have to convert them to a format compatible with PuTTY. A conversion tool can also be found on the PuTTY website.

Once we connect to the VPS, installing Flask is the same process as it was previously:

sudo apt-get update
sudo apt-get install python-pip
pip install --user Flask

To install our web server, Apache, and WSGI, we will run the following:

sudo apt-get install apache2
sudo apt-get install libapache2-mod-wsgi

Apache is our web server. It will listen for web requests (which are generated by our users visiting our web application using their browsers) and hand these requests over to our Flask application. As our application is in Python, we also need WSGI (Web Server Gateway Interface).

This is a common interface between web servers and Python applications, which allows Apache to talk to Flask and vice versa. An overview of the architecture can be seen in the following diagram:

Configuring our server

Now that we've installed Apache, we can see our first results. You're probably used to visiting websites using a URL, such as http://example.com. We'll access our web applications using the IP address of our VPS directly. Your VPS should have a static public address. Static means that it doesn't change periodically, and public means that it is globally unique. When you connected to the VPS via SSH, you probably used the public IP to do this. If you can't find it, run the following on your VPS and you should see an inet addr section in the output, which contains your public IP:

ifconfig

The IP address should look similar to 123.456.78.9. Enter your IP address into your browser's address bar, and you should see a page saying "Apache2 Ubuntu Default Page: It Works!" or something similar, as in the following screenshot:

This means that we can now serve web content to anyone with an Internet connection! However, we still have to:

  • Copy our code to the VPS

  • Link up Apache and Flask

  • Configure Apache to serve our Flask application

For the first step, we'll set up a Git repository on our local machine and clone the repository to the VPS. For the second step, we'll use the WSGI module that we installed with Apache. Finally, we'll take a look at how to write a virtual host to have Apache serve our Flask application by default.

Installing and using Git

Git is a version control system. A version control system, among other things, saves multiple versions of our code base automatically. This is great to undo accidental changes or even deletions; we can simply revert to a previous version of our code. It also includes lots of functionality for distributed development—that is, many developers working on a single project. We'll use it mainly for its backup and deployment features, however.

To install Git on your local machine and VPS, run the following commands on each:

sudo apt-get update
sudo apt-get install git

Note

Make sure you're comfortable with the difference between running commands on your own machine using the terminal and on your server through the SSH connection. In many cases, we'll need to run the same commands twice—once for each environment.

Now that you have the software, you need a place to host your Git repositories or "repos". Two popular and free Git hosting services are GitHub (http://github.com) and Bitbucket (http://bitbucket.org). Head over to one of them, create an account, and create a new repository by following the instructions that they provide. When given the option to give your repository a name, call it firstapp to match the name of the directory that we will use for our code base. Once you create a new repository, you should be given a unique URL to your repository. Take note of this as we'll use it to push our Hello, World! application using git and then deploy it to our VPS.

On your local machine, open a terminal and change the directory to the Flask application. Initialize a new repository and link it to your remote Git repository via the following commands:

cd firstapp
git init
git remote add origin <your-git-url>

Tell git who you are, to allow it to automatically add metadata to your code changes, as follows:

git config --global user.email "[email protected]"
git config --global user.name "Your Name"

Git allows you full control over which files are part of your repository and which aren't. Even though we initialized the Git repo in our firstapp directory, our repo currently contains no files. Add our application to the repo, commit, and then push it, as follows:

git add hello.py
git commit -m "Initial commit"
git push -u origin master

These are the main Git commands that we'll use throughout this book, so let's take a brief look at what each does. The add command adds new or modified files to our repository. This tells Git which files are actually part of our project. Think of the commit command as taking a snapshot of our project in its current state. This snapshot is saved on our local machine. It is good to make a new commit with any major change to the code base as we can easily revert to previous commits if a later commit breaks our application. Finally, the push command pushes our local changes to the remote Git server. This is good for backup, and it will also allow us to fetch the changes on our VPS, thus keeping the code base on our local machine and that on our VPS in sync.

Now, SSH into your VPS again and get a copy of our code, as follows:

cd /var/www
git clone <your-git-url>

Note

Where the <your-git-url> part of the above command is actually a placeholder for the URL to your Git repository.

If you get a permission denied error on trying to clone the Git repository, you might need to take ownership of the /var/www directory for the Linux user that you're using. If you logged into the server with [email protected], you can run the following command, which will give your user ownership of /var/www and allow you to clone the Git repository into it. Again tom is the placeholder used in the following case:

sudo chown -R tom /var/www

If you used firstapp as a name for your remote repository, this should create a new directory called firstapp. Let's verify that our code is there using the following:

cd firstapp
ls

You should see your hello.py file. Now, we need to configure Apache to use WSGI.

Serving our Flask app with WSGI

First, we'll create a very straightforward .wsgi file in our application directory. Then, we'll create an Apache configuration file in the directory where Apache looks for available sites.

The only slightly tricky part about these two steps is that we'll create the files directly on our VPS, and as our VPS does not have a display, this means that we have to use command-line interface text editors. Of course, we could create the files locally and then transfer them to our VPS as we did for our code base, but for small changes to configuration files, this is often more effort than it's worth. Using a text editor without a mouse takes a bit of getting used to, but it's a good skill to learn. The default text editor on Ubuntu is Nano, and the other popular choices are vi or Vim. Some people use Emacs. If you already have a favorite, go with it. If not, we'll use Nano for the examples in this book (it is already installed and arguably the simplest to use). However, if you want to go the extra mile, I recommend learning to use Vim.

Assuming you're still connected to your VPS and have navigated to the /var/www/firstapp directory as in the most recent steps, run the following command:

nano hello.wsgi

This creates the hello.wsgi file, which you can now edit through Nano. Type the following:

import sys
sys.path.insert(0, "/var/www/firstapp")
from hello import app as application

This is simply Python syntax, which patches our application into the PATH system so that Apache can find it through WSGI. We will then import app (we named this in our hello.py app with the app = Flask(__name__) line) into the namespace.

Hit Ctrl + X to exit Nano and enter Y when prompted to save the changes.

Now, we'll create an Apache configuration file that points to the .wsgi file we just created, as follows:

cd /etc/apache2/sites-available
nano hello.conf

Note

If you run into permission issues while editing or saving files, you may need to take ownership of the apache2 directory too. Run the following command, substituting the username for your Linux user:

sudo chown –R tom /etc/apache2

In this file, we'll create a configuration for an Apache virtual host. This will allow us to serve multiple sites from a single server, which will be useful later when we want to serve other applications using our single VPS. In Nano, enter the following configuration:

<VirtualHost *>
    ServerName example.com

    WSGIScriptAlias / /var/www/firstapp/hello.wsgi
    WSGIDaemonProcess hello
    <Directory /var/www/firstapp>
       WSGIProcessGroup hello
       WSGIApplicationGroup %{GLOBAL}
        Order deny,allow
        Allow from all
    </Directory>
</VirtualHost>

This might look quite complicated, but it's actually very straightforward. We will create a virtualhost and specify our domain name, where our .wsgi script is, the name of our application, and who is allowed to access it. We'll discuss domain names in the final chapter, but for now, you can just leave it as example.com because we'll access our application by its IP address.

Note

If you get stuck on this step, the Flask website has a great resource on configuring and troubleshooting Apache configuration. You can find it at http://flask.pocoo.org/docs/0.10/deploying/mod_wsgi/.

Hit Ctrl + X and enter Y when prompted again to save and exit the file. Now, we need to enable the configuration and set it as our default site.

Configuring Apache to serve our Flask application

Apache sites work as follows: there is a sites-available directory (where we created the new virtual host configuration file) and a sites-enabled directory, which contains shortcuts to all the configuration files that we want to be active. By default, you'll see a file in the sites-available directory named 000-default.conf. This is the reason that we saw a default It works Apache page when we first installed Apache. We don't want this anymore; instead, we want to use our application as the default site. Therefore, we'll disable the default Apache site, enable our own, and then restart Apache for the changes to take effect. Run these commands to do this:

sudo a2dissite 000-default.conf
sudo a2ensite hello.conf
sudo service apache2 reload

Note

The required Apache configuration and commands can vary quite a bit based on the platform you're using. If you use Ubuntu Server as recommended, the preceding should all work smoothly. If not, you may need to read up a bit on how to configure Apache for your specific platform.

You should note reloading web server apache2 in the output. If errors are displayed, then you probably misconfigured something in the preceding command. If this is the case, read the error message carefully and go back over the previous steps to take a look at why things didn't work as expected.

To test that everything is working, open a web browser on your local machine and type your IP address into the address bar again. You should see Hello, World! displayed in your browser instead of the default Apache page that we saw before.

If you get Error 500 instead, it means that our application fell over for some reason. Fear not; it's better that you get used to dealing with this error now, when the fix will probably be simple, than later on, when we've added more components that could break or be misconfigured. To find out what went wrong, run the following command on your VPS:

sudo tail –f /var/log/apache2/error.log

The tail command simply outputs the last several lines of the file passed as an argument. The -f is for follow, which means that the output will be updated if the file changes. If you can't immediately work out which lines are indicative of the error we're looking for, visit the site in your web browser on your local machine again, and you'll see the output from the tail command be updated accordingly. The following screenshot shows the output from the tail command when there are no errors; however, if anything goes wrong, you'll see the error output printed among all the info messages.

Some possible tripping points are incorrectly configured WSGI and Apache files (make sure that your WSGIDaemonProcess and daemon name match, for example) or incorrectly configured Python (you may forget to install Flask on your VPS). If you can't figure out what the error message means, an Internet search for the message (removing the error-specific parts of your app, such as names and paths) will usually point you in the right direction. Failing this, there are strong and very friendly Flask and WSGI communities on Stack Overflow and Google Groups, and there's normally someone willing to help beginners. Remember that if you're having a problem and can't find an existing solution online, don't feel bad for asking; you'll help countless people facing issues similar to yours.