The Flask Mega-Tutorial, Part I: Hello, World!
Posted byon under
(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:
- Part I: Hello, World! (this article)
- Part II: Templates
- Part III: Web Forms
- Part IV: Database
- Part V: User Logins
- Part VI: Profile Page And Avatars
- Part VII: Unit Testing
- Part VIII: Followers, Contacts And Friends
- Part IX: Pagination
- Part X: Full Text Search
- Part XI: Email Support
- Part XII: Facelift
- Part XIII: Dates and Times
- Part XIV: I18n and L10n
- Part XV: Ajax
- Part XVI: Debugging, Testing and Profiling
- Part XVII: Deployment on Linux (even on the Raspberry Pi!)
- Part XVIII: Deployment on the Heroku Cloud
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 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.
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.
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
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
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!
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
app folder will be where we will put our application package. 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
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
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
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
/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:
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:
Alternatively you can use the following URL:
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:
Note that you still need to install Flask as indicated above before you can run the application.
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.
Become a Patron!
Hello, and thank you for visiting my blog! If you enjoyed this article, please consider supporting my work on this blog on Patreon!
#1 Alexander Manenko said 2012-05-13T12:45:29Z
Hello, thank you for your article. It is definitely a good starting point for beginner like I am. However, I found one misprint here:
from Flask import Flask
This should be
from flask import Flask
#2 Miguel Grinberg said 2012-05-13T15:24:48Z
Alexander, thanks for letting me know, I have corrected the error now.
#3 twrivera said 2012-07-12T20:02:14Z
Good Job!!! Me likes and thx for doing this
#4 drew said 2012-08-23T00:29:42Z
Wounderful, thanks for sharing this.
#5 drew said 2012-09-11T03:53:32Z
You said :"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. I personally do not like this feature.."
Can you explain why?
#6 Miguel Grinberg said 2012-09-11T05:19:18Z
@drew: There is nothing wrong with activating virtualenvs, it's just that the feature does not work for me. I typically need to switch between two or more environments, so I've found that if I get used to having an "active" virtualenv I end up forgetting to activate another one when I need to switch and end up mixing up virtual environments. Once I got used to explicitly invoke the python interpreter I want I stopped making these kinds of mistakes. On Linux/OS X/Cygwin it is really not much different, since the interpreter is in the shebang line of the scripts. Since all my virtualenvs have the same relative path to my scripts I can even copy scripts between projects and the scripts always find the project specific virtualenv.
#7 Alex said 2012-09-30T16:50:49Z
Wonderful tutorial. I keep running into an issue though, 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 can force it to find flask with sys.path.append(flask_path) but that seems like a crude hack. Is there a better way of managing the environment this module operates in? Maybe some virtualenv setting?
I'm working on a Windows XP machine. My folder structure matches my understanding of your structure:
#8 Miguel Grinberg said 2012-09-30T17:38:41Z
#9 Alex said 2012-09-30T18:10:31Z
You are right! Thank you, I'm new to virtualenv.
#10 Catherine Penfold said 2012-10-29T17:27:22Z
so I am starting afresh to try to get things working with the flask-WTF. I have followed your instructions incl 'flask\Scripts\pip install flask-wtf' should this now be visible somewhere. Also ./run.py does not work from the microblog directory, but python run.py does. Should this file be put elsewhere?
#11 Catherine Penfold said 2012-10-29T17:35:57Z
Just another quick note, I think everything installed OK, here's the path to flask_wtf:
- would be handy to know why the ./run.py command is not working though -thanks
#13 Catherine Penfold said 2012-10-30T16:53:35Z
I am interested to know what was your motivation in creating this tutorial?
#14 Miguel Grinberg said 2012-10-31T05:32:18Z
@Catherine: I'm just writing the kind of tutorial that I would have loved to have found a few years ago when I embarked on my first web project :)
#15 Marcin said 2012-11-01T17:39:59Z
Hi, good art. However I've got not clue how to make to work with some others files. For example have script in file: script.py. where should I put this file?
#16 Miguel Grinberg said 2012-11-01T19:49:53Z
@Marcin: you may want to find a general purpuse Python tutorial that can teach you the basics of dealing with script files. This tutorial is for a specific type of application.
#17 Sanjay Mavinkurve said 2012-11-27T06:33:54Z
run.py should be placed in the microblog directory. I had it in the app directory and it didn't work.
#18 Miguel Grinberg said 2012-11-27T06:50:42Z
@Sanjay: yes, that's correct. Note that your current directory should be microblog when working on the app. All the pathnames I show are relative to that path. Any filenames that have no path (like run.py) should be located in the current directory.
#19 Edwin said 2012-12-14T14:21:36Z
I am having an issue with the number of parameters for __init___, and couldn't really find the problem. I was just going to start the "Unit testing framework" part, but before I wanted to test the page and when I try to edit my profile it gets me this error:
#20 Miguel Grinberg said 2012-12-23T00:02:20Z
@Edwin: you will need to look in the stack trace that you get to find out exactly what part of the application is calling this init function with less arguments than necessary.
#21 Gator said 2012-12-28T21:47:14Z
First, thanks for this tutorial. I find the documentation pretty good for Flask, but your tutorial is much more digestable for a newbie.
When I try to use the script to activate the webserver, I am getting this message:
-bash: ./run.py: flask/bin/python: bad interpreter: No such file or directory
When I run it using "python run.py", I get:
Traceback (most recent call last):
File "run.py", line 2, in <module>
from app import app
ImportError: No module named app
I think my folder structure is not like yours, if the previous commenter is correct.
My app structure looks like this: microblog > app > init.py | run.py | views.py
#22 Guilherme Rezende said 2012-12-30T01:49:18Z
Good post Miguel!!
About virtualenv, you tried virtualenvwrapper?
you use command 'workon' to switch between enviroments.
#23 Miguel Grinberg said 2012-12-31T17:51:07Z
@Gator: did you setup a virtualenv as indicated in the article? The error suggests you don't have it setup as indicated. Please review the section above titled "Installing Flask".
#24 Adam said 2013-01-04T17:08:20Z
Hi i have done everything as sad but when i run the run.py in the scrips directory i get the following error im using windows 7
ImportError: No module named app.
thank you for the tutorial
#25 Miguel Grinberg said 2013-01-05T03:54:43Z