writing your first web app using python and flask
DESCRIPTION
This tutorial will help you create your first webapp using Python and the Flask microframework. We will cover the following topics: * What is Flask and why would you use it * Rendering your first response * Handling forms and POST data * Using SQLAlchemy * Writing your first RESTful API * Holding open a connection to emit updates * Testing your app with py.test * Deploying to Redhat's Openshift platform Familiarity with Python is assumed. A passing familiarity with Javascript is recommended by not essential. https://github.com/danni/linux-conf-au-flask-tute http://mirror.linux.org.au/linux.conf.au/2014/Thursday/87-Writing_your_first_web_app_using_Python_and_Flask_-_Danielle_Madeley.mp4TRANSCRIPT
![Page 1: Writing your first web app using Python and Flask](https://reader036.vdocuments.us/reader036/viewer/2022082309/547ea27ab379594e2b8b54cc/html5/thumbnails/1.jpg)
Writing your firstweb app usingPython and Flask
Danielle Madeley, Infoxchange blogs.gnome.org/danni dannipenguin
flickr.com/photos/kevinomara/7695277030
![Page 2: Writing your first web app using Python and Flask](https://reader036.vdocuments.us/reader036/viewer/2022082309/547ea27ab379594e2b8b54cc/html5/thumbnails/2.jpg)
If you haven't already...git clone
git://github.com/danni/linux-conf-au-flask-tute
Follow the README to set up yourenvironment
![Page 3: Writing your first web app using Python and Flask](https://reader036.vdocuments.us/reader036/viewer/2022082309/547ea27ab379594e2b8b54cc/html5/thumbnails/3.jpg)
What is Flask and why would you use itRendering your first responseHandling forms and POST dataUsing SQLAlchemyWriting your first RESTful APIHolding open a connection to emit updatesTesting your app with py.testDeploying to Redhat's Openshift platform
![Page 4: Writing your first web app using Python and Flask](https://reader036.vdocuments.us/reader036/viewer/2022082309/547ea27ab379594e2b8b54cc/html5/thumbnails/4.jpg)
import cgi Just kidding!
![Page 5: Writing your first web app using Python and Flask](https://reader036.vdocuments.us/reader036/viewer/2022082309/547ea27ab379594e2b8b54cc/html5/thumbnails/5.jpg)
Just what is Flask?
flickr.com/photos/markstos/3579118891
![Page 6: Writing your first web app using Python and Flask](https://reader036.vdocuments.us/reader036/viewer/2022082309/547ea27ab379594e2b8b54cc/html5/thumbnails/6.jpg)
Rendering yourfirst response
![Page 7: Writing your first web app using Python and Flask](https://reader036.vdocuments.us/reader036/viewer/2022082309/547ea27ab379594e2b8b54cc/html5/thumbnails/7.jpg)
#!/usr/bin/env python
from flask import Flask
app = Flask(__name__)
if __name__ == '__main__': app.run(debug=True)
![Page 8: Writing your first web app using Python and Flask](https://reader036.vdocuments.us/reader036/viewer/2022082309/547ea27ab379594e2b8b54cc/html5/thumbnails/8.jpg)
#!/usr/bin/env python
from flask import Flask
app = Flask(__name__)
@app.route('/')def index(): """Homepage"""
return "Hello, linux.conf.au"
if __name__ == '__main__': app.run(debug=True)
![Page 9: Writing your first web app using Python and Flask](https://reader036.vdocuments.us/reader036/viewer/2022082309/547ea27ab379594e2b8b54cc/html5/thumbnails/9.jpg)
x â pythonÿenv�bin�activatex git checkout example÷ÎÏx pip install ÷r requirementsâtxtx python webapp�ÿÿinitÿÿâpy
![Page 10: Writing your first web app using Python and Flask](https://reader036.vdocuments.us/reader036/viewer/2022082309/547ea27ab379594e2b8b54cc/html5/thumbnails/10.jpg)
from flask import redirect, render_template
@app.route('/a-redirect')def a_redirect(): """Redirect the user"""
return redirect(SOME_URL)
@app.route('/a-template')def a_template(): """Render a page using a Jinga2 template"""
return render_template('template.html')
![Page 11: Writing your first web app using Python and Flask](https://reader036.vdocuments.us/reader036/viewer/2022082309/547ea27ab379594e2b8b54cc/html5/thumbnails/11.jpg)
By default: templates arelocated in the module'stemplates/ directory:
webapp/__init__.pytemplates/
template.html
![Page 12: Writing your first web app using Python and Flask](https://reader036.vdocuments.us/reader036/viewer/2022082309/547ea27ab379594e2b8b54cc/html5/thumbnails/12.jpg)
x git checkout example÷ÎÐx pip install ÷r requirementsâtxtx python webapp�ÿÿinitÿÿâpy
![Page 13: Writing your first web app using Python and Flask](https://reader036.vdocuments.us/reader036/viewer/2022082309/547ea27ab379594e2b8b54cc/html5/thumbnails/13.jpg)
handling querystrings
![Page 14: Writing your first web app using Python and Flask](https://reader036.vdocuments.us/reader036/viewer/2022082309/547ea27ab379594e2b8b54cc/html5/thumbnails/14.jpg)
from flask import request
@app.route('/')def index(): """Return the name query argument"""
return request.args['name']
![Page 15: Writing your first web app using Python and Flask](https://reader036.vdocuments.us/reader036/viewer/2022082309/547ea27ab379594e2b8b54cc/html5/thumbnails/15.jpg)
or doing itRESTfully
![Page 16: Writing your first web app using Python and Flask](https://reader036.vdocuments.us/reader036/viewer/2022082309/547ea27ab379594e2b8b54cc/html5/thumbnails/16.jpg)
@app.route('/item/<int:pk>')def get_item(pk): """Return the item referred to by pk"""
# ...
![Page 17: Writing your first web app using Python and Flask](https://reader036.vdocuments.us/reader036/viewer/2022082309/547ea27ab379594e2b8b54cc/html5/thumbnails/17.jpg)
?ou=Linux+Australia&ou=linux.conf.aurequestâargs�ëouë� �� ëLinux Australiaërequestâargsâgetlist�ëouë� �� �ëLinux Australiaëã ëlinuxâconfâauë� requestâargs�ënot presentë� raises KeyErrorrequestâargsâgetlist�ënot presentë� �� ��
![Page 18: Writing your first web app using Python and Flask](https://reader036.vdocuments.us/reader036/viewer/2022082309/547ea27ab379594e2b8b54cc/html5/thumbnails/18.jpg)
handling forms andPOST data
![Page 19: Writing your first web app using Python and Flask](https://reader036.vdocuments.us/reader036/viewer/2022082309/547ea27ab379594e2b8b54cc/html5/thumbnails/19.jpg)
from flask import request
@app.route('/')def index(): """Return the name POST value"""
return request.form['name']
![Page 20: Writing your first web app using Python and Flask](https://reader036.vdocuments.us/reader036/viewer/2022082309/547ea27ab379594e2b8b54cc/html5/thumbnails/20.jpg)
or better still use aforms library
pip install Flask÷WTF
![Page 21: Writing your first web app using Python and Flask](https://reader036.vdocuments.us/reader036/viewer/2022082309/547ea27ab379594e2b8b54cc/html5/thumbnails/21.jpg)
from flask import Flask, render_templatefrom flask.ext.wtf import Form
from wtforms import TextField
class RegoForm(Form): """A simple rego form"""
email = TextField('Email')
@app.route('/register', methods=('GET', 'POST'))def get_register(): """Handle the registration form"""
form = RegoForm()
if form.validate_on_submit(): return "Success"
return render_template('template.html', form=form)
if __name__ == '__main__': app.secret_key = 'THIS IS REALLY SECRET' app.run(debug=True)
![Page 22: Writing your first web app using Python and Flask](https://reader036.vdocuments.us/reader036/viewer/2022082309/547ea27ab379594e2b8b54cc/html5/thumbnails/22.jpg)
from flask.ext.wtf import Form
from wtforms import TextField, validators
class RegoForm(Form): """A simple rego form"""
email = TextField('Email' validators=(validators.DataRequired(), validators.Email()))
![Page 23: Writing your first web app using Python and Flask](https://reader036.vdocuments.us/reader036/viewer/2022082309/547ea27ab379594e2b8b54cc/html5/thumbnails/23.jpg)
<form method="post"> {{ form.hidden_tag() }} {# for CSRF.. important! #} {{ form.email.label }} {{ form.email }} {% if form.email.errors %} <ul> {% for error in form.email.errors %} <li>{{ error }}</li> {% endfor %} </ul> {% endif %} <input type="submit"></form>
![Page 24: Writing your first web app using Python and Flask](https://reader036.vdocuments.us/reader036/viewer/2022082309/547ea27ab379594e2b8b54cc/html5/thumbnails/24.jpg)
SQL alchemy pip install Flask÷SQLAlchemy
![Page 25: Writing your first web app using Python and Flask](https://reader036.vdocuments.us/reader036/viewer/2022082309/547ea27ab379594e2b8b54cc/html5/thumbnails/25.jpg)
from flask.ext.sqlalchemy import SQLAlchemy
db = SQLAlchemy(app)
class User(db.Model): """A user in my database"""
__tablename__ = 'users'
id = db.Column(db.Integer, primary_key=True)
# ...
![Page 26: Writing your first web app using Python and Flask](https://reader036.vdocuments.us/reader036/viewer/2022082309/547ea27ab379594e2b8b54cc/html5/thumbnails/26.jpg)
if __name__ == "__main__": app.config['SQLALCHEMY_DATABASE_URI'] = \ 'postgresql://username:password@localhost/myapp' app.run(debug=True)
![Page 27: Writing your first web app using Python and Flask](https://reader036.vdocuments.us/reader036/viewer/2022082309/547ea27ab379594e2b8b54cc/html5/thumbnails/27.jpg)
user = db.session.query(User)\ .filter(User.user_id == user_id)\ .one()
![Page 28: Writing your first web app using Python and Flask](https://reader036.vdocuments.us/reader036/viewer/2022082309/547ea27ab379594e2b8b54cc/html5/thumbnails/28.jpg)
+ migrations(with Alembic)
pip install Flask÷Migrate
![Page 29: Writing your first web app using Python and Flask](https://reader036.vdocuments.us/reader036/viewer/2022082309/547ea27ab379594e2b8b54cc/html5/thumbnails/29.jpg)
Detour:
Flask-Script
![Page 30: Writing your first web app using Python and Flask](https://reader036.vdocuments.us/reader036/viewer/2022082309/547ea27ab379594e2b8b54cc/html5/thumbnails/30.jpg)
from flask import Flaskfrom flask.ext.script import Manager
app = Flask(__name__)manager = Manager(app)
if __name__ == '__main__': manager.run()
![Page 31: Writing your first web app using Python and Flask](https://reader036.vdocuments.us/reader036/viewer/2022082309/547ea27ab379594e2b8b54cc/html5/thumbnails/31.jpg)
x python ÿÿinitÿÿâpyusageä ÿÿinitÿÿâpy �÷h� �shellãrunserver� âââ
positional argumentsä �shellãrunserver� shell Runs a Python shell inside Flask application contextâ runserver Runs the Flask development server iâeâ appârun��
optional argumentsä ÷hã ÷÷help show this help message and exit
x python ÿÿinitÿÿâpy runserver � Running on httpä��ÏÐÕâÎâÎâÏäÓÎÎÎ� � Restarting with reloader
![Page 32: Writing your first web app using Python and Flask](https://reader036.vdocuments.us/reader036/viewer/2022082309/547ea27ab379594e2b8b54cc/html5/thumbnails/32.jpg)
from flask import Flaskfrom flask.ext.migrate import Migrate, MigrateCommandfrom flask.ext.script import Managerfrom flask.ext.sqlalchemy import SQLAlchemy
app = Flask(__name__)
manager = Manager(app)
db = SQLAlchemy(app)
migrate = Migrate(app, db)manager.add_command('db', MigrateCommand)
![Page 33: Writing your first web app using Python and Flask](https://reader036.vdocuments.us/reader036/viewer/2022082309/547ea27ab379594e2b8b54cc/html5/thumbnails/33.jpg)
x python webapp�ÿÿinitÿÿâpy db initx git add migrations
![Page 34: Writing your first web app using Python and Flask](https://reader036.vdocuments.us/reader036/viewer/2022082309/547ea27ab379594e2b8b54cc/html5/thumbnails/34.jpg)
x python webapp�ÿÿinitÿÿâpy db migratex git add migrations�versionsx python webapp�ÿÿinitÿÿâpy db upgrade
![Page 35: Writing your first web app using Python and Flask](https://reader036.vdocuments.us/reader036/viewer/2022082309/547ea27ab379594e2b8b54cc/html5/thumbnails/35.jpg)
Tie it all together so far:
Models and Forms
![Page 36: Writing your first web app using Python and Flask](https://reader036.vdocuments.us/reader036/viewer/2022082309/547ea27ab379594e2b8b54cc/html5/thumbnails/36.jpg)
from flask.ext.wtf import Form
from wtforms.ext.sqlalchemy.orm import model_form
class User(db.Model): """A user"""
__tablename__ = 'users'
id = db.Column(db.Integer, primary_key=True) email = db.Column(db.String(256), unique=True)
UserForm = model_form(User, base_class=Form)
![Page 37: Writing your first web app using Python and Flask](https://reader036.vdocuments.us/reader036/viewer/2022082309/547ea27ab379594e2b8b54cc/html5/thumbnails/37.jpg)
from flask.ext.wtf import Form
from wtforms import validatorsfrom wtforms.ext.sqlalchemy.orm import model_form
UserForm = model_form(User, base_class=Form, field_args={ 'email': { 'validators': [validators.Email()], },})
![Page 38: Writing your first web app using Python and Flask](https://reader036.vdocuments.us/reader036/viewer/2022082309/547ea27ab379594e2b8b54cc/html5/thumbnails/38.jpg)
from flask import Flask, request, render_template, redirect, url_for
@app.route('/register', methods=('GET', 'POST'))def register(): """Register a new user"""
obj = User() form = UserForm(request.form, obj)
if form.validate_on_submit(): form.populate_obj(obj) db.session.add(obj) db.session.commit()
return redirect(url_for('register'))
return render_template('template.html', form=form, users=User.query.all())
![Page 39: Writing your first web app using Python and Flask](https://reader036.vdocuments.us/reader036/viewer/2022082309/547ea27ab379594e2b8b54cc/html5/thumbnails/39.jpg)
Emitting events(and other streams)
![Page 40: Writing your first web app using Python and Flask](https://reader036.vdocuments.us/reader036/viewer/2022082309/547ea27ab379594e2b8b54cc/html5/thumbnails/40.jpg)
Detour:
Generators
![Page 41: Writing your first web app using Python and Flask](https://reader036.vdocuments.us/reader036/viewer/2022082309/547ea27ab379594e2b8b54cc/html5/thumbnails/41.jpg)
def fibonacci(): """Generate an infinite Fibonacci sequence""" a = 0 b = 1
while True: yield b c = a + b a = b b = c
![Page 42: Writing your first web app using Python and Flask](https://reader036.vdocuments.us/reader036/viewer/2022082309/547ea27ab379594e2b8b54cc/html5/thumbnails/42.jpg)
for i in fibonacci(): print i
# WARNING: will never end!
![Page 43: Writing your first web app using Python and Flask](https://reader036.vdocuments.us/reader036/viewer/2022082309/547ea27ab379594e2b8b54cc/html5/thumbnails/43.jpg)
def fibonacci(n=10): """Generate an n elements of the Fibonacci sequence""" a = 0 b = 1
for i in xrange(n): yield b c = a + b a = b b = c
![Page 44: Writing your first web app using Python and Flask](https://reader036.vdocuments.us/reader036/viewer/2022082309/547ea27ab379594e2b8b54cc/html5/thumbnails/44.jpg)
for i in fibonacci(): print iÏÏÐÑÓÖÏÑÐÏÑÒÓÓ
![Page 45: Writing your first web app using Python and Flask](https://reader036.vdocuments.us/reader036/viewer/2022082309/547ea27ab379594e2b8b54cc/html5/thumbnails/45.jpg)
We can use agenerator to emitthe response!
![Page 46: Writing your first web app using Python and Flask](https://reader036.vdocuments.us/reader036/viewer/2022082309/547ea27ab379594e2b8b54cc/html5/thumbnails/46.jpg)
from flask import Response, stream_with_context
@app.route('/events/stream')def get_events(): """Return a stream of events"""
@stream_with_context def generate(): """ A generator that returns a single JSON-encoded event, followed by an empty line. """
while True: yield get_event()
return Response(generate(), mimetype='text/event-stream')
![Page 47: Writing your first web app using Python and Flask](https://reader036.vdocuments.us/reader036/viewer/2022082309/547ea27ab379594e2b8b54cc/html5/thumbnails/47.jpg)
x git checkout example÷ÎÓx pip install ÷r requirementsâtxtx python webapp�ÿÿinitÿÿâpy runserver ÷÷threaded
![Page 48: Writing your first web app using Python and Flask](https://reader036.vdocuments.us/reader036/viewer/2022082309/547ea27ab379594e2b8b54cc/html5/thumbnails/48.jpg)
But wait!
![Page 49: Writing your first web app using Python and Flask](https://reader036.vdocuments.us/reader036/viewer/2022082309/547ea27ab379594e2b8b54cc/html5/thumbnails/49.jpg)
Flask will gracefully finish requests.One request will never finish.
![Page 50: Writing your first web app using Python and Flask](https://reader036.vdocuments.us/reader036/viewer/2022082309/547ea27ab379594e2b8b54cc/html5/thumbnails/50.jpg)
from flask.ext.script import (Manager, Server as ServerCommand)
class Server(ServerCommand): def handle(self, *args, **kwargs): app.running = True
super(Server, self).handle(*args, **kwargs)
print "Shutting down" app.running = False
manager.add_command('runserver', Server)
![Page 51: Writing your first web app using Python and Flask](https://reader036.vdocuments.us/reader036/viewer/2022082309/547ea27ab379594e2b8b54cc/html5/thumbnails/51.jpg)
from Queue import Queue
queue = Queue()
@stream_with_contextdef generate(): """ Yield JSON-encoded events """
while app.running: try: item = queue.get(timeout=1)
yield format_messages([item]) queue.task_done() # eat the queue item except Empty: pass
![Page 52: Writing your first web app using Python and Flask](https://reader036.vdocuments.us/reader036/viewer/2022082309/547ea27ab379594e2b8b54cc/html5/thumbnails/52.jpg)
the other sidewarning: javascript ahead
![Page 53: Writing your first web app using Python and Flask](https://reader036.vdocuments.us/reader036/viewer/2022082309/547ea27ab379594e2b8b54cc/html5/thumbnails/53.jpg)
<title>Event Stream</title> <ul id="messages"> {% for message in get_flashed_messages() %} <li>{{ message }}</li> {% endfor %} </ul>
<script src="/static/bower/jquery.js" type="text/javascript"></script><script src="/static/bower/jquery.eventsource.js" type="text/javascript"></script
<script type="text/javascript">
</script>
$(document).ready(function() { $.eventsource({ label: 'connect', dataType: 'json', url: '/events/stream', message: function(data) { $.each(data, function() { $('<li>', { text: this }).appendTo('#messages'); }); } })});
![Page 54: Writing your first web app using Python and Flask](https://reader036.vdocuments.us/reader036/viewer/2022082309/547ea27ab379594e2b8b54cc/html5/thumbnails/54.jpg)
x git checkout example÷ÎÔx pip install ÷r requirementsâtxtx bower install � NâBâ httpä��bowerâio�x python webapp�ÿÿinitÿÿâpy collectstatic
![Page 55: Writing your first web app using Python and Flask](https://reader036.vdocuments.us/reader036/viewer/2022082309/547ea27ab379594e2b8b54cc/html5/thumbnails/55.jpg)
If you're into websockets you can look atgithub.com/kennethreitz/flask-sockets
![Page 56: Writing your first web app using Python and Flask](https://reader036.vdocuments.us/reader036/viewer/2022082309/547ea27ab379594e2b8b54cc/html5/thumbnails/56.jpg)
Testing withpy.test
![Page 57: Writing your first web app using Python and Flask](https://reader036.vdocuments.us/reader036/viewer/2022082309/547ea27ab379594e2b8b54cc/html5/thumbnails/57.jpg)
tests/conftest.pyimport pytest
from webapp import (app as flask_app, db as flask_db)
@pytest.fixture(scope='session')def db(): """Set up the database"""
flask_app.config['TESTING'] = True flask_app.config['SQLALCHEMY_DATABASE_URI'] = ...
flask_db.drop_all() flask_db.create_all()
return flask_db
@pytest.fixture(scope='session')def app(db): """Set up the Flask test client"""
return flask_app.test_client()
![Page 58: Writing your first web app using Python and Flask](https://reader036.vdocuments.us/reader036/viewer/2022082309/547ea27ab379594e2b8b54cc/html5/thumbnails/58.jpg)
tests/test_views.py"""app and db are available in the test scope"""
def test_index(app): """Test I can get the index page"""
rv = app.get('/')
print rv.data
assert '<title>' in rv.data
![Page 59: Writing your first web app using Python and Flask](https://reader036.vdocuments.us/reader036/viewer/2022082309/547ea27ab379594e2b8b54cc/html5/thumbnails/59.jpg)
x git checkout example÷ÎÕx pip install ÷r requirementsâtxtx pyâtest tests�
![Page 60: Writing your first web app using Python and Flask](https://reader036.vdocuments.us/reader036/viewer/2022082309/547ea27ab379594e2b8b54cc/html5/thumbnails/60.jpg)
deploying toOpenShift
![Page 61: Writing your first web app using Python and Flask](https://reader036.vdocuments.us/reader036/viewer/2022082309/547ea27ab379594e2b8b54cc/html5/thumbnails/61.jpg)
To deploy OpenShift runs your top-levelsetup.py
To serve requests OpenShift runswsgi.application.application
www.openshift.com/developers/python
![Page 62: Writing your first web app using Python and Flask](https://reader036.vdocuments.us/reader036/viewer/2022082309/547ea27ab379594e2b8b54cc/html5/thumbnails/62.jpg)
setup.pyimport os
from setuptools import setup, find_packages
PROJECT_ROOT = os.environ.get('OPENSHIFT_REPO_DIR', os.path.dirname(os.path.abspath(__file__)))
with open(os.path.join(PROJECT_ROOT, 'requirements.txt')) as file_: requirements = [req.strip() for req in file_.xreadlines()]
setup(name='example', version='0.0', author='Danielle Madeley', author_email='[email protected]', url='https://github.com/danni/linux-conf-au-flask-tute', description='Example deploy to OpenShift', install_requires=requirements, )
![Page 63: Writing your first web app using Python and Flask](https://reader036.vdocuments.us/reader036/viewer/2022082309/547ea27ab379594e2b8b54cc/html5/thumbnails/63.jpg)
wsgi/application.pyimport osimport sys
# add local codesys.path.append(os.path.join(os.environ['OPENSHIFT_REPO_DIR']))
# initialise virtual environmentvirtenv = os.environ['OPENSHIFT_HOMEDIR'] + 'python-2.7/virtenv/'os.environ['PYTHON_EGG_CACHE'] = os.path.join(virtenv, 'lib/python2.7/site-packages'
virtualenv = os.path.join(virtenv, 'bin/activate_this.py')
try: execfile(virtualenv, dict(__file__=virtualenv))except IOError: pass
# import and configure WSGI applicationfrom webapp import app as application
![Page 64: Writing your first web app using Python and Flask](https://reader036.vdocuments.us/reader036/viewer/2022082309/547ea27ab379594e2b8b54cc/html5/thumbnails/64.jpg)
app = Flask(__name__)
app.secret_key = os.environ.get('OPENSHIFT_SECRET_TOKEN', 'THIS IS REALLY SECRET')app.config['SQLALCHEMY_DATABASE_URI'] = \ os.environ.get('OPENSHIFT_POSTGRESQL_DB_URL', 'sqlite:///../app.db')
try: app.static_folder = os.path.join(os.environ['OPENSHIFT_REPO_DIR'], 'wsgi'except KeyError: pass
![Page 65: Writing your first web app using Python and Flask](https://reader036.vdocuments.us/reader036/viewer/2022082309/547ea27ab379594e2b8b54cc/html5/thumbnails/65.jpg)
(assuming you've set up Openshift)x rhc app create example python÷ÐâÕ ÷÷no÷gitx git remote add rhc sshä��âââ�example÷âââ�£�git�exampleâgit�
x rhc cartridge add ÷c postgresql÷×âÐ ÷a example
x git push rhc ÷÷force example÷ÎÖämaster
![Page 66: Writing your first web app using Python and Flask](https://reader036.vdocuments.us/reader036/viewer/2022082309/547ea27ab379594e2b8b54cc/html5/thumbnails/66.jpg)
setup.pymanage.pywebapp
__init__.pymanager.pymodels.pyviews.pycollectstatic.pytemplates
events.htmltemplate.html
![Page 67: Writing your first web app using Python and Flask](https://reader036.vdocuments.us/reader036/viewer/2022082309/547ea27ab379594e2b8b54cc/html5/thumbnails/67.jpg)
Going FurtherGetting Bigger
![Page 68: Writing your first web app using Python and Flask](https://reader036.vdocuments.us/reader036/viewer/2022082309/547ea27ab379594e2b8b54cc/html5/thumbnails/68.jpg)
class based viewsfrom flask.views import MethodView
class UserAPI(MethodView):
def get(self): users = User.query.all() ...
def post(self): user = User.from_form_data(request.form) ...
app.add_url_rule('/users/', view_func=UserAPI.as_view('users'))
![Page 69: Writing your first web app using Python and Flask](https://reader036.vdocuments.us/reader036/viewer/2022082309/547ea27ab379594e2b8b54cc/html5/thumbnails/69.jpg)
blueprintsfrom flask import Blueprint, render_template
simple_page = Blueprint('simple_page', __name__, template_folder='templates')
@simple_page.route('/<page>')def show(page): return render_template('pages/%s.html' % page) </page>
![Page 70: Writing your first web app using Python and Flask](https://reader036.vdocuments.us/reader036/viewer/2022082309/547ea27ab379594e2b8b54cc/html5/thumbnails/70.jpg)
blueprintsfrom flask import Flaskfrom module.simple_page import simple_page
app = Flask(__name__)app.register_blueprint(simple_page)
![Page 71: Writing your first web app using Python and Flask](https://reader036.vdocuments.us/reader036/viewer/2022082309/547ea27ab379594e2b8b54cc/html5/thumbnails/71.jpg)
fin ;-)github.com/danni/linux-conf-au-flask-tute
blogs.gnome.org/danni dannipenguin
flickr.com/photos/mau3ry/3763640652