diff options
Diffstat (limited to 'app/static/doc/flask-docs/extensiondev.html')
-rw-r--r-- | app/static/doc/flask-docs/extensiondev.html | 475 |
1 files changed, 0 insertions, 475 deletions
diff --git a/app/static/doc/flask-docs/extensiondev.html b/app/static/doc/flask-docs/extensiondev.html deleted file mode 100644 index 05044b0..0000000 --- a/app/static/doc/flask-docs/extensiondev.html +++ /dev/null @@ -1,475 +0,0 @@ - -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" - "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> - - -<html xmlns="http://www.w3.org/1999/xhtml"> - <head> - <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> - - <title>Flask Extension Development — Flask 0.8 documentation</title> - - <link rel="stylesheet" href="_static/flasky.css" type="text/css" /> - <link rel="stylesheet" href="_static/pygments.css" type="text/css" /> - - <script type="text/javascript"> - var DOCUMENTATION_OPTIONS = { - URL_ROOT: '', - VERSION: '0.8', - COLLAPSE_INDEX: false, - FILE_SUFFIX: '.html', - HAS_SOURCE: true - }; - </script> - <script type="text/javascript" src="_static/jquery.js"></script> - <script type="text/javascript" src="_static/underscore.js"></script> - <script type="text/javascript" src="_static/doctools.js"></script> - <link rel="top" title="Flask 0.8 documentation" href="index.html" /> - <link rel="next" title="Pocoo Styleguide" href="styleguide.html" /> - <link rel="prev" title="Unicode in Flask" href="unicode.html" /> - - - <link rel="apple-touch-icon" href="_static/touch-icon.png" /> - - <link media="only screen and (max-device-width: 480px)" href="_static/small_flask.css" type= "text/css" rel="stylesheet" /> - - </head> - <body> - <div class="related"> - <h3>Navigation</h3> - <ul> - <li class="right" style="margin-right: 10px"> - <a href="genindex.html" title="General Index" - accesskey="I">index</a></li> - <li class="right" > - <a href="styleguide.html" title="Pocoo Styleguide" - accesskey="N">next</a> |</li> - <li class="right" > - <a href="unicode.html" title="Unicode in Flask" - accesskey="P">previous</a> |</li> - <li><a href="index.html">Flask 0.8 documentation</a> »</li> - </ul> - </div> - - <div class="document"> - <div class="documentwrapper"> - <div class="bodywrapper"> - <div class="body"> - - <div class="section" id="flask-extension-development"> -<h1>Flask Extension Development<a class="headerlink" href="#flask-extension-development" title="Permalink to this headline">¶</a></h1> -<p>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 <a class="reference external" href="http://flask.pocoo.org/extensions/">Flask Extension Registry</a> -was created.</p> -<p>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.</p> -<div class="section" id="anatomy-of-an-extension"> -<h2>Anatomy of an Extension<a class="headerlink" href="#anatomy-of-an-extension" title="Permalink to this headline">¶</a></h2> -<p>Extensions are all located in a package called <tt class="docutils literal"><span class="pre">flask_something</span></tt> -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 <cite>simplexml</cite> to -Flask, you would name your extension’s package <tt class="docutils literal"><span class="pre">flask_simplexml</span></tt>.</p> -<p>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 <cite>setup.py</cite> files.</p> -<p>Flask sets up a redirect package called <tt class="xref py py-data docutils literal"><span class="pre">flask.ext</span></tt> where users -should import the extensions from. If you for instance have a package -called <tt class="docutils literal"><span class="pre">flask_something</span></tt> users would import it as -<tt class="docutils literal"><span class="pre">flask.ext.something</span></tt>. This is done to transition from the old -namespace packages. See <a class="reference internal" href="#ext-import-transition"><em>Extension Import Transition</em></a> for more details.</p> -<p>But how 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 -<a class="reference internal" href="patterns/appfactories.html#app-factories"><em>Application Factories</em></a> 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 behaviour.</p> -<p>Most importantly the extension must be shipped with a <cite>setup.py</cite> 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.</p> -<p>Flask extensions must be licensed as BSD or MIT or a more liberal license -to be enlisted on 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.</p> -</div> -<div class="section" id="hello-flaskext"> -<h2>“Hello Flaskext!”<a class="headerlink" href="#hello-flaskext" title="Permalink to this headline">¶</a></h2> -<p>So let’s get started with creating such a Flask extension. The extension -we want to create here will provide very basic support for SQLite3.</p> -<p>First we create the following folder structure:</p> -<div class="highlight-python"><pre>flask-sqlite3/ - flask_sqlite3.py - LICENSE - README</pre> -</div> -<p>Here’s the contents of the most important files:</p> -<div class="section" id="setup-py"> -<h3>setup.py<a class="headerlink" href="#setup-py" title="Permalink to this headline">¶</a></h3> -<p>The next file that is absolutely required is the <cite>setup.py</cite> file which is -used to install your Flask extension. The following contents are -something you can work with:</p> -<div class="highlight-python"><div class="highlight"><pre><span class="sd">"""</span> -<span class="sd">Flask-SQLite3</span> -<span class="sd">-------------</span> - -<span class="sd">This is the description for that library</span> -<span class="sd">"""</span> -<span class="kn">from</span> <span class="nn">setuptools</span> <span class="kn">import</span> <span class="n">setup</span> - - -<span class="n">setup</span><span class="p">(</span> - <span class="n">name</span><span class="o">=</span><span class="s">'Flask-SQLite3'</span><span class="p">,</span> - <span class="n">version</span><span class="o">=</span><span class="s">'1.0'</span><span class="p">,</span> - <span class="n">url</span><span class="o">=</span><span class="s">'http://example.com/flask-sqlite3/'</span><span class="p">,</span> - <span class="n">license</span><span class="o">=</span><span class="s">'BSD'</span><span class="p">,</span> - <span class="n">author</span><span class="o">=</span><span class="s">'Your Name'</span><span class="p">,</span> - <span class="n">author_email</span><span class="o">=</span><span class="s">'your-email@example.com'</span><span class="p">,</span> - <span class="n">description</span><span class="o">=</span><span class="s">'Very short description'</span><span class="p">,</span> - <span class="n">long_description</span><span class="o">=</span><span class="n">__doc__</span><span class="p">,</span> - <span class="n">py_modules</span><span class="o">=</span><span class="p">[</span><span class="s">'flask_sqlite3'</span><span class="p">],</span> - <span class="c"># if you would be using a package instead use packages instead</span> - <span class="c"># of py_modules:</span> - <span class="c"># packages=['flask_sqlite3'],</span> - <span class="n">zip_safe</span><span class="o">=</span><span class="bp">False</span><span class="p">,</span> - <span class="n">include_package_data</span><span class="o">=</span><span class="bp">True</span><span class="p">,</span> - <span class="n">platforms</span><span class="o">=</span><span class="s">'any'</span><span class="p">,</span> - <span class="n">install_requires</span><span class="o">=</span><span class="p">[</span> - <span class="s">'Flask'</span> - <span class="p">],</span> - <span class="n">classifiers</span><span class="o">=</span><span class="p">[</span> - <span class="s">'Environment :: Web Environment'</span><span class="p">,</span> - <span class="s">'Intended Audience :: Developers'</span><span class="p">,</span> - <span class="s">'License :: OSI Approved :: BSD License'</span><span class="p">,</span> - <span class="s">'Operating System :: OS Independent'</span><span class="p">,</span> - <span class="s">'Programming Language :: Python'</span><span class="p">,</span> - <span class="s">'Topic :: Internet :: WWW/HTTP :: Dynamic Content'</span><span class="p">,</span> - <span class="s">'Topic :: Software Development :: Libraries :: Python Modules'</span> - <span class="p">]</span> -<span class="p">)</span> -</pre></div> -</div> -<p>That’s a lot of code but you can really just copy/paste that from existing -extensions and adapt.</p> -</div> -<div class="section" id="flask-sqlite3-py"> -<h3>flask_sqlite3.py<a class="headerlink" href="#flask-sqlite3-py" title="Permalink to this headline">¶</a></h3> -<p>Now this is where your extension code goes. But how exactly should such -an extension look like? What are the best practices? Continue reading -for some insight.</p> -</div> -</div> -<div class="section" id="initializing-extensions"> -<h2>Initializing Extensions<a class="headerlink" href="#initializing-extensions" title="Permalink to this headline">¶</a></h2> -<p>Many extensions will need some kind of initialization step. For example, -consider your application is currently connecting to SQLite like the -documentation suggests (<a class="reference internal" href="patterns/sqlite3.html#sqlite3"><em>Using SQLite 3 with Flask</em></a>) you will need to provide a few -functions and before / after request handlers. So how does the extension -know the name of the application object?</p> -<p>Quite simple: you pass it to it.</p> -<p>There are two recommended ways for an extension to initialize:</p> -<dl class="docutils"> -<dt>initialization functions:</dt> -<dd>If your extension is called <cite>helloworld</cite> you might have a function -called <tt class="docutils literal"><span class="pre">init_helloworld(app[,</span> <span class="pre">extra_args])</span></tt> that initializes the -extension for that application. It could attach before / after -handlers etc.</dd> -<dt>classes:</dt> -<dd>Classes work mostly like initialization functions but can later be -used to further change the behaviour. For an example look at how the -<a class="reference external" href="http://packages.python.org/Flask-OAuth/">OAuth extension</a> works: there is an <cite>OAuth</cite> object that provides -some helper functions like <cite>OAuth.remote_app</cite> to create a reference to -a remote application that uses OAuth.</dd> -</dl> -<p>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 a -manager object that handles opening and closing database connections.</p> -</div> -<div class="section" id="the-extension-code"> -<h2>The Extension Code<a class="headerlink" href="#the-extension-code" title="Permalink to this headline">¶</a></h2> -<p>Here’s the contents of the <cite>flask_sqlite3.py</cite> for copy/paste:</p> -<div class="highlight-python"><div class="highlight"><pre><span class="kn">from</span> <span class="nn">__future__</span> <span class="kn">import</span> <span class="n">absolute_import</span> -<span class="kn">import</span> <span class="nn">sqlite3</span> - -<span class="kn">from</span> <span class="nn">flask</span> <span class="kn">import</span> <span class="n">_request_ctx_stack</span> - -<span class="k">class</span> <span class="nc">SQLite3</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span> - - <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">app</span><span class="p">):</span> - <span class="bp">self</span><span class="o">.</span><span class="n">app</span> <span class="o">=</span> <span class="n">app</span> - <span class="bp">self</span><span class="o">.</span><span class="n">app</span><span class="o">.</span><span class="n">config</span><span class="o">.</span><span class="n">setdefault</span><span class="p">(</span><span class="s">'SQLITE3_DATABASE'</span><span class="p">,</span> <span class="s">':memory:'</span><span class="p">)</span> - <span class="bp">self</span><span class="o">.</span><span class="n">app</span><span class="o">.</span><span class="n">teardown_request</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">teardown_request</span><span class="p">)</span> - <span class="bp">self</span><span class="o">.</span><span class="n">app</span><span class="o">.</span><span class="n">before_request</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">before_request</span><span class="p">)</span> - - <span class="k">def</span> <span class="nf">connect</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> - <span class="k">return</span> <span class="n">sqlite3</span><span class="o">.</span><span class="n">connect</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">app</span><span class="o">.</span><span class="n">config</span><span class="p">[</span><span class="s">'SQLITE3_DATABASE'</span><span class="p">])</span> - - <span class="k">def</span> <span class="nf">before_request</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> - <span class="n">ctx</span> <span class="o">=</span> <span class="n">_request_ctx_stack</span><span class="o">.</span><span class="n">top</span> - <span class="n">ctx</span><span class="o">.</span><span class="n">sqlite3_db</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">connect</span><span class="p">()</span> - - <span class="k">def</span> <span class="nf">teardown_request</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">exception</span><span class="p">):</span> - <span class="n">ctx</span> <span class="o">=</span> <span class="n">_request_ctx_stack</span><span class="o">.</span><span class="n">top</span> - <span class="n">ctx</span><span class="o">.</span><span class="n">sqlite3_db</span><span class="o">.</span><span class="n">close</span><span class="p">()</span> - - <span class="k">def</span> <span class="nf">get_db</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> - <span class="n">ctx</span> <span class="o">=</span> <span class="n">_request_ctx_stack</span><span class="o">.</span><span class="n">top</span> - <span class="k">if</span> <span class="n">ctx</span> <span class="ow">is</span> <span class="ow">not</span> <span class="bp">None</span><span class="p">:</span> - <span class="k">return</span> <span class="n">ctx</span><span class="o">.</span><span class="n">sqlite3_db</span> -</pre></div> -</div> -<p>So here’s what these lines of code do:</p> -<ol class="arabic simple"> -<li>The <tt class="docutils literal"><span class="pre">__future__</span></tt> import is necessary to activate absolute imports. -Otherwise we could not call our module <cite>sqlite3.py</cite> and import the -top-level <cite>sqlite3</cite> module which actually implements the connection to -SQLite.</li> -<li>We create a class for our extension that requires a supplied <cite>app</cite> object, -sets a configuration for the database if it’s not there -(<a class="reference external" href="http://docs.python.org/dev/library/stdtypes.html#dict.setdefault" title="(in Python v3.3)"><tt class="xref py py-meth docutils literal"><span class="pre">dict.setdefault()</span></tt></a>), and attaches <cite>before_request</cite> and -<cite>teardown_request</cite> handlers.</li> -<li>Next, we define a <cite>connect</cite> function that opens a database connection.</li> -<li>Then we set up the request handlers we bound to the app above. Note here -that we’re attaching our database connection to the top request context via -<cite>_request_ctx_stack.top</cite>. Extensions should use the top context and not the -<cite>g</cite> object to store things like database connections.</li> -<li>Finally, we add a <cite>get_db</cite> function that simplifies access to the context’s -database.</li> -</ol> -<p>So why did we decide on a class based approach here? Because using our -extension looks something like this:</p> -<div class="highlight-python"><div class="highlight"><pre><span class="kn">from</span> <span class="nn">flask</span> <span class="kn">import</span> <span class="n">Flask</span> -<span class="kn">from</span> <span class="nn">flask_sqlite3</span> <span class="kn">import</span> <span class="n">SQLite3</span> - -<span class="n">app</span> <span class="o">=</span> <span class="n">Flask</span><span class="p">(</span><span class="n">__name__</span><span class="p">)</span> -<span class="n">app</span><span class="o">.</span><span class="n">config</span><span class="o">.</span><span class="n">from_pyfile</span><span class="p">(</span><span class="s">'the-config.cfg'</span><span class="p">)</span> -<span class="n">manager</span> <span class="o">=</span> <span class="n">SQLite3</span><span class="p">(</span><span class="n">app</span><span class="p">)</span> -<span class="n">db</span> <span class="o">=</span> <span class="n">manager</span><span class="o">.</span><span class="n">get_db</span><span class="p">()</span> -</pre></div> -</div> -<p>You can then use the database from views like this:</p> -<div class="highlight-python"><div class="highlight"><pre><span class="nd">@app.route</span><span class="p">(</span><span class="s">'/'</span><span class="p">)</span> -<span class="k">def</span> <span class="nf">show_all</span><span class="p">():</span> - <span class="n">cur</span> <span class="o">=</span> <span class="n">db</span><span class="o">.</span><span class="n">cursor</span><span class="p">()</span> - <span class="n">cur</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="o">...</span><span class="p">)</span> -</pre></div> -</div> -<p>Opening a database connection from outside a view function is simple.</p> -<div class="highlight-python"><div class="highlight"><pre><span class="gp">>>> </span><span class="kn">from</span> <span class="nn">yourapplication</span> <span class="kn">import</span> <span class="n">db</span> -<span class="gp">>>> </span><span class="n">cur</span> <span class="o">=</span> <span class="n">db</span><span class="o">.</span><span class="n">cursor</span><span class="p">()</span> -<span class="gp">>>> </span><span class="n">cur</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="o">...</span><span class="p">)</span> -</pre></div> -</div> -</div> -<div class="section" id="adding-an-init-app-function"> -<h2>Adding an <cite>init_app</cite> Function<a class="headerlink" href="#adding-an-init-app-function" title="Permalink to this headline">¶</a></h2> -<p>In practice, you’ll almost always want to permit users to initialize your -extension and provide an app object after the fact. This can help avoid -circular import problems when a user is breaking their app into multiple files. -Our extension could add an <cite>init_app</cite> function as follows:</p> -<div class="highlight-python"><div class="highlight"><pre><span class="k">class</span> <span class="nc">SQLite3</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span> - - <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">app</span><span class="o">=</span><span class="bp">None</span><span class="p">):</span> - <span class="k">if</span> <span class="n">app</span> <span class="ow">is</span> <span class="ow">not</span> <span class="bp">None</span><span class="p">:</span> - <span class="bp">self</span><span class="o">.</span><span class="n">app</span> <span class="o">=</span> <span class="n">app</span> - <span class="bp">self</span><span class="o">.</span><span class="n">init_app</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">app</span><span class="p">)</span> - <span class="k">else</span><span class="p">:</span> - <span class="bp">self</span><span class="o">.</span><span class="n">app</span> <span class="o">=</span> <span class="bp">None</span> - - <span class="k">def</span> <span class="nf">init_app</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">app</span><span class="p">):</span> - <span class="bp">self</span><span class="o">.</span><span class="n">app</span> <span class="o">=</span> <span class="n">app</span> - <span class="bp">self</span><span class="o">.</span><span class="n">app</span><span class="o">.</span><span class="n">config</span><span class="o">.</span><span class="n">setdefault</span><span class="p">(</span><span class="s">'SQLITE3_DATABASE'</span><span class="p">,</span> <span class="s">':memory:'</span><span class="p">)</span> - <span class="bp">self</span><span class="o">.</span><span class="n">app</span><span class="o">.</span><span class="n">teardown_request</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">teardown_request</span><span class="p">)</span> - <span class="bp">self</span><span class="o">.</span><span class="n">app</span><span class="o">.</span><span class="n">before_request</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">before_request</span><span class="p">)</span> - - <span class="k">def</span> <span class="nf">connect</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> - <span class="k">return</span> <span class="n">sqlite3</span><span class="o">.</span><span class="n">connect</span><span class="p">(</span><span class="n">app</span><span class="o">.</span><span class="n">config</span><span class="p">[</span><span class="s">'SQLITE3_DATABASE'</span><span class="p">])</span> - - <span class="k">def</span> <span class="nf">before_request</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> - <span class="n">ctx</span> <span class="o">=</span> <span class="n">_request_ctx_stack</span><span class="o">.</span><span class="n">top</span> - <span class="n">ctx</span><span class="o">.</span><span class="n">sqlite3_db</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">connect</span><span class="p">()</span> - - <span class="k">def</span> <span class="nf">teardown_request</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">exception</span><span class="p">):</span> - <span class="n">ctx</span> <span class="o">=</span> <span class="n">_request_ctx_stack</span><span class="o">.</span><span class="n">top</span> - <span class="n">ctx</span><span class="o">.</span><span class="n">sqlite3_db</span><span class="o">.</span><span class="n">close</span><span class="p">()</span> - - <span class="k">def</span> <span class="nf">get_db</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> - <span class="n">ctx</span> <span class="o">=</span> <span class="n">_request_ctx_stack</span><span class="o">.</span><span class="n">top</span> - <span class="k">if</span> <span class="n">ctx</span> <span class="ow">is</span> <span class="ow">not</span> <span class="bp">None</span><span class="p">:</span> - <span class="k">return</span> <span class="n">ctx</span><span class="o">.</span><span class="n">sqlite3_db</span> -</pre></div> -</div> -<p>The user could then initialize the extension in one file:</p> -<div class="highlight-python"><div class="highlight"><pre><span class="n">manager</span> <span class="o">=</span> <span class="n">SQLite3</span><span class="p">()</span> -</pre></div> -</div> -<p>and bind their app to the extension in another file:</p> -<div class="highlight-python"><div class="highlight"><pre><span class="n">manager</span><span class="o">.</span><span class="n">init_app</span><span class="p">(</span><span class="n">app</span><span class="p">)</span> -</pre></div> -</div> -</div> -<div class="section" id="end-of-request-behavior"> -<h2>End-Of-Request Behavior<a class="headerlink" href="#end-of-request-behavior" title="Permalink to this headline">¶</a></h2> -<p>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:</p> -<div class="highlight-python"><div class="highlight"><pre><span class="k">def</span> <span class="nf">close_connection</span><span class="p">(</span><span class="n">response</span><span class="p">):</span> - <span class="n">ctx</span> <span class="o">=</span> <span class="n">_request_ctx_stack</span><span class="o">.</span><span class="n">top</span> - <span class="n">ctx</span><span class="o">.</span><span class="n">sqlite3_db</span><span class="o">.</span><span class="n">close</span><span class="p">()</span> - <span class="k">return</span> <span class="n">response</span> - -<span class="k">if</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">app</span><span class="p">,</span> <span class="s">'teardown_request'</span><span class="p">):</span> - <span class="n">app</span><span class="o">.</span><span class="n">teardown_request</span><span class="p">(</span><span class="n">close_connection</span><span class="p">)</span> -<span class="k">else</span><span class="p">:</span> - <span class="n">app</span><span class="o">.</span><span class="n">after_request</span><span class="p">(</span><span class="n">close_connection</span><span class="p">)</span> -</pre></div> -</div> -<p>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.</p> -</div> -<div class="section" id="learn-from-others"> -<h2>Learn from Others<a class="headerlink" href="#learn-from-others" title="Permalink to this headline">¶</a></h2> -<p>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 <a class="reference external" href="http://flask.pocoo.org/extensions/">Flask Extension Registry</a>. If you feel -lost there is still the <a class="reference external" href="http://flask.pocoo.org/mailinglist/">mailinglist</a> and the <a class="reference external" href="http://flask.pocoo.org/community/irc/">IRC channel</a> 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.</p> -<p>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.</p> -<p>The best Flask extensions are extensions that share common idioms for the -API. And this can only work if collaboration happens early.</p> -</div> -<div class="section" id="approved-extensions"> -<h2>Approved Extensions<a class="headerlink" href="#approved-extensions" title="Permalink to this headline">¶</a></h2> -<p>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 <a class="reference external" href="http://flask.pocoo.org/extensions/">Flask -Extension Registry</a> and marked appropriately. If you want your own -extension to be approved you have to follow these guidelines:</p> -<ol class="arabic simple"> -<li>An approved Flask extension must provide exactly one package or module -named <tt class="docutils literal"><span class="pre">flask_extensionname</span></tt>. They might also reside inside a -<tt class="docutils literal"><span class="pre">flaskext</span></tt> namespace packages though this is discouraged now.</li> -<li>It must ship a testing suite that can either be invoked with <tt class="docutils literal"><span class="pre">make</span> <span class="pre">test</span></tt> -or <tt class="docutils literal"><span class="pre">python</span> <span class="pre">setup.py</span> <span class="pre">test</span></tt>. For test suites invoked with <tt class="docutils literal"><span class="pre">make</span> -<span class="pre">test</span></tt> the extension has to ensure that all dependencies for the test -are installed automatically, in case of <tt class="docutils literal"><span class="pre">python</span> <span class="pre">setup.py</span> <span class="pre">test</span></tt> -dependencies for tests alone can be specified in the <cite>setup.py</cite> -file. The test suite also has to be part of the distribution.</li> -<li>APIs of approved extensions will be checked for the following -characteristics:<ul> -<li>an approved extension has to support multiple applications -running in the same Python process.</li> -<li>it must be possible to use the factory pattern for creating -applications.</li> -</ul> -</li> -<li>The license must be BSD/MIT/WTFPL licensed.</li> -<li>The naming scheme for official extensions is <em>Flask-ExtensionName</em> or -<em>ExtensionName-Flask</em>.</li> -<li>Approved extensions must define all their dependencies in the -<cite>setup.py</cite> file unless a dependency cannot be met because it is not -available on PyPI.</li> -<li>The extension must have documentation that uses one of the two Flask -themes for Sphinx documentation.</li> -<li>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 -(<tt class="docutils literal"><span class="pre">PackageName==dev</span></tt>).</li> -<li>The <tt class="docutils literal"><span class="pre">zip_safe</span></tt> flag in the setup script must be set to <tt class="docutils literal"><span class="pre">False</span></tt>, -even if the extension would be safe for zipping.</li> -<li>An extension currently has to support Python 2.5, 2.6 as well as -Python 2.7</li> -</ol> -</div> -<div class="section" id="extension-import-transition"> -<span id="ext-import-transition"></span><h2>Extension Import Transition<a class="headerlink" href="#extension-import-transition" title="Permalink to this headline">¶</a></h2> -<p>For a while we recommended using namespace packages for Flask extensions. -This turned out to be problematic in practice because many different -competing namespace package systems exist and pip would automatically -switch between different systems and this caused a lot of problems for -users.</p> -<p>Instead we now recommend naming packages <tt class="docutils literal"><span class="pre">flask_foo</span></tt> instead of the now -deprecated <tt class="docutils literal"><span class="pre">flaskext.foo</span></tt>. Flask 0.8 introduces a redirect import -system that lets uses import from <tt class="docutils literal"><span class="pre">flask.ext.foo</span></tt> and it will try -<tt class="docutils literal"><span class="pre">flask_foo</span></tt> first and if that fails <tt class="docutils literal"><span class="pre">flaskext.foo</span></tt>.</p> -<p>Flask extensions should urge users to import from <tt class="docutils literal"><span class="pre">flask.ext.foo</span></tt> -instead of <tt class="docutils literal"><span class="pre">flask_foo</span></tt> or <tt class="docutils literal"><span class="pre">flaskext_foo</span></tt> so that extensions can -transition to the new package name without affecting users.</p> -</div> -</div> - - - </div> - </div> - </div> - <div class="sphinxsidebar"> - <div class="sphinxsidebarwrapper"><p class="logo"><a href="index.html"> - <img class="logo" src="_static/flask.png" alt="Logo"/> -</a></p> - <h3><a href="index.html">Table Of Contents</a></h3> - <ul> -<li><a class="reference internal" href="#">Flask Extension Development</a><ul> -<li><a class="reference internal" href="#anatomy-of-an-extension">Anatomy of an Extension</a></li> -<li><a class="reference internal" href="#hello-flaskext">“Hello Flaskext!”</a><ul> -<li><a class="reference internal" href="#setup-py">setup.py</a></li> -<li><a class="reference internal" href="#flask-sqlite3-py">flask_sqlite3.py</a></li> -</ul> -</li> -<li><a class="reference internal" href="#initializing-extensions">Initializing Extensions</a></li> -<li><a class="reference internal" href="#the-extension-code">The Extension Code</a></li> -<li><a class="reference internal" href="#adding-an-init-app-function">Adding an <cite>init_app</cite> Function</a></li> -<li><a class="reference internal" href="#end-of-request-behavior">End-Of-Request Behavior</a></li> -<li><a class="reference internal" href="#learn-from-others">Learn from Others</a></li> -<li><a class="reference internal" href="#approved-extensions">Approved Extensions</a></li> -<li><a class="reference internal" href="#extension-import-transition">Extension Import Transition</a></li> -</ul> -</li> -</ul> -<h3>Related Topics</h3> -<ul> - <li><a href="index.html">Documentation overview</a><ul> - <li>Previous: <a href="unicode.html" title="previous chapter">Unicode in Flask</a></li> - <li>Next: <a href="styleguide.html" title="next chapter">Pocoo Styleguide</a></li> - </ul></li> -</ul> - <h3>This Page</h3> - <ul class="this-page-menu"> - <li><a href="_sources/extensiondev.txt" - rel="nofollow">Show Source</a></li> - </ul> -<div id="searchbox" style="display: none"> - <h3>Quick search</h3> - <form class="search" action="search.html" method="get"> - <input type="text" name="q" /> - <input type="submit" value="Go" /> - <input type="hidden" name="check_keywords" value="yes" /> - <input type="hidden" name="area" value="default" /> - </form> - <p class="searchtip" style="font-size: 90%"> - Enter search terms or a module, class or function name. - </p> -</div> -<script type="text/javascript">$('#searchbox').show(0);</script> - </div> - </div> - <div class="clearer"></div> - </div> - <div class="footer"> - © Copyright 2010, Armin Ronacher. - Created using <a href="http://sphinx.pocoo.org/">Sphinx</a>. - </div> - </body> -</html>
\ No newline at end of file |