diff --git a/docs/api.rst b/docs/api.rst index de33ff95..0db2f6b6 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -370,22 +370,6 @@ Configuration .. autoclass:: Config :members: -Extensions ----------- - -.. data:: flask.ext - - This module acts as redirect import module to Flask extensions. It was - added in 0.8 as the canonical way to import Flask extensions and makes - it possible for us to have more flexibility in how we distribute - extensions. - - If you want to use an extension named “Flask-Foo” you would import it - from :data:`~flask.ext` as follows:: - - from flask.ext import foo - - .. versionadded:: 0.8 Stream Helpers -------------- diff --git a/docs/extensiondev.rst b/docs/extensiondev.rst index 29c33f3c..677cc19a 100644 --- a/docs/extensiondev.rst +++ b/docs/extensiondev.rst @@ -159,19 +159,10 @@ The Extension Code Here's the contents of the `flask_sqlite3.py` for copy/paste:: import sqlite3 - from flask import current_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: - from flask import _app_ctx_stack as stack - except ImportError: - from flask import _request_ctx_stack as stack + from flask import current_app, _app_ctx_stack class SQLite3(object): - def __init__(self, app=None): self.app = app if app is not None: @@ -179,24 +170,19 @@ Here's the contents of the `flask_sqlite3.py` for copy/paste:: def init_app(self, app): app.config.setdefault('SQLITE3_DATABASE', ':memory:') - # Use the newstyle teardown_appcontext if it's available, - # otherwise fall back to the request context - if hasattr(app, 'teardown_appcontext'): - app.teardown_appcontext(self.teardown) - else: - app.teardown_request(self.teardown) + app.teardown_appcontext(self.teardown) def connect(self): return sqlite3.connect(current_app.config['SQLITE3_DATABASE']) def teardown(self, exception): - ctx = stack.top + ctx = _app_ctx_stack.top if hasattr(ctx, 'sqlite3_db'): ctx.sqlite3_db.close() @property def connection(self): - ctx = stack.top + ctx = _app_ctx_stack.top if ctx is not None: if not hasattr(ctx, 'sqlite3_db'): ctx.sqlite3_db = self.connect() @@ -212,9 +198,7 @@ So here's what these lines of code do: 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. + the ``teardown`` handler. 3. Next, we define a ``connect`` method that opens a database connection. 4. Finally, we add a ``connection`` property that on first access opens the database connection and stores it on the context. This is also @@ -224,9 +208,7 @@ So here's what these lines of code do: 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. + complex name. So why did we decide on a class-based approach here? Because using our extension looks something like this:: @@ -245,9 +227,8 @@ You can then use the database from views like this:: cur = db.connection.cursor() cur.execute(...) -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:: +Likewise if you are outside of a request you can use the database by +pushing an app context:: with app.app_context(): cur = db.connection.cursor() @@ -291,34 +272,6 @@ 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 :data:`~flask._app_ctx_stack` does not exist because the user uses -an old version of Flask, it is recommended to fall back to -:data:`~flask._request_ctx_stack` which is bound to a request. - -Teardown Behavior ------------------ - -*This is only relevant if you want to support Flask 0.6 and older* - -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:: - - def close_connection(response): - ctx = _request_ctx_stack.top - ctx.sqlite3_db.close() - return response - - if hasattr(app, 'teardown_request'): - app.teardown_request(close_connection) - else: - app.after_request(close_connection) - -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. Learn from Others ----------------- @@ -386,25 +339,6 @@ extension to be approved you have to follow these guidelines: 10. An extension currently has to support Python 3.4 and newer and 2.7. - -Extension Import Transition ---------------------------- - -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``. - - .. _OAuth extension: https://pythonhosted.org/Flask-OAuth/ .. _mailinglist: http://flask.pocoo.org/mailinglist/ .. _IRC channel: http://flask.pocoo.org/community/irc/ diff --git a/docs/extensions.rst b/docs/extensions.rst index 6deb9652..54e2c3eb 100644 --- a/docs/extensions.rst +++ b/docs/extensions.rst @@ -1,58 +1,53 @@ .. _extensions: -Flask Extensions -================ +Extensions +========== + +Extensions are extra packages that add functionality to a Flask +application. For example, an extension might add support for sending +email or connecting to a database. Some extensions add entire new +frameworks to help build certain types of applications, like a ReST API. -Flask extensions extend the functionality of Flask in various different -ways. For instance they add support for databases and other common tasks. Finding Extensions ------------------ -Flask extensions are listed on the `Flask Extension Registry`_ and can be -downloaded with :command:`easy_install` or :command:`pip`. If you add a Flask extension -as dependency to your :file:`requirements.txt` or :file:`setup.py` file they are -usually installed with a simple command or when your application installs. +Flask extensions are usually named "Flask-Foo" or "Foo-Flask". Many +extensions are listed in the `Extension Registry`_, which can be updated +by extension developers. You can also search PyPI for packages tagged +with `Framework :: Flask `_. + Using Extensions ---------------- -Extensions typically have documentation that goes along that shows how to -use it. There are no general rules in how extensions are supposed to -behave but they are imported from common locations. If you have an -extension called ``Flask-Foo`` or ``Foo-Flask`` it should be always -importable from ``flask_foo``:: +Consult each extension's documentation for installation, configuration, +and usage instructions. Generally, extensions pull their own +configuration from :attr:`app.config ` and are +passed an application instance during initialization. For example, +an extension caled "Flask-Foo" might be used like this:: - import flask_foo + from flask_foo import Foo -Building Extensions -------------------- + foo = Foo() -While `Flask Extension Registry`_ contains many Flask extensions, you may not find -an extension that fits your need. If this is the case, you can always create your own. -Consider reading :ref:`extension-dev` to develop your own Flask extension. + app = Flask(__name__) + app.config.update( + FOO_BAR='baz', + FOO_SPAM='eggs', + ) -Flask Before 0.8 ----------------- + foo.init_app(app) -If you are using Flask 0.7 or earlier the :data:`flask.ext` package will not -exist, instead you have to import from ``flaskext.foo`` or ``flask_foo`` -depending on how the extension is distributed. If you want to develop an -application that supports Flask 0.7 or earlier you should still import -from the :data:`flask.ext` package. We provide you with a compatibility -module that provides this package for older versions of Flask. You can -download it from GitHub: `flaskext_compat.py`_ -And here is how you can use it:: - - import flaskext_compat - flaskext_compat.activate() - - from flask.ext import foo +Building Extensions +------------------- -Once the ``flaskext_compat`` module is activated the :data:`flask.ext` will -exist and you can start importing from there. +While the `Extension Registry`_ contains many Flask extensions, you may +not find an extension that fits your need. If this is the case, you can +create your own. Read :ref:`extension-dev` to develop your own Flask +extension. -.. _Flask Extension Registry: http://flask.pocoo.org/extensions/ -.. _flaskext_compat.py: https://raw.githubusercontent.com/pallets/flask/master/scripts/flaskext_compat.py +.. _Extension Registry: http://flask.pocoo.org/extensions/ +.. _pypi: https://pypi.python.org/pypi?:action=browse&c=585