Navigation

Flask, being a microframework, often requires some repetitive steps to get
a third party library working. Because very often these steps could be
abstracted to support multiple projects the Flask Extension Registry
was created.

If you want to create your own Flask extension for something that does not
exist yet, this guide to extension development will help you get your
extension running in no time and to feel like users would expect your
extension to behave.

Extensions are all located in a package called flask_something
where “something” is the name of the library you want to bridge. So for
example if you plan to add support for a library named simplexml to
Flask, you would name your extension’s package flask_simplexml.

The name of the actual extension (the human readable name) however would
be something like “Flask-SimpleXML”. Make sure to include the name
“Flask” somewhere in that name and that you check the capitalization.
This is how users can then register dependencies to your extension in
their setup.py files.

Flask sets up a redirect package called flask.ext where users
should import the extensions from. If you for instance have a package
called flask_something users would import it as
flask.ext.something. This is done to transition from the old
namespace packages. See Extension Import Transition for more details.

But what do extensions look like themselves? An extension has to ensure
that it works with multiple Flask application instances at once. This is
a requirement because many people will use patterns like the
Application Factories pattern to create their application as needed to aid
unittests and to support multiple configurations. Because of that it is
crucial that your application supports that kind of behavior.

Most importantly the extension must be shipped with a setup.py file and
registered on PyPI. Also the development checkout link should work so
that people can easily install the development version into their
virtualenv without having to download the library by hand.

Flask extensions must be licensed under a BSD, MIT or more liberal license
to be able to be enlisted in the Flask Extension Registry. Keep in mind
that the Flask Extension Registry is a moderated place and libraries will
be reviewed upfront if they behave as required.

Many extensions will need some kind of initialization step. For example,
consider an application that’s currently connecting to SQLite like the
documentation suggests (Using SQLite 3 with Flask). So how does the extension
know the name of the application object?

Quite simple: you pass it to it.

There are two recommended ways for an extension to initialize:

initialization functions:

If your extension is called helloworld you might have a function
called init_helloworld(app[,extra_args]) that initializes the
extension for that application. It could attach before / after
handlers etc.

classes:

Classes work mostly like initialization functions but can later be
used to further change the behavior. For an example look at how the
OAuth extension works: there is an OAuth object that provides
some helper functions like OAuth.remote_app to create a reference to
a remote application that uses OAuth.

What to use depends on what you have in mind. For the SQLite 3 extension
we will use the class-based approach because it will provide users with an
object that handles opening and closing database connections.

What’s important about classes is that they encourage to be shared around
on module level. In that case, the object itself must not under any
circumstances store any application specific state and must be shareable
between different application.

importsqlite3fromflaskimportcurrent_app# Find the stack on which we want to store the database connection.# Starting with Flask 0.9, the _app_ctx_stack is the correct one,# before that we need to use the _request_ctx_stack.try:fromflaskimport_app_ctx_stackasstackexceptImportError:fromflaskimport_request_ctx_stackasstackclassSQLite3(object):def__init__(self,app=None):self.app=appifappisnotNone:self.init_app(app)definit_app(self,app):app.config.setdefault('SQLITE3_DATABASE',':memory:')# Use the newstyle teardown_appcontext if it's available,# otherwise fall back to the request contextifhasattr(app,'teardown_appcontext'):app.teardown_appcontext(self.teardown)else:app.teardown_request(self.teardown)defconnect(self):returnsqlite3.connect(current_app.config['SQLITE3_DATABASE'])defteardown(self,exception):ctx=stack.topifhasattr(ctx,'sqlite3_db'):ctx.sqlite3_db.close()@propertydefconnection(self):ctx=stack.topifctxisnotNone:ifnothasattr(ctx,'sqlite3_db'):ctx.sqlite3_db=self.connect()returnctx.sqlite3_db

The init_app method exists so that the SQLite3 object can be
instantiated without requiring an app object. This method supports the
factory pattern for creating applications. The init_app will set the
configuration for the database, defaulting to an in memory database if
no configuration is supplied. In addition, the init_app method attaches
the teardown handler. It will try to use the newstyle app context
handler and if it does not exist, falls back to the request context
one.

Next, we define a connect method that opens a database connection.

Finally, we add a connection property that on first access opens
the database connection and stores it on the context. This is also
the recommended way to handling resources: fetch resources lazily the
first time they are used.

Note here that we’re attaching our database connection to the top
application context via _app_ctx_stack.top. Extensions should use
the top context for storing their own information with a sufficiently
complex name. Note that we’re falling back to the
_request_ctx_stack.top if the application is using an older
version of Flask that does not support it.

So why did we decide on a class-based approach here? Because using our
extension looks something like this:

Likewise if you are outside of a request but you are using Flask 0.9 or
later with the app context support, you can use the database in the same
way:

withapp.app_context():cur=db.connection.cursor()cur.execute(...)

At the end of the with block the teardown handles will be executed
automatically.

Additionally, the init_app method is used to support the factory pattern
for creating apps:

db=Sqlite3()# Then later on.app=create_app('the-config.cfg')db.init_app(app)

Keep in mind that supporting this factory pattern for creating apps is required
for approved flask extensions (described below).

Note on init_app

As you noticed, init_app does not assign app to self. This
is intentional! Class based Flask extensions must only store the
application on the object when the application was passed to the
constructor. This tells the extension: I am not interested in using
multiple applications.

When the extension needs to find the current application and it does
not have a reference to it, it must either use the
current_app context local or change the API in a way
that you can pass the application explicitly.

In the example above, before every request, a sqlite3_db variable is
assigned to _app_ctx_stack.top. In a view function, this variable is
accessible using the connection property of SQLite3. During the
teardown of a request, the sqlite3_db connection is closed. By using
this pattern, the same connection to the sqlite3 database is accessible
to anything that needs it for the duration of the request.

If the _app_ctx_stack does not exist because the user uses
an old version of Flask, it is recommended to fall back to
_request_ctx_stack which is bound to a request.

Due to the change in Flask 0.7 regarding functions that are run at the end
of the request your extension will have to be extra careful there if it
wants to continue to support older versions of Flask. The following
pattern is a good way to support both:

Strictly speaking the above code is wrong, because teardown functions are
passed the exception and typically don’t return anything. However because
the return value is discarded this will just work assuming that the code
in between does not touch the passed parameter.

This documentation only touches the bare minimum for extension
development. If you want to learn more, it’s a very good idea to check
out existing extensions on the Flask Extension Registry. If you feel
lost there is still the mailinglist and the IRC channel to get some
ideas for nice looking APIs. Especially if you do something nobody before
you did, it might be a very good idea to get some more input. This not
only to get an idea about what people might want to have from an
extension, but also to avoid having multiple developers working on pretty
much the same side by side.

Remember: good API design is hard, so introduce your project on the
mailinglist, and let other developers give you a helping hand with
designing the API.

The best Flask extensions are extensions that share common idioms for the
API. And this can only work if collaboration happens early.

Flask also has the concept of approved extensions. Approved extensions
are tested as part of Flask itself to ensure extensions do not break on
new releases. These approved extensions are listed on the Flask
Extension Registry and marked appropriately. If you want your own
extension to be approved you have to follow these guidelines:

An approved Flask extension requires a maintainer. In the event an
extension author would like to move beyond the project, the project should
find a new maintainer including full source hosting transition and PyPI
access. If no maintainer is available, give access to the Flask core team.

An approved Flask extension must provide exactly one package or module
named flask_extensionname.

It must ship a testing suite that can either be invoked with maketest
or pythonsetup.pytest. For test suites invoked with maketest the extension has to ensure that all dependencies for the test
are installed automatically. If tests are invoked with pythonsetup.pytest, test dependencies can be specified in the setup.py file. The
test suite also has to be part of the distribution.

APIs of approved extensions will be checked for the following
characteristics:

an approved extension has to support multiple applications
running in the same Python process.

it must be possible to use the factory pattern for creating
applications.

The license must be BSD/MIT/WTFPL licensed.

The naming scheme for official extensions is Flask-ExtensionName or
ExtensionName-Flask.

Approved extensions must define all their dependencies in the
setup.py file unless a dependency cannot be met because it is not
available on PyPI.

The extension must have documentation that uses one of the two Flask
themes for Sphinx documentation.

The setup.py description (and thus the PyPI description) has to
link to the documentation, website (if there is one) and there
must be a link to automatically install the development version
(PackageName==dev).

The zip_safe flag in the setup script must be set to False,
even if the extension would be safe for zipping.

An extension currently has to support Python 2.6 as well as
Python 2.7

In early versions of Flask we recommended using namespace packages for Flask
extensions, of the form flaskext.foo. This turned out to be problematic in
practice because it meant that multiple flaskext packages coexist.
Consequently we have recommended to name extensions flask_foo over
flaskext.foo for a long time.

Flask 0.8 introduced a redirect import system as a compatibility aid for app
developers: Importing flask.ext.foo would try flask_foo and
flaskext.foo in that order.

As of Flask 0.11, most Flask extensions have transitioned to the new naming
schema. The flask.ext.foo compatibility alias is still in Flask 0.11 but is
now deprecated – you should use flask_foo.