Jinja2 (template engine) and bunch of good things on top • No unnecessary batteries included by default • The idea of Flask is to build a good foundation for all applications. Everything else is up to you or extensions • So no more projects. All you need is Flask application
needs a SQL database • People have different preferences and requirements • Flask could not and don’t want to apply those differences • Flask itself just bridges to Werkzeug to implement a proper WSGI application and to Jinja2 to handle templating • And yeah, most of web applications really need a template engine in some sort
views (but blueprint is not a reusable app) • Extensions as real batteries for our application • And yeah, we have ORM (Flask-SQLAlchemy, Flask- Peewee, Flask-MongoEngine and many others) • We have forms (Flask-WTF) • We have anything we need (Flask-Script, Flask-Testing, Flask-Dropbox, Flask-FlatPages, Frozen-Flask, etc)
is one request object per request which is read only • The request object is available through local context • Request is thread-safe by design • When you need it, import it! from flask import request def page_view(pk): return ‘Page #{0:d} @ {1!r} host’.format(pk, request.host)
request In [2]: app = Flask('appname') In [3]: app Out[3]: <flask.app.Flask at 0x1073139d0> In [4]: current_app Out[4]: <LocalProxy unbound> In [5]: with app.app_context(): print(repr(current_app)) ...: <flask.app.Flask object at 0x1073139d0> In [6]: request Out[6]: <LocalProxy unbound> In [7]: with app.test_request_context(): ....: print(repr(request)) ....: <Request 'http://localhost/' [GET]>
= SQLAlchemy(app) ... from .blueprintname import blueprint app.register_blueprint(blueprint, url_prefix=’/blueprint’) $ cat appname/models.py from app import db class Model(db.Model): ... $ cat appname/blueprintname/blueprint.py from flask import Blueprint from appname.models import Model blueprint = Blueprint(‘blueprintname’, ‘importname’) @blueprint.route(‘/’) def hello(): # Work with model return ‘something...’
than in one Flask app? • Place it to flask_extname module or package • Implement Extname class and provide init_app method • Don’t forget to add your extension to app.extensions dict • Volia!
multiple applications • Don’t forget about app.extensions dict • Do not assign self.app = app in init_app method • Extension should have not-null self.app only for singleton pattern
• Don’t forget about contexts from unittest import TestCase from webtest import TestApp from appname.app import app class TestSomething(TestCase): def setUp(self): app.testing = True self.client = TestApp(app) self._ctx = app.test_request_context() self._ctx.push() def tearDown(self): if self._ctx is not None: self._ctx.pop()
responses on 100 concurrency requests • Bottle, Django and Pyramid WSGI servers will have 2-10% errors or will shutdown after 1000 requests • Gunicorn will not help for sure :(