├── 02-templates ├── templates │ ├── index.html │ └── user.html ├── hello.py └── README.md ├── 05-structure ├── config_production.py ├── config_development.py ├── config_testing.py ├── app │ ├── hello │ │ ├── __init__.py │ │ └── routes.py │ ├── __init__.py │ └── templates │ │ └── hello │ │ └── index.html ├── manage.py ├── README.md └── tests │ └── test_basics.py ├── requirements.txt ├── 01-hello-world ├── hello.py └── README.md ├── 03-forms ├── hello.py ├── templates │ └── index.html └── README.md ├── 04-database ├── README.md ├── templates │ └── index.html └── hello.py ├── .gitignore ├── README.md └── LICENSE /02-templates/templates/index.html: -------------------------------------------------------------------------------- 1 |

Hello World!

2 | -------------------------------------------------------------------------------- /02-templates/templates/user.html: -------------------------------------------------------------------------------- 1 |

Hello, {{name}}!

2 | -------------------------------------------------------------------------------- /05-structure/config_production.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | DEBUG=False 4 | MONGO_URI=os.getenv['MONGO_URI'] 5 | -------------------------------------------------------------------------------- /05-structure/config_development.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | DEBUG=True 4 | MONGO_URI=os.environ['MONGO_DEV_URI'] 5 | -------------------------------------------------------------------------------- /05-structure/config_testing.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | DEBUG=False 4 | TESTING=True 5 | MONGO_URI=os.environ['MONGO_TEST_URI'] 6 | -------------------------------------------------------------------------------- /05-structure/app/hello/__init__.py: -------------------------------------------------------------------------------- 1 | from flask import Blueprint 2 | 3 | hello = Blueprint('hello', __name__) 4 | 5 | from . import routes 6 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | Flask==0.10.1 2 | Flask-PyMongo==0.3.0 3 | Flask-Script==2.0.3 4 | Jinja2==2.7.2 5 | MarkupSafe==0.21 6 | Werkzeug==0.9.4 7 | coverage==3.7.1 8 | itsdangerous==0.24 9 | nose==1.3.3 10 | pymongo==2.7 11 | -------------------------------------------------------------------------------- /01-hello-world/hello.py: -------------------------------------------------------------------------------- 1 | from flask import Flask 2 | app = Flask(__name__) 3 | 4 | @app.route('/') 5 | def index(): 6 | return "

Hello, World!

" 7 | 8 | @app.route('/user/') 9 | def user(name): 10 | return '

Hello, {0}!

'.format(name) 11 | 12 | if __name__ == '__main__': 13 | app.run(debug=True) 14 | 15 | -------------------------------------------------------------------------------- /02-templates/hello.py: -------------------------------------------------------------------------------- 1 | from flask import Flask, render_template 2 | app = Flask(__name__) 3 | 4 | @app.route('/') 5 | def index(): 6 | return render_template('index.html') 7 | 8 | @app.route('/user/') 9 | def user(name): 10 | return render_template('user.html', name=name) 11 | 12 | if __name__ == '__main__': 13 | app.run(debug=True) 14 | 15 | -------------------------------------------------------------------------------- /03-forms/hello.py: -------------------------------------------------------------------------------- 1 | from flask import Flask, render_template, request 2 | app = Flask(__name__) 3 | 4 | @app.route('/', methods=['GET', 'POST']) 5 | def index(): 6 | name = None 7 | if request.method == 'POST' and 'name' in request.form: 8 | name = request.form['name'] 9 | return render_template('index.html', name=name) 10 | 11 | if __name__ == '__main__': 12 | app.run(debug=True) 13 | 14 | -------------------------------------------------------------------------------- /03-forms/templates/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Flask Example 5 | 6 | 7 |
8 | What is your name? 9 | 10 |
11 | {% if name %} 12 |

Hello, {{name}}!

13 | {% endif %} 14 | 15 | 16 | -------------------------------------------------------------------------------- /03-forms/README.md: -------------------------------------------------------------------------------- 1 | Example 3 2 | ========= 3 | 4 | This example shows how a Flask application can work with web forms. 5 | 6 | Running the application 7 | ----------------------- 8 | 9 | To run this example follow these steps: 10 | 11 | - Activate a virtual environment that contains the packages in `../requirements.txt` 12 | - To start the application run the following command: 13 | 14 | (venv) $ python hello.py 15 | -------------------------------------------------------------------------------- /02-templates/README.md: -------------------------------------------------------------------------------- 1 | Example 2 2 | ========= 3 | 4 | This example shows how a Flask application can work with templates. 5 | 6 | Running the application 7 | ----------------------- 8 | 9 | To run this example follow these steps: 10 | 11 | - Activate a virtual environment that contains the packages in `../requirements.txt` 12 | - To start the application run the following command: 13 | 14 | (venv) $ python hello.py 15 | -------------------------------------------------------------------------------- /01-hello-world/README.md: -------------------------------------------------------------------------------- 1 | Example 1 2 | ========= 3 | 4 | This example shows a simple Flask application. 5 | 6 | Running the application 7 | ----------------------- 8 | 9 | To run this example follow these steps: 10 | 11 | - Activate a virtual environment that contains the packages in `../requirements.txt` 12 | - To start the application run the following command: 13 | 14 | (venv) $ python hello.py 15 | 16 | - Works fine with both Windows and Linux OS. 17 | 18 | -------------------------------------------------------------------------------- /05-structure/app/__init__.py: -------------------------------------------------------------------------------- 1 | import os 2 | from flask import Flask 3 | from flask.ext.pymongo import PyMongo 4 | 5 | mongo = PyMongo() 6 | 7 | def create_app(): 8 | config_name = os.environ.get('FLASK_CONFIG', 'development') 9 | 10 | app = Flask(__name__) 11 | app.config.from_object('config_' + config_name) 12 | 13 | mongo.init_app(app) 14 | 15 | from .hello import hello as hello_blueprint 16 | app.register_blueprint(hello_blueprint) 17 | 18 | return app 19 | -------------------------------------------------------------------------------- /04-database/README.md: -------------------------------------------------------------------------------- 1 | Example 4 2 | ========= 3 | 4 | This example shows how a Flask application can access a database. 5 | 6 | Running the application 7 | ----------------------- 8 | 9 | To run this example follow these steps: 10 | 11 | - Activate a virtual environment that contains the packages in `../requirements.txt` 12 | - Set a `MONGO_URI` environment variable to the MongoDB database for the application. 13 | - To start the application run the following command: 14 | 15 | (venv) $ python hello.py 16 | -------------------------------------------------------------------------------- /05-structure/manage.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import os 3 | from app import create_app 4 | from flask.ext.script import Manager 5 | 6 | manager = Manager(create_app) 7 | 8 | @manager.command 9 | def test(): 10 | from subprocess import call 11 | 12 | os.environ['FLASK_CONFIG'] = 'testing' 13 | call(['nosetests', '-v', 14 | '--with-coverage', '--cover-package=app', '--cover-branches', 15 | '--cover-erase', '--cover-html', '--cover-html-dir=cover']) 16 | 17 | if __name__ == '__main__': 18 | manager.run() 19 | -------------------------------------------------------------------------------- /04-database/templates/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Flask Example 5 | 6 | 7 |
8 | What is your name? 9 | 10 |
11 | {% if name %} 12 |

Hello, {{name}}!

13 | {% if new %} 14 |

Nice to meet you!

15 | {% else %} 16 |

Great to see you again!

17 | {% endif %} 18 | {% endif %} 19 | 20 | 21 | -------------------------------------------------------------------------------- /05-structure/app/templates/hello/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Flask Example 5 | 6 | 7 |
8 | What is your name? 9 | 10 |
11 | {% if name %} 12 |

Hello, {{name}}!

13 | {% if new %} 14 |

Nice to meet you!

15 | {% else %} 16 |

Great to see you again!

17 | {% endif %} 18 | {% endif %} 19 | 20 | 21 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.py[cod] 2 | 3 | # C extensions 4 | *.so 5 | 6 | # Packages 7 | *.egg 8 | *.egg-info 9 | dist 10 | build 11 | eggs 12 | parts 13 | bin 14 | var 15 | sdist 16 | develop-eggs 17 | .installed.cfg 18 | lib 19 | lib64 20 | __pycache__ 21 | 22 | # Installer logs 23 | pip-log.txt 24 | 25 | # Unit test / coverage reports 26 | .coverage 27 | .tox 28 | nosetests.xml 29 | 30 | # Translations 31 | *.mo 32 | 33 | # Mr Developer 34 | .mr.developer.cfg 35 | .project 36 | .pydevproject 37 | 38 | # SQLite databases 39 | *.sqlite 40 | 41 | # Virtual environment 42 | venv 43 | 44 | # Coverage 45 | cover 46 | -------------------------------------------------------------------------------- /05-structure/app/hello/routes.py: -------------------------------------------------------------------------------- 1 | from flask import request, render_template 2 | from . import hello 3 | from .. import mongo 4 | 5 | @hello.route('/', methods=['GET', 'POST']) 6 | def index(): 7 | name = None 8 | new = False 9 | if request.method == 'POST' and 'name' in request.form: 10 | name = request.form['name'] 11 | if mongo.db.names.find_one({'name': name}) is None: 12 | # this is a new name, add it to the database 13 | mongo.db.names.insert({'name': name}) 14 | new = True 15 | return render_template('hello/index.html', name=name, new=new) 16 | -------------------------------------------------------------------------------- /04-database/hello.py: -------------------------------------------------------------------------------- 1 | import os 2 | from flask import Flask, render_template, request 3 | from flask.ext.pymongo import PyMongo 4 | 5 | app = Flask(__name__) 6 | app.config['MONGO_URI'] = os.environ['MONGO_URI'] 7 | mongo = PyMongo(app) 8 | 9 | @app.route('/', methods=['GET', 'POST']) 10 | def index(): 11 | name = None 12 | new = False 13 | if request.method == 'POST' and 'name' in request.form: 14 | name = request.form['name'] 15 | if mongo.db.names.find_one({'name': name}) is None: 16 | # this is a new name, add it to the database 17 | mongo.db.names.insert({'name': name}) 18 | new = True 19 | return render_template('index.html', name=name, new=new) 20 | 21 | if __name__ == '__main__': 22 | app.run(debug=True) 23 | 24 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Python Web Development with Flask 2 | ================================= 3 | 4 | This repository contains the source code that I demonstrate in my "Python Web Development with Flask" presentation. 5 | 6 | Requirements 7 | ------------ 8 | 9 | To install and run these examples you need: 10 | 11 | - Python 2.7 or 3.3+ 12 | - virtualenv (not required if you are using Python 3.4) 13 | - git (only to clone this repository) 14 | 15 | Installation 16 | ------------ 17 | 18 | The commands below set everything up to run the examples: 19 | 20 | $ git clone https://github.com/miguelgrinberg/flask-examples.git 21 | $ cd flask-examples 22 | $ virtualenv venv 23 | $ . venv/bin/activate 24 | (venv) pip install -r requirements.txt 25 | 26 | Note for Python 3.4 users: replace `virtualenv` with `pyvenv`. 27 | 28 | Note for Microsoft Windows users: replace the virtual environment activation command above with `venv\Scripts\activate`. 29 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Miguel Grinberg 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /05-structure/README.md: -------------------------------------------------------------------------------- 1 | Example 5 2 | ========= 3 | 4 | This example shows a scalable application structure. 5 | 6 | Running the application 7 | ----------------------- 8 | 9 | To run this example follow these steps: 10 | 11 | - Activate a virtual environment that contains the packages in `../requirements.txt` 12 | - Set a `FLASK_CONFIG` environment variable to `development` or `production` to select the proper configuration. If this variable is not set `development` is used by default. 13 | - Set a `MONGO_DEV_URI` (development) or `MONGO_URI` (production) environment variable to the MongoDB database for the application. 14 | - To start the application run the following command: 15 | 16 | (venv) $ python manage.py runserver 17 | 18 | Running the test suite 19 | ---------------------- 20 | 21 | This application contains unit tests, which can be executed with the following steps: 22 | 23 | - Set a `MONGO_TEST_URI` environment variable to the MongoDB database used for testing. Do not use the development or production databases here, as the tests will destroy their contents. 24 | - Run the tests with the following command: 25 | 26 | (venv) $ python manage.py test 27 | -------------------------------------------------------------------------------- /05-structure/tests/test_basics.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | from flask import current_app 3 | from app import create_app, mongo 4 | 5 | 6 | class BasicsTestCase(unittest.TestCase): 7 | def setUp(self): 8 | self.app = create_app() 9 | self.app_context = self.app.app_context() 10 | self.app_context.push() 11 | self.client = self.app.test_client() 12 | 13 | def tearDown(self): 14 | for c in mongo.db.collection_names(False): 15 | print(c) 16 | mongo.db.drop_collection(c) 17 | self.app_context.pop() 18 | 19 | def test_app_exists(self): 20 | self.assertFalse(current_app is None) 21 | 22 | def test_app_is_testing(self): 23 | self.assertTrue(current_app.config['TESTING']) 24 | 25 | def test_names(self): 26 | response = self.client.get('/') 27 | self.assertTrue(response.status_code == 200) 28 | self.assertTrue(b'What is your name?' in response.data) 29 | 30 | response = self.client.post('/', data={'name': 'dave'}) 31 | self.assertTrue(response.status_code == 200) 32 | self.assertTrue(b'Hello, dave' in response.data) 33 | self.assertTrue(b'Nice to meet you' in response.data) 34 | 35 | response = self.client.post('/', data={'name': 'dave'}) 36 | self.assertTrue(response.status_code == 200) 37 | self.assertTrue(b'Hello, dave' in response.data) 38 | self.assertTrue(b'Great to see you again' in response.data) 39 | --------------------------------------------------------------------------------