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

  • #251 Stephanie said 2014-10-18T09:37:51Z

    @Miguel Ahh, I've been writing out all the code myself that I didn't even download the project. Kudos! And thanks for writing this. Has tremendously helped me get onboard pretty quickly.

  • #252 Jack said 2014-10-21T02:19:01Z

    Hey, thanks for the tutorial, its great!! I got a question.... currently i setup my virtual env by mkdir test, then virtualenv test, then cd test, then source bin/activate, then mkdir workplace, cd workplace, then add the files you specify like so: - workplace - run.py - app - init.py - views.py - static - templates - tmp

    and I run it by simply python run.py and i get an ip which gives me hello world. It also gives me .pyc files for both init and views, I was curious what those are and why it made them? I am also curious what the difference is between running the code the way you specified vs the way I did? did I run it incorrectly? I was unable to run the code your way. Lastly is my file structure correct? and am I running virtual env correctly? when I am finished working in the python space I say "deactivate" and it leaves the virtual space, i believe.. I am just curious, I am trying to learn flask, any questions answered would be much appreciated!!

    thanks!

  • #253 Miguel Grinberg said 2014-10-22T06:25:32Z

    The .pyc files are compiled python files. They enable the Python interpreter to load files faster, as it prevents files that have been compiled already from having to get compiled every time they run.

    I think you are putting the entire application inside the virtualenv, that is a pretty odd structure, typically it is the reverse, you have the virtualenv inside the root application folder. What problem do you have when using my recommended structure?

  • #254 Rimte Rocher said 2014-10-22T14:21:59Z

    Is it possible to run this without the virtualenv? I mean without having to create a virtual env and stuff.. Thanks

  • #255 Miguel Grinberg said 2014-10-22T21:16:44Z

    @Rimte: you can, sure, but it is not a good idea. You will be installing all the Flask packages in your system interpreter.

  • #256 ashwin said 2014-10-27T06:31:30Z

    I followed all your steps, but I am getting the following error: Traceback (most recent call last): File "./run.py", line 2, in from app import app File "/home/netman/flask_test/app/init.py", line 1, in from flask import Flask ImportError: No module named flask

    I am running flask on my ubuntu vmware. Please help

  • #257 Miguel Grinberg said 2014-10-27T06:45:12Z

    @ashwin: make sure you run the script using the python interpreter from the virtual environment, and also make sure you have installed Flask in it.

  • #258 Andrew said 2014-10-31T16:01:47Z

    $ python -m venv flask This command did not work for me instead I used: $ python3 -m venv flask

  • #259 Miguel Grinberg said 2014-11-01T00:03:08Z

    @Andrew: in many operating systems the default Python interpreter is Python 2.x. These install Python 3 as "python3", so what you did is correct. I'm going to add a note in the article about this.

  • #260 fird0s said 2014-11-09T11:28:22Z

    HI, i have file upload, usually Flask store file uploads in /static/uploads. but i want file upload different folder, like make new dir /media in root app path, how to access that /media dir ?

  • #261 Miguel Grinberg said 2014-11-09T19:18:07Z

    @fird0s: your question is really unrelated to this tutorial. Have you tried StackOverflow?

  • #262 Carl said 2014-11-10T16:39:26Z

    Awesome tutorial Miguel, thanks a lot!

    I decided to install the flask folder in my Dropbox so that I can work on this Flask project from two different computers, namely PC and laptop.

    I initially configured everything from my PC. The process was smooth. I run the "run.py" script from my PC and it works flawlessly.

    But when I repeat the exact same process from my laptop (to get to see the "Hello, World!" in Firefox), the Command Prompt gives me the following error message:

    "python: can't open file 'run.py': [Errno 2] No such file or directory"

    Any thoughts on what could be done to solve this issue and allow me to work on this flask project (hosted on Dropbox) from both my PC and my laptop?

    For the records, the PC runs with Windows 8 and the laptop Windows 7.

    Thanks!

  • #263 Grace said 2014-11-11T09:47:24Z

    Hi,

    I'm having some trouble getting this working. Python isn't looking for the modules in the right place. For example, when run.py calls init.py, I get "ImportError: No module named flask". I had originally created my project on a Windows machine and I was able to run "flask\Scripts\Python run.py" and it worked fine. However I have now copied my project over onto a Linux virtual machine and I am trying to run ./run.py, but again I keep getting the error message "ImportError: No module named flask." Do you know how I can resolve this?

    Thanks

  • #264 Miguel Grinberg said 2014-11-11T19:38:22Z

    @Carl: not sure, but one thing I know can be a source of problems is reusing a virtual environment on two computers. Make a brand new virtualenv on your second computer (using a different name than "flask") and hopefully that'll do it.

  • #265 Miguel Grinberg said 2014-11-12T07:30:32Z

    @Grace: have you created a virtual environment and installed flask into it? Try running:

    $ flask/bin/pip install flask

    Then run ./run.py again.

  • #266 Menuka said 2014-11-16T01:56:38Z

    for me, flask installaiton commands didn't work for me. However, flask web site has the following commands. $ mkdir myproject $ cd myproject $ virtualenv venv New python executable in venv/bin/python Installing distribute............done.

    which helped me to fix the issue... Thanks for the tutorial

  • #267 David Terwilliger said 2014-11-28T15:37:06Z

    Hey, I'm in the very early steps of following this tutorial.

    the command python virtualenv.py flask didn't work for me: No such module exists. sudo virtualenv flask did work.

  • #268 Miguel Grinberg said 2014-11-28T22:40:00Z

    @David: sorry about that, I missed an update to that command when I ported this tutorial to also support Python 3. The correct command is "virtualenv flask", see above for the correction.

  • #269 Maria said 2014-12-06T18:03:38Z

    For the complete noobs like me the command: $ flask/bin/pip install flask is incorrect, if you are copy pasting you should edit it like so: $ flask/bin/ pip install flask as "pip" is a command.

  • #270 Miguel Grinberg said 2014-12-07T01:19:41Z

    @Maria: No, you are incorrect. The command does not use a space before "pip". If you create a virtual environment named "flask", then pip is in located in directory flask/bin, so you can invoke it by saying "flask/bin/pip". Another option is to activate the environment, and then you can just say "pip", since the flask/bin directory will be added to your PATH.

  • #271 wandonye said 2014-12-16T17:04:20Z

    Hi, Thanks a lot for the great work. I wonder is it possible to use conda instead of virtualenv in this tutorial? I have Conda, when I tried to install virtualenv, Conda reported conflict. So I don't have virtualenv. Thanks~!

  • #272 Miguel Grinberg said 2014-12-17T17:29:25Z

    @wandonye: as long as you install the required packages you should be fine, there is nothing specifically tied to virtualenvs in this tutorial.

  • #273 dlb said 2014-12-23T21:25:05Z

    I also got "ImportError: No module named app." on FreeBSD running python2.7. The problem for me was typing a single underscore: init.py Rather than a double: init.py

  • #274 Matt Gabor said 2014-12-24T10:18:33Z

    Hi Miguel, Having issues when trying to execute run.py (followed the rest of your instructions)

    I get this error:

    mydirectories/flask/lib/python3.4/site-packages/werkzeug/http.py", line 26, in from urllib2 import parse_http_list as _parse_list_header ImportError: No module named 'urllib2'

    Along with a whole slew of errors after. I'm using Mac OS X Yosemite.

  • #275 Miguel Grinberg said 2014-12-24T17:58:09Z

    @Matt: I'm going to guess that your Python 3.4 isn't correctly installed, it seems it is not able to find urllib2, which is part of the Python standard library.