2012-05-07T06:05:40Z

The Flask Mega-Tutorial, Part I: Hello, World!

(Great news! There is a new version of this tutorial!)

This is the first article in a series where I will be documenting my experience writing web applications in Python using the Flask microframework.

NOTE: This article was revised in September 2014 to be in sync with current versions of Python and Flask.

Here is an index of all the articles in the series that have been published to date:

My background

I'm a software engineer with double digit years of experience developing complex applications in several languages. I first learned Python as part of an effort to create bindings for a C++ library at work.

In addition to Python, I've written web apps in PHP, Ruby, Smalltalk and believe it or not, also in C++. Of all these, the Python/Flask combination is the one that I've found to be the most flexible.

UPDATE: I have written a book titled "Flask Web Development", published in 2014 by O'Reilly Media. The book and the tutorial complement each other, the book presents a more updated usage of Flask and is, in general, more advanced than the tutorial, but some topics are only covered in the tutorial. Visit http://flaskbook.com for more information.

The application

The application I'm going to develop as part of this tutorial is a decently featured microblogging server that I decided to call microblog. Pretty creative, I know.

These are some of the topics I will cover as we make progress with this project:

  • User management, including managing logins, sessions, user roles, profiles and user avatars.
  • Database management, including migration handling.
  • Web form support, including field validation.
  • Pagination of long lists of items.
  • Full text search.
  • Email notifications to users.
  • HTML templates.
  • Support for multiple languages.
  • Caching and other performance optimizations.
  • Debugging techniques for development and production servers.
  • Installation on a production server.

So as you see, I'm going pretty much for the whole thing. I hope this application, when finished, will serve as a sort of template for writing other web applications.

Requirements

If you have a computer that runs Python then you are probably good to go. The tutorial application should run just fine on Windows, OS X and Linux. Unless noted, the code presented in these articles has been tested against Python 2.7 and 3.4, though it will likely be okay if you use a newer 3.x release.

The tutorial assumes that you are familiar with the terminal window (command prompt for Windows users) and know the basic command line file management functions of your operating system. If you don't, then I recommend that you learn how to create directories, copy files, etc. using the command line before continuing.

Finally, you should be somewhat comfortable writing Python code. Familiarity with Python modules and packages is also recommended.

Installing Flask

Okay, let's get started!

If you haven't yet, go ahead and install Python.

Now we have to install Flask and several extensions that we will be using. My preferred way to do this is to create a virtual environment where everything gets installed, so that your main Python installation is not affected. As an added benefit, you won't need root access to do the installation in this way.

So, open up a terminal window, choose a location where you want your application to live and create a new folder there to contain it. Let's call the application folder microblog.

If you are using Python 3, then cd into the microblog folder and then create a virtual environment with the following command:

$ python -m venv flask

Note that in some operating systems you may need to use python3 instead of python. The above command creates a private version of your Python interpreter inside a folder named flask.

If you are using any other version of Python older than 3.4, then you need to download and install virtualenv.py before you can create a virtual environment. If you are on Mac OS X, then you can install it with the following command:

$ sudo easy_install virtualenv

On Linux you likely have a package for your distribution. For example, if you use Ubuntu:

$ sudo apt-get install python-virtualenv

Windows users have the most difficulty in installing virtualenv, so if you want to avoid the trouble then install Python 3. If you want to install virtualenv on Windows then the easiest way is by installing pip first, as explaned in this page. Once pip is installed, the following command installsvirtualenv`:

$ pip install virtualenv

We've seen above how to create a virtual environment in Python 3. For older versions of Python that have been expanded with virtualenv, the command that creates a virtual environment is the following:

$ virtualenv flask

Regardless of the method you use to create the virtual environment, you will end up with a folder named flask that contains a complete Python environment ready to be used for this project.

Virtual environments can be activated and deactivated, if desired. An activated environment adds the location of its bin folder to the system path, so that for example, when you type python you get the environment's version and not the system's one. But activating a virtual environment is not necessary, it is equally effective to invoke the interpreter by specifying its pathname.

If you are on Linux, OS X or Cygwin, install flask and extensions by entering the following commands, one after another:

$ flask/bin/pip install flask
$ flask/bin/pip install flask-login
$ flask/bin/pip install flask-openid
$ flask/bin/pip install flask-mail
$ flask/bin/pip install flask-sqlalchemy
$ flask/bin/pip install sqlalchemy-migrate
$ flask/bin/pip install flask-whooshalchemy
$ flask/bin/pip install flask-wtf
$ flask/bin/pip install flask-babel
$ flask/bin/pip install guess_language
$ flask/bin/pip install flipflop
$ flask/bin/pip install coverage

If you are on Windows the commands are slightly different:

$ flask\Scripts\pip install flask
$ flask\Scripts\pip install flask-login
$ flask\Scripts\pip install flask-openid
$ flask\Scripts\pip install flask-mail
$ flask\Scripts\pip install flask-sqlalchemy
$ flask\Scripts\pip install sqlalchemy-migrate
$ flask\Scripts\pip install flask-whooshalchemy
$ flask\Scripts\pip install flask-wtf
$ flask\Scripts\pip install flask-babel
$ flask\Scripts\pip install guess_language
$ flask\Scripts\pip install flipflop
$ flask\Scripts\pip install coverage

These commands will download and install all the packages that we will use for our application.

"Hello, World" in Flask

You now have a flask sub-folder inside your microblog folder that is populated with a Python interpreter and the Flask framework and extensions that we will use for this application. Now it's time to write our first web application!

After you cd to the microblog folder, let's create the basic folder structure for our application:

$ mkdir app
$ mkdir app/static
$ mkdir app/templates
$ mkdir tmp

The app folder will be where we will put our application package. The static sub-folder is where we will store static files like images, javascripts, and cascading style sheets. The templates sub-folder is obviously where our templates will go.

Let's start by creating a simple init script for our app package (file app/__init__.py):

from flask import Flask

app = Flask(__name__)
from app import views

The script above simply creates the application object (of class Flask) and then imports the views module, which we haven't written yet. Do not confuse app the variable (which gets assigned the Flask instance) with app the package (from which we import the views module).

If you are wondering why the import statement is at the end and not at the beginning of the script as it is always done, the reason is to avoid circular references, because you are going to see that the views module needs to import the app variable defined in this script. Putting the import at the end avoids the circular import error.

The views are the handlers that respond to requests from web browsers or other clients. In Flask handlers are written as Python functions. Each view function is mapped to one or more request URLs.

Let's write our first view function (file app/views.py):

from app import app

@app.route('/')
@app.route('/index')
def index():
    return "Hello, World!"

This view is actually pretty simple, it just returns a string, to be displayed on the client's web browser. The two route decorators above the function create the mappings from URLs / and /index to this function.

The final step to have a fully working web application is to create a script that starts up the development web server with our application. Let's call this script run.py, and put it in the root folder:

#!flask/bin/python
from app import app
app.run(debug=True)

The script simply imports the app variable from our app package and invokes its run method to start the server. Remember that the app variable holds the Flask instance that we created it above.

To start the app you just run this script. On OS X, Linux and Cygwin you have to indicate that this is an executable file before you can run it:

$ chmod a+x run.py

Then the script can simply be executed as follows:

./run.py

On Windows the process is a bit different. There is no need to indicate the file is executable. Instead you have to run the script as an argument to the Python interpreter from the virtual environment:

$ flask\Scripts\python run.py

After the server initializes it will listen on port 5000 waiting for connections. Now open up your web browser and enter the following URL in the address field:

http://localhost:5000

Alternatively you can use the following URL:

http://localhost:5000/index

Do you see the route mappings in action? The first URL maps to /, while the second maps to /index. Both routes are associated with our view function, so they produce the same result. If you enter any other URL you will get an error, since only these two have been defined.

When you are done playing with the server you can just hit Ctrl-C to stop it.

And with this I conclude this first installment of this tutorial.

For those of you that are lazy typists, you can download the code from this tutorial below:

Download microblog-0.1.zip.

Note that you still need to install Flask as indicated above before you can run the application.

What's next

In the next part of the series we will modify our little application to use HTML templates.

I hope to see you in the next chapter.

Miguel

350 comments

  • #201 Miguel Grinberg said 2014-04-20T17:36:24Z

    @klz: this tutorial was written before Flask had support for Python 3. The changes to make the code Python 3 ready aren't big, but if you want to not have to worry about that then I recommend that you do the tutorial with Python 2.7. For this particular error you are having you have to change "from forms import LoginForm" to "from .forms import LoginForm", a dot needs to be added before "forms".

  • #202 Ed Valenzuela said 2014-05-07T19:56:01Z

    I am running windows 7, python34- when I try to execute the virtualenv.py flask command I get the following: Using base prefix 'c:\Python34' New python executable in flask\Scripts\python.exe Failed to import the site module Traceback : File "C:\Users\TopDog\flask\lib\site.py" line 67 in import os File "C:\Users\TopDog\flask\lib\os.py" line 634 in from _collections_abc import MutableMapping Import error: No module named '_collections_abc' ERROR: The executable flask\Scripts\python.exe is not functioning ERROR: It thinks sys.prefix is 'c:\users\topdog' ERROR: virtualenv is not compatible with this system or executable

    What should I try to do now?

  • #203 Miguel Grinberg said 2014-05-08T04:05:02Z

    @Ed: on Python 3.4 virtualenv is deprecated, you need to use "pyvenv" which should already be installed with your Python interpreter. Note that this tutorial was written before Flask had support for Python 3, so you will need to make some minor adjustments for everything to work. When I find the time I will update everything so that it works on Python 3.

  • #204 John Valentine said 2014-05-21T01:33:03Z

    Miguel - Thanks for putting this tutorial together; looking forward to grabbing your new book once the print edition comes out.

    I am having issues running the basic app. I have tried it both in and out of a virtualenv, and am receiving the same traceback in both situations:

    Traceback (most recent call last): File "flask.py", line 1, in <module> from flask import Flask File "/home/makisupa43/dev/flask.py", line 1, in <module> from flask import Flask ImportError: cannot import name Flask

    Any thoughts? Thanks a lot.

  • #205 Miguel Grinberg said 2014-05-21T05:14:09Z

    @John: have you installed Flask in your virtualenv? Sounds like it isn't installed.

  • #206 Pitto said 2014-05-30T16:20:22Z

    Hi there and thanks for the tutorial!

    I've decided digging into flask but I can't find how to set its webserver to listen port 80...

    I've read that if I use:

    !flask/bin/python

    from app import app app.run(host=0.0.0.0, port=80)

    Instead of code suggested here it should work but I get an error instead: syntax error: invalid syntax

    What am I doing wrong?

  • #207 Miguel Grinberg said 2014-05-30T17:02:14Z

    @Pitto: the host argument is a string:

    app.run(host="0.0.0.0", port=80)

    Also note that port numbers below 1024 are only accessible only to the superuser.

  • #208 B said 2014-06-10T16:48:48Z

    Hi Miguel,

    First off let me thank you for the amazing tutorial, learning loads from it, exactly what I needed.

    I have a question though. I was wondering what is the difference between running the app on a 'real' web server or any given frameworks built-in one. Is using apache or any of the others better for performance considerations? Can you even run this app solely on the frameworks server, could it be reached from the internet? Also the script that initializes a Flask instance in the first article (that starts the Flask server on localhost:5000), does this bit get taken out later on? (sorry haven't read the whole tutorial yet) or does that bit still run so there is the Flask server running inside the dedicated web server in which case the webserver kind of acts like a router doing port forwarding? Sorry for the wall of questions but I am a bit confused about the relationship between the webserver and the framework and I wasn't sure where else to ask about this.

  • #209 Miguel Grinberg said 2014-06-11T05:54:02Z

    @B: the development web server can be used to serve external clients, but this server will have really bad performance compared to production servers such as apache or nginx. The two lines that start the development web server are not removed, but they do not run when the app is started via a production server.

  • #210 Pawel said 2014-06-12T14:19:49Z

    Sorry if it's stupid question but I wanted to take a look at Falsk but I am not sure if this tutorial is still actual.

  • #211 Miguel Grinberg said 2014-06-13T05:33:22Z

    @Pawel: see this post for info on the state of this tutorial: http://blog.miguelgrinberg.com/post/my-flask-web-development-book-is-out

  • #212 Krishna Shukla said 2014-06-16T11:16:30Z

    does this installation work just fine with python 3.4? i have run into problems; error:the virtualenv is not compatible with this system. What might be the problem?

  • #213 Miguel Grinberg said 2014-06-16T15:39:47Z

    @Krishna: No, this tutorial was written for Python 2 a couple of years ago (Flask did not support Python 3 then).

  • #214 Chris Kavanagh said 2014-06-17T07:03:48Z

    I noticed a difference in some boilerplate code between the book and this tutorial. In this tutorial you create an "init.py" file and then a "run.py" file in different folders. In the book this is NOT done, and everything is in one .py file. . .Now I noticed somewhere o n your blog you said this tutorial is getting a bit dated, so my question is, which way is the conventional way of structuring your project? The tutorial way, or the way it's done in the (wonderful) book?

  • #215 Charles Mims said 2014-06-17T11:51:53Z

    Excellent tutorial in terms of writing style and content. I'm curious to see how much has changed since it was published two years ago. One thing that I've spotted so far is the virtualenv command. I believe it is now "virtualenv flask" instead of "python virtualenv.py flask". I could be mistaken from context.

  • #216 Charles Mims said 2014-06-17T11:53:07Z

    The captcha tool on here appears broken. It prompts to type the two words, but only shows a picture of a street address and sometimes static.

  • #217 Miguel Grinberg said 2014-06-19T05:30:29Z

    @Chris: there is no "conventional" way, unlike other frameworks, Flask leaves the application structure to be decided by the developer. You are going to find several differences between these tutorials and the book. For starters, the tutorials are two years old and were written back when Flask only supported Python 2, while the project featured in the book is more modern, it uses the latest version of Flask and runs on Python 2 and Python 3. If you have access to both then you should look at the book in places where the two differ.

  • #218 Miguel Grinberg said 2014-06-19T05:33:44Z

    @Charles: there are a few minor changes, but if you run the versions of packages that I used back then very little should change, if anything.

  • #219 Salam said 2014-06-21T23:07:40Z

    for who is use Pycharm with python 2.6 does he need to wrote all that because the Pycharm will do Static and templates directly when choose a flask project

  • #220 akash said 2014-06-30T06:34:14Z

    hello sir, i created the file and directory according to this tutorial. but i am getting error when i run run.py.

    my directory structure is like this:-

    \microblog run.py \flask \Include \Scripts \Lib \app init.py view.py

    its giving following error: from app import app ImportError: no module named app.

    i am not getting where i should put my run file. i am using windows

  • #221 Miguel Grinberg said 2014-07-02T18:39:20Z

    @akash: I recommend that you compare your files to my version on GitHub, here: https://github.com/miguelgrinberg/microblog/tree/v0.1

  • #222 JAY PRAKASH said 2014-07-03T10:24:17Z

    I just started using flask . I am trying render some data in template . like dict['x'] in template . but i am getting error UnicodeDecodeError: 'utf8' codec can't decode byte 0xf3 while same time i have enabled debug mode true so if i try to print dict['x'] then it's printing result. Please help me what is this error . I am using hack also reload(sys) sys.setdefaultencoding("UTF8") still not able to solve my error

  • #223 Miguel Grinberg said 2014-07-03T17:52:57Z

    @Jay: what is the value of dict['x']? Try making this a simple string w/o any special characters and see if that works. Or better yet, set dict['x'] to a Unicode string.

  • #224 Yecid said 2014-07-10T18:06:13Z

    Hi, Miguel I'm excited about you tutorial, but i Had a Problem. I use Windows, I create run.py on flask/Scripts folder. When I write "python run.py" it shows "Import error: No module name app" and when I use "/flask/Scripts/python run.py" it shows "flask is an unknown command" Am I doing missing something, please Help me! . Thanks

  • #225 Yecid said 2014-07-10T18:24:21Z

    when i use "flask\Scripts\python run.py" it shows "can't find main module in flask\Scripts" o.O