Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/app/static/doc/flask-docs/extensiondev.html
blob: 05044b0700ebb58d23cd68782239771f153d0d5a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475

<!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 &mdash; 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> &raquo;</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 &#8220;something&#8221; 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&#8217;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 &#8220;Flask-SimpleXML&#8221;.  Make sure to include the name
&#8220;Flask&#8221; 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>&#8220;Hello Flaskext!&#8221;<a class="headerlink" href="#hello-flaskext" title="Permalink to this headline">¶</a></h2>
<p>So let&#8217;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&#8217;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">&quot;&quot;&quot;</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">&quot;&quot;&quot;</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">&#39;Flask-SQLite3&#39;</span><span class="p">,</span>
    <span class="n">version</span><span class="o">=</span><span class="s">&#39;1.0&#39;</span><span class="p">,</span>
    <span class="n">url</span><span class="o">=</span><span class="s">&#39;http://example.com/flask-sqlite3/&#39;</span><span class="p">,</span>
    <span class="n">license</span><span class="o">=</span><span class="s">&#39;BSD&#39;</span><span class="p">,</span>
    <span class="n">author</span><span class="o">=</span><span class="s">&#39;Your Name&#39;</span><span class="p">,</span>
    <span class="n">author_email</span><span class="o">=</span><span class="s">&#39;your-email@example.com&#39;</span><span class="p">,</span>
    <span class="n">description</span><span class="o">=</span><span class="s">&#39;Very short description&#39;</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">&#39;flask_sqlite3&#39;</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=[&#39;flask_sqlite3&#39;],</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">&#39;any&#39;</span><span class="p">,</span>
    <span class="n">install_requires</span><span class="o">=</span><span class="p">[</span>
        <span class="s">&#39;Flask&#39;</span>
    <span class="p">],</span>
    <span class="n">classifiers</span><span class="o">=</span><span class="p">[</span>
        <span class="s">&#39;Environment :: Web Environment&#39;</span><span class="p">,</span>
        <span class="s">&#39;Intended Audience :: Developers&#39;</span><span class="p">,</span>
        <span class="s">&#39;License :: OSI Approved :: BSD License&#39;</span><span class="p">,</span>
        <span class="s">&#39;Operating System :: OS Independent&#39;</span><span class="p">,</span>
        <span class="s">&#39;Programming Language :: Python&#39;</span><span class="p">,</span>
        <span class="s">&#39;Topic :: Internet :: WWW/HTTP :: Dynamic Content&#39;</span><span class="p">,</span>
        <span class="s">&#39;Topic :: Software Development :: Libraries :: Python Modules&#39;</span>
    <span class="p">]</span>
<span class="p">)</span>
</pre></div>
</div>
<p>That&#8217;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&#8217;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">&#39;SQLITE3_DATABASE&#39;</span><span class="p">,</span> <span class="s">&#39;:memory:&#39;</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">&#39;SQLITE3_DATABASE&#39;</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&#8217;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&#8217;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&#8217;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&#8217;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">&#39;the-config.cfg&#39;</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">&#39;/&#39;</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">&gt;&gt;&gt; </span><span class="kn">from</span> <span class="nn">yourapplication</span> <span class="kn">import</span> <span class="n">db</span>
<span class="gp">&gt;&gt;&gt; </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">&gt;&gt;&gt; </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&#8217;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">&#39;SQLITE3_DATABASE&#39;</span><span class="p">,</span> <span class="s">&#39;:memory:&#39;</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">&#39;SQLITE3_DATABASE&#39;</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">&#39;teardown_request&#39;</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&#8217;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&#8217;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">&#8220;Hello Flaskext!&#8221;</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">
      &copy; Copyright 2010, Armin Ronacher.
      Created using <a href="http://sphinx.pocoo.org/">Sphinx</a>.
    </div>
  </body>
</html>