Professional Documents
Culture Documents
Osvaldo Matos-Junior
How an April Fool's Joke became a Framework with Good Intentions (PyCon 2011)
Why micro?
The micro in microframework means Flask aims to keep the core simple but extensible. Flask wont make many decisions for you. (Armin Ronacher)
Some Numbers
800 LOC Code 1500 LOC Tests 200 A4 Pages of Documentation over 3900 followers and 550 forks on github
Flask is Fun
from flask import Flask app = Flask(__name__) @app.route('/') def index(): return 'Hello World!' if __name__ == '__main__': app.run(debug=True)
Easy to Setup
$ pip install Flask $ python hello.py * Running on http://localhost:5000/
debug mode
URL building
from flask import Flask, url_for app = Flask(__name__) @app.route('/login') def login(): pass @app.route('/user/<username>') def profile(username): pass with app.test_request_context(): print url_for('login') print url_for('login', next='/') print url_for('profile', username='John Doe') print url_for('static', filename='css/style.css', _external=True) /login /login?next=/ /user/John%20Doe http://localhost/static/css/style.css
rendering templates
hello.py
from flask import Flask, render_template app = Flask(__name__) @app.route('/', defaults={'name': 'Flask'}) @app.route('/<name>') def index(name): return render_template('hello.html', name=name) if __name__ == '__main__': app.run(debug=True)
templates/hello.html
<head> <title>Greetings</title> </head> <body> Hello {{ name }}! </body>
Template Filters
<h1> {{ title|capitalize|truncate(120) }} </h1>
Built in: capitalize, lower, length, trim, striptags, truncate, urlize ... Customize: slugify, timesince ...
Macros
header FLASK
Results for: "query"
GO
300x250
Macros
{# ads.html #} {% macro google_adsense(id, width=120, height=120) -%}
<script>google_ad_client = "pub-XXXX" ; google_ad_slot = "{{id}}"; google_ad_width = "{{width}}" ; google_ad_height = "{{height}}" ;<script /> <script type="text/javascript" src="http://pagead2.googlesyndication. com/pagead/show_ads.js" ></ script>
{%- endmacro %} {# sidebar.html #} {% from 'ads.html' import ads_google %} <div>{{ google_adsense('arroba', 300, 250) }}</div> <div>{{ google_adsense('ads1', 300, 100) }}</div> {% include "related_content.html" %} <div>{{ google_adsense('ads2', 300, 100) }}</div>
header 2
Template Inheritance
header content 3
content 2 footer
footer
Base Template
<html> <head> <link rel="stylesheet" href="style.css" /> <title>{% block title %}{% endblock %} - My Webpage</title> </head> <body> <div id="content">{% block content %}{% endblock %}</div> <div id="footer"> {% block footer %} © Copyright 2008 by <a href="http://domain.invalid/">you</a>. {% endblock %} </div> </body>
Child Template
{% extends "base.html" %} {% block title %}Index{% endblock %} {% block content %} <h1>Index</h1> <p class="important"> Welcome on my awesome homepage. </p> {% endblock %}
render_template('child.html')
<html> <head> <link rel="stylesheet" href="style.css" /> <title>Index - My Webpage</title> </head> <body> <div id="content"><h1>Index</h1> <p class="important"> Welcome on my awesome homepage.</p> </div> <div id="footer">© Copyright 2008 by <a href="http://domain.invalid/">you</a>.</div> </body>
more...
Snippets
import sqlite3 from flask import g def connect_db(): return sqlite3.connect('/path/to/database.db') @app.before_request def before_request(): g.db = connect_db() @app.teardown_request def teardown_request(exception): g.db.close()
many extensions
Flask-Babel Flask-CouchDB Flask-MongoKit Flask-Login Flask-Mail Flask-Script Flask-SQLAlchemy Flask-Testing Flask-WTF ...
Flask-SQLAlchemy
from flask import Flask from flaskext.sqlalchemy import SQLAlchemy app = Flask(__name__) db = SQLAlchemy(app) class User(db.Model): name = db.Column(db.String(40), primary_key=True) email = db.Column(db.String(100)) @@app.route('/user/<name>') def show_user(name): user = User.query.filter_by(name=name). first_or_404() return render_template('user.html', user=user)
Flask-Testing
from flaskext.testing import TestCase from hello import app class AppTest(TestCase): def create_app(self): return app def test_index(self): response = self.client.get('/') self.assert200(response) self.assertTemplateUsed('index.html') title = self.get_cotext_variable('title') self.assertEqual('My Page', title)
larger applications
getting started
Create App
def create_app(config=None, app_name=None, blueprints=None): app_name = app_name or __name__ app = flask.Flask(app_name, static_folder=None) configure_app(app, config) configure_blueprints(app, blueprints) configure_error_handlers(app) configure_database(app) configure_context_processors(app) configure_template_filters(app) configure_before_request(app) configure_extensions(app) configure_views(app) configure_admin(app) return app
def configure_error_handlers(app): @app.errorhandler(401) def unauthorized(error): flask.flash(u'Para acessar voc precisa estar logado.') return flask.redirect(url_for('login', next=request.url, _external=True)) @app.errorhandler(404) def page_not_found(error): return render("errors/page_not_found.html"), 404 @app.errorhandler(500) def server_error_page(error): return render("errors/server_error.html"), 500
Own Extensions
from jusbrasil.search import pool from thriftclient import ThriftClient class SearchClient(ThriftClient): def __init__(self, app=None): ThriftClient.__init__(self) self.app = None if app is not None: self.init_app(app) def init_app(self, app): if not app.config['TESTING']: self.pool = pool.ConnectionPool( server_list=app.config['SEARCH_SERVERS'], timeout=app.config['SEARCH_TIMEOUT'], pool_size=app.config['SEARCH_POOL_SIZE']) self.app = app
Logged Users
def get_current_user(): return getattr(flask.g, 'user', None) def configure_before_request(app): @app.before_request def load_current_user(): flask.g.user = None if 'user' in session: flask.g.user = load_user_session(session['user'])
Shortcuts
from jusbrasil.web import cache @cache.memoize() def get_object_or_404(id, document_type): # no valid id if id < 0: abort(404) _object = client.getDocument(document_type, id) # document not found if _object is None: abort(404) return _object
modularize
Blueprints
import flask from jusbrasil.web.utils.shortcuts import get_object_or_404 app = flask.Blueprint('jurisprudencia', __name__) @app.route('/<int:id>/<slug>') def view(id, slug): juris = get_object_or_404(id, 'jurisprudencia') template = 'jurisprudencia/view.html' return render(template, juris=juris)
Templates
{% block title %} {{ juris.title }} {% endblock %} {% block content %} <div class="jurisprudencia"> <h1>{{ juris.titulo }}</h1> <div class="ementa">{{ juris.ementa }}</div> <a href="{{ juris.inteiroTeor }}">Download Inteiro Teor</a> <div class="acordao"> <h2>Acrdo</h2> {{ juris.acordao }}</div> </div> {% endblock %}
finally...
Flask is a microframework for Python based on Werkzeug, Jinja 2 and good intentions.
scaling
Q& A
References
http://denied.immersedcode.org/ http://flask.pocoo.org/ http://jinja.pocoo.org/ http://werkzeug.pocoo.org/ http://www.quora.com/Flask https://github.com/mitsuhiko/flask http://www.slideshare.net/mitsuhiko/flask https://github.com/italomaia/flask-empty