All about Flask Extensions

What is Flask?

  • Micro web-framework, built on top of:
  • It also contains:
    • Configuration primitives
    • Helpers to work with Cookies and Sessions
    • Testing utilities
    • Various other web-helpers (JSON, static files, etc)

Is this enough?

  • Yes!
from flask import Flask, render_template
from . import settings

app = Flask(__name__)

def index():
    return render_template('index.html')

But what if?

  • You need work with database?
  • Or with cache?
  • Or with assets?
  • Or with user authentication?
  • Or put your need here?

Meet Flask Extensions

  • Python modules or packages which adds needed abilities to Flask
  • Should named as flask_<ability>
  • Could contain as Flask-related, but just raw Python code
from flask_sqlalchemy import SQLAlchemy
# from flask.ext.sqlalchemy import SQLAlchemy  (preferred way)
db = SQLAlchemy(app)
  • It's like Django reusabble apps, but better :)

Popular Flask Extensions

Database, datastore, cache

User authentication

Useful extensions for every Flask application

Useful extensions

My extensions

How to use extensions?

  1. Define extension settings
  2. Import extension class in your application module
  3. Init extension class with or without app
  4. ???
  5. PROFIT!

How to use extensions?

  • Without application factory
SQLALCHEMY_SCHEMA_URI = 'postgresql://username:password@host:port/database'

from flask import Flask
from flask.ext.sqlalchemy import SQLAlchemy

app = Flask(__name__)
db = SQLAlchemy(app)

How to use extensions?

  • Without application factory
from .app import db

class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(64), unique=True)

How to use extensions?

  • With application factory
REDIS_URL = 'redis://localhost:6379/0'

from flask.ext.redis import Redis

redis = Redis()

from flask import Flask
from .extensions import redis

def create_app(name, ...):
    app = Flask(name)
    return app

How to use extensions?

  • With application factory
from flask import render_template
from .app import create_app

app = create_app('myapp')

def index():
    redis = app.extensions['redis']
    with redis.pipeline() as pipe:
    return render_template('index.html', ...)

Creating custom
Flask Extensions

It's easy!

  • Create Python module or package
  • It should be named flask_<ability>
  • That's all, now put Python code there
from redis import StrictRedis

class Redis(object):
    def __init__(self, app=None):
        if app:
   = app

    def init_app(self, app):
        url = app.config.get('REDIS_URL') or 'redis://localhost:6379/0'
        connection = StrictRedis.from_url(url)
        app.extensions['redis'] = connection

And it works easy

import logging

from flask import current_app

logger = logging.getLogger(__name__)

def stat(record):
    redis = current_app.extensions.get('redis')

    if not redis:
        app_extensions = sorted(current_app.extensions.iterkeys())
        logger.warning('No redis extension configured for app',
                       extra={'app': current_app,
                              'app_extensions': app_extensions})

    with redis.pipeline() as pipe:


  • Extension has to ensure that it works with multiple Flask application at once
    • Extension.__init__(app=None)
    • Extension.init_app(app)
  • init_app shouldn't assign app to self
  • When application passed to constructor, extension not interested in using multiple applications


  • Extension must be shipped with and registered on PyPI
  • There is Flask Extension Registry
  • To put extension there it should be licensed under the BSD, MIT or more libreal license
  • And have documentation on Python Packages or Read the Docs


  • See how other people do, learn from their code
  • Use best practicies and solutions in your code
  • Flask Extensions is great example of sharing common idioms in API
  • Don't be a bully, don't create new bycicle here

Testing custom
Flask Extensions

Welcome Travis CI

  • Continous integration system
  • Perfectly suitable for testing open-source libraries
  • You could test against:
    • Different Python versions
    • Different Flask versions


language: python
  - 2.6
  - 2.7
  - 3.3
  - pypy
  - FLASK_VERSION=0.10.1


  - pip install -e .
  - pip install -I Flask==$FLASK_VERSION
  - if [[ $TRAVIS_PYTHON_VERSION == '2.6' ]]; then pip install unittest2; fi
  - python
  - python test


    - python: pypy
    - python: 3.3
      env: FLASK_VERSION=0.8
    - python: 3.3
      env: FLASK_VERSION=0.9

How it works?

  • You make push to GitHub
  • GitHub sends hook with necessary payload to Travis
  • Travis reads your configuration
  • Travis installs venv and runs your tests