diff options
Diffstat (limited to 'app/static/doc/flask-docs/quickstart.html')
-rw-r--r-- | app/static/doc/flask-docs/quickstart.html | 875 |
1 files changed, 875 insertions, 0 deletions
diff --git a/app/static/doc/flask-docs/quickstart.html b/app/static/doc/flask-docs/quickstart.html new file mode 100644 index 0000000..4a26798 --- /dev/null +++ b/app/static/doc/flask-docs/quickstart.html @@ -0,0 +1,875 @@ + +<!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>Quickstart — 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="Tutorial" href="tutorial/index.html" /> + <link rel="prev" title="Installation" href="installation.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="tutorial/index.html" title="Tutorial" + accesskey="N">next</a> |</li> + <li class="right" > + <a href="installation.html" title="Installation" + 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="quickstart"> +<span id="id1"></span><h1>Quickstart<a class="headerlink" href="#quickstart" title="Permalink to this headline">¶</a></h1> +<p>Eager to get started? This page gives a good introduction in how to get +started with Flask. This assumes you already have Flask installed. If +you do not, head over to the <a class="reference internal" href="installation.html#installation"><em>Installation</em></a> section.</p> +<div class="section" id="a-minimal-application"> +<h2>A Minimal Application<a class="headerlink" href="#a-minimal-application" title="Permalink to this headline">¶</a></h2> +<p>A minimal Flask application 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="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="nd">@app.route</span><span class="p">(</span><span class="s">'/'</span><span class="p">)</span> +<span class="k">def</span> <span class="nf">hello_world</span><span class="p">():</span> + <span class="k">return</span> <span class="s">'Hello World!'</span> + +<span class="k">if</span> <span class="n">__name__</span> <span class="o">==</span> <span class="s">'__main__'</span><span class="p">:</span> + <span class="n">app</span><span class="o">.</span><span class="n">run</span><span class="p">()</span> +</pre></div> +</div> +<p>Just save it as <cite>hello.py</cite> or something similar and run it with your +Python interpreter. Make sure to not call your application <cite>flask.py</cite> +because this would conflict with Flask itself.</p> +<div class="highlight-python"><pre>$ python hello.py + * Running on http://127.0.0.1:5000/</pre> +</div> +<p>Head over to <a class="reference external" href="http://127.0.0.1:5000/">http://127.0.0.1:5000/</a>, you should +see your hello world greeting.</p> +<p>So what did that code do?</p> +<ol class="arabic simple"> +<li>First we imported the <a class="reference internal" href="api.html#flask.Flask" title="flask.Flask"><tt class="xref py py-class docutils literal"><span class="pre">Flask</span></tt></a> class. An instance of this +class will be our WSGI application. The first argument is the name of +the application’s module. If you are using a single module (like here) +you should use <cite>__name__</cite> because depending on if it’s started as +application or imported as module the name will be different +(<tt class="docutils literal"><span class="pre">'__main__'</span></tt> versus the actual import name). For more information +on that, have a look at the <a class="reference internal" href="api.html#flask.Flask" title="flask.Flask"><tt class="xref py py-class docutils literal"><span class="pre">Flask</span></tt></a> documentation.</li> +<li>Next we create an instance of it. We pass it the name of the module / +package. This is needed so that Flask knows where it should look for +templates, static files and so on.</li> +<li>Then we use the <a class="reference internal" href="api.html#flask.Flask.route" title="flask.Flask.route"><tt class="xref py py-meth docutils literal"><span class="pre">route()</span></tt></a> decorator to tell Flask +what URL should trigger our function.</li> +<li>The function then has a name which is also used to generate URLs to +that particular function, and returns the message we want to display in +the user’s browser.</li> +<li>Finally we use the <a class="reference internal" href="api.html#flask.Flask.run" title="flask.Flask.run"><tt class="xref py py-meth docutils literal"><span class="pre">run()</span></tt></a> function to run the +local server with our application. The <tt class="docutils literal"><span class="pre">if</span> <span class="pre">__name__</span> <span class="pre">==</span> <span class="pre">'__main__':</span></tt> +makes sure the server only runs if the script is executed directly from +the Python interpreter and not used as imported module.</li> +</ol> +<p>To stop the server, hit control-C.</p> +<div class="admonition-externally-visible-server admonition " id="public-server"> +<p class="first admonition-title">Externally Visible Server</p> +<p>If you run the server you will notice that the server is only available +from your own computer, not from any other in the network. This is the +default because in debugging mode a user of the application can execute +arbitrary Python code on your computer. If you have <cite>debug</cite> disabled +or trust the users on your network, you can make the server publicly +available.</p> +<p>Just change the call of the <a class="reference internal" href="api.html#flask.Flask.run" title="flask.Flask.run"><tt class="xref py py-meth docutils literal"><span class="pre">run()</span></tt></a> method to look +like this:</p> +<div class="highlight-python"><div class="highlight"><pre><span class="n">app</span><span class="o">.</span><span class="n">run</span><span class="p">(</span><span class="n">host</span><span class="o">=</span><span class="s">'0.0.0.0'</span><span class="p">)</span> +</pre></div> +</div> +<p class="last">This tells your operating system to listen on a public IP.</p> +</div> +</div> +<div class="section" id="debug-mode"> +<h2>Debug Mode<a class="headerlink" href="#debug-mode" title="Permalink to this headline">¶</a></h2> +<p>The <a class="reference internal" href="api.html#flask.Flask.run" title="flask.Flask.run"><tt class="xref py py-meth docutils literal"><span class="pre">run()</span></tt></a> method is nice to start a local +development server, but you would have to restart it manually after each +change you do to code. That is not very nice and Flask can do better. If +you enable the debug support the server will reload itself on code changes +and also provide you with a helpful debugger if things go wrong.</p> +<p>There are two ways to enable debugging. Either set that flag on the +application object:</p> +<div class="highlight-python"><div class="highlight"><pre><span class="n">app</span><span class="o">.</span><span class="n">debug</span> <span class="o">=</span> <span class="bp">True</span> +<span class="n">app</span><span class="o">.</span><span class="n">run</span><span class="p">()</span> +</pre></div> +</div> +<p>Or pass it to run:</p> +<div class="highlight-python"><div class="highlight"><pre><span class="n">app</span><span class="o">.</span><span class="n">run</span><span class="p">(</span><span class="n">debug</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span> +</pre></div> +</div> +<p>Both will have exactly the same effect.</p> +<div class="admonition-attention admonition "> +<p class="first admonition-title">Attention</p> +<p class="last">Even though the interactive debugger does not work in forking environments +(which makes it nearly impossible to use on production servers), it still +allows the execution of arbitrary code. That makes it a major security +risk and therefore it <strong>must never be used on production machines</strong>.</p> +</div> +<p>Screenshot of the debugger in action:</p> +<img alt="screenshot of debugger in action" class="screenshot align-center" src="_images/debugger5.png" /> +<div class="admonition-working-with-other-debuggers admonition "> +<p class="first admonition-title">Working With Other Debuggers</p> +<p class="last">Debuggers interfere with each other. If you are using another debugger +(e.g. PyDev or IntelliJ), you may need to set <tt class="docutils literal"><span class="pre">app.debug</span> <span class="pre">=</span> <span class="pre">False</span></tt>.</p> +</div> +</div> +<div class="section" id="routing"> +<h2>Routing<a class="headerlink" href="#routing" title="Permalink to this headline">¶</a></h2> +<p>Modern web applications have beautiful URLs. This helps people remember +the URLs which is especially handy for applications that are used from +mobile devices with slower network connections. If the user can directly +go to the desired page without having to hit the index page it is more +likely they will like the page and come back next time.</p> +<p>As you have seen above, the <a class="reference internal" href="api.html#flask.Flask.route" title="flask.Flask.route"><tt class="xref py py-meth docutils literal"><span class="pre">route()</span></tt></a> decorator is used +to bind a function to a URL. Here are some basic examples:</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">index</span><span class="p">():</span> + <span class="k">return</span> <span class="s">'Index Page'</span> + +<span class="nd">@app.route</span><span class="p">(</span><span class="s">'/hello'</span><span class="p">)</span> +<span class="k">def</span> <span class="nf">hello</span><span class="p">():</span> + <span class="k">return</span> <span class="s">'Hello World'</span> +</pre></div> +</div> +<p>But there is more to it! You can make certain parts of the URL dynamic +and attach multiple rules to a function.</p> +<div class="section" id="variable-rules"> +<h3>Variable Rules<a class="headerlink" href="#variable-rules" title="Permalink to this headline">¶</a></h3> +<p>To add variable parts to a URL you can mark these special sections as +<tt class="docutils literal"><span class="pre"><variable_name></span></tt>. Such a part is then passed as keyword argument to +your function. Optionally a converter can be specified by specifying a +rule with <tt class="docutils literal"><span class="pre"><converter:variable_name></span></tt>. Here are some nice examples:</p> +<div class="highlight-python"><div class="highlight"><pre><span class="nd">@app.route</span><span class="p">(</span><span class="s">'/user/<username>'</span><span class="p">)</span> +<span class="k">def</span> <span class="nf">show_user_profile</span><span class="p">(</span><span class="n">username</span><span class="p">):</span> + <span class="c"># show the user profile for that user</span> + <span class="k">pass</span> + +<span class="nd">@app.route</span><span class="p">(</span><span class="s">'/post/<int:post_id>'</span><span class="p">)</span> +<span class="k">def</span> <span class="nf">show_post</span><span class="p">(</span><span class="n">post_id</span><span class="p">):</span> + <span class="c"># show the post with the given id, the id is an integer</span> + <span class="k">pass</span> +</pre></div> +</div> +<p>The following converters exist:</p> +<table border="1" class="docutils"> +<colgroup> +<col width="20%" /> +<col width="80%" /> +</colgroup> +<tbody valign="top"> +<tr class="row-odd"><td><cite>int</cite></td> +<td>accepts integers</td> +</tr> +<tr class="row-even"><td><cite>float</cite></td> +<td>like <cite>int</cite> but for floating point values</td> +</tr> +<tr class="row-odd"><td><cite>path</cite></td> +<td>like the default but also accepts slashes</td> +</tr> +</tbody> +</table> +<div class="admonition-unique-urls-redirection-behaviour admonition "> +<p class="first admonition-title">Unique URLs / Redirection Behaviour</p> +<p>Flask’s URL rules are based on Werkzeug’s routing module. The idea +behind that module is to ensure nice looking and also unique URLs based +on behaviour Apache and earlier servers coined.</p> +<p>Take these two rules:</p> +<div class="highlight-python"><div class="highlight"><pre><span class="nd">@app.route</span><span class="p">(</span><span class="s">'/projects/'</span><span class="p">)</span> +<span class="k">def</span> <span class="nf">projects</span><span class="p">():</span> + <span class="k">pass</span> + +<span class="nd">@app.route</span><span class="p">(</span><span class="s">'/about'</span><span class="p">)</span> +<span class="k">def</span> <span class="nf">about</span><span class="p">():</span> + <span class="k">pass</span> +</pre></div> +</div> +<p>They look rather similar, the difference is the trailing slash in the +URL <em>definition</em>. In the first case, the canonical URL for the +<cite>projects</cite> endpoint has a trailing slash. It’s similar to a folder in +that sense. Accessing it without a trailing slash will cause Flask to +redirect to the canonical URL with the trailing slash.</p> +<p>However in the second case the URL is defined without a slash so it +behaves similar to a file and accessing the URL with a trailing slash +will be a 404 error.</p> +<p class="last">Why is this? This allows relative URLs to continue working if users +access the page when they forget a trailing slash. This behaviour is +also consistent with how Apache and other servers work. Also, the URLs +will stay unique which helps search engines not indexing the same page +twice.</p> +</div> +</div> +<div class="section" id="url-building"> +<span id="id2"></span><h3>URL Building<a class="headerlink" href="#url-building" title="Permalink to this headline">¶</a></h3> +<p>If it can match URLs, can it also generate them? Of course it can. To +build a URL to a specific function you can use the <a class="reference internal" href="api.html#flask.url_for" title="flask.url_for"><tt class="xref py py-func docutils literal"><span class="pre">url_for()</span></tt></a> +function. It accepts the name of the function as first argument and a +number of keyword arguments, each corresponding to the variable part of +the URL rule. Unknown variable parts are appended to the URL as query +parameter. Here are some examples:</p> +<div class="highlight-python"><div class="highlight"><pre><span class="gp">>>> </span><span class="kn">from</span> <span class="nn">flask</span> <span class="kn">import</span> <span class="n">Flask</span><span class="p">,</span> <span class="n">url_for</span> +<span class="gp">>>> </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="gp">>>> </span><span class="nd">@app.route</span><span class="p">(</span><span class="s">'/'</span><span class="p">)</span> +<span class="gp">... </span><span class="k">def</span> <span class="nf">index</span><span class="p">():</span> <span class="k">pass</span> +<span class="gp">...</span> +<span class="gp">>>> </span><span class="nd">@app.route</span><span class="p">(</span><span class="s">'/login'</span><span class="p">)</span> +<span class="gp">... </span><span class="k">def</span> <span class="nf">login</span><span class="p">():</span> <span class="k">pass</span> +<span class="gp">...</span> +<span class="gp">>>> </span><span class="nd">@app.route</span><span class="p">(</span><span class="s">'/user/<username>'</span><span class="p">)</span> +<span class="gp">... </span><span class="k">def</span> <span class="nf">profile</span><span class="p">(</span><span class="n">username</span><span class="p">):</span> <span class="k">pass</span> +<span class="gp">...</span> +<span class="gp">>>> </span><span class="k">with</span> <span class="n">app</span><span class="o">.</span><span class="n">test_request_context</span><span class="p">():</span> +<span class="gp">... </span> <span class="k">print</span> <span class="n">url_for</span><span class="p">(</span><span class="s">'index'</span><span class="p">)</span> +<span class="gp">... </span> <span class="k">print</span> <span class="n">url_for</span><span class="p">(</span><span class="s">'login'</span><span class="p">)</span> +<span class="gp">... </span> <span class="k">print</span> <span class="n">url_for</span><span class="p">(</span><span class="s">'login'</span><span class="p">,</span> <span class="nb">next</span><span class="o">=</span><span class="s">'/'</span><span class="p">)</span> +<span class="gp">... </span> <span class="k">print</span> <span class="n">url_for</span><span class="p">(</span><span class="s">'profile'</span><span class="p">,</span> <span class="n">username</span><span class="o">=</span><span class="s">'John Doe'</span><span class="p">)</span> +<span class="gp">...</span> +<span class="go">/</span> +<span class="go">/login</span> +<span class="go">/login?next=/</span> +<span class="go">/user/John%20Doe</span> +</pre></div> +</div> +<p>(This also uses the <a class="reference internal" href="api.html#flask.Flask.test_request_context" title="flask.Flask.test_request_context"><tt class="xref py py-meth docutils literal"><span class="pre">test_request_context()</span></tt></a> method +explained below. It basically tells Flask to think we are handling a +request even though we are not, we are in an interactive Python shell. +Have a look at the explanation below. <a class="reference internal" href="#context-locals"><em>Context Locals</em></a>).</p> +<p>Why would you want to build URLs instead of hardcoding them in your +templates? There are three good reasons for this:</p> +<ol class="arabic simple"> +<li>reversing is often more descriptive than hardcoding the URLs. Also and +more importantly you can change URLs in one go without having to change +the URLs all over the place.</li> +<li>URL building will handle escaping of special characters and Unicode +data transparently for you, you don’t have to deal with that.</li> +<li>If your application is placed outside the URL root (so say in +<tt class="docutils literal"><span class="pre">/myapplication</span></tt> instead of <tt class="docutils literal"><span class="pre">/</span></tt>), <a class="reference internal" href="api.html#flask.url_for" title="flask.url_for"><tt class="xref py py-func docutils literal"><span class="pre">url_for()</span></tt></a> will +handle that properly for you.</li> +</ol> +</div> +<div class="section" id="http-methods"> +<h3>HTTP Methods<a class="headerlink" href="#http-methods" title="Permalink to this headline">¶</a></h3> +<p>HTTP (the protocol web applications are speaking) knows different methods +to access URLs. By default a route only answers to <cite>GET</cite> requests, but +that can be changed by providing the <cite>methods</cite> argument to the +<a class="reference internal" href="api.html#flask.Flask.route" title="flask.Flask.route"><tt class="xref py py-meth docutils literal"><span class="pre">route()</span></tt></a> decorator. Here are some examples:</p> +<div class="highlight-python"><div class="highlight"><pre><span class="nd">@app.route</span><span class="p">(</span><span class="s">'/login'</span><span class="p">,</span> <span class="n">methods</span><span class="o">=</span><span class="p">[</span><span class="s">'GET'</span><span class="p">,</span> <span class="s">'POST'</span><span class="p">])</span> +<span class="k">def</span> <span class="nf">login</span><span class="p">():</span> + <span class="k">if</span> <span class="n">request</span><span class="o">.</span><span class="n">method</span> <span class="o">==</span> <span class="s">'POST'</span><span class="p">:</span> + <span class="n">do_the_login</span><span class="p">()</span> + <span class="k">else</span><span class="p">:</span> + <span class="n">show_the_login_form</span><span class="p">()</span> +</pre></div> +</div> +<p>If <cite>GET</cite> is present, <cite>HEAD</cite> will be added automatically for you. You +don’t have to deal with that. It will also make sure that <cite>HEAD</cite> requests +are handled like the <a class="reference external" href="http://www.ietf.org/rfc/rfc2068.txt">HTTP RFC</a> (the document describing the HTTP +protocol) demands, so you can completely ignore that part of the HTTP +specification. Likewise as of Flask 0.6, <cite>OPTIONS</cite> is implemented for you +as well automatically.</p> +<p>You have no idea what an HTTP method is? Worry not, here is a quick +introduction to HTTP methods and why they matter:</p> +<p>The HTTP method (also often called “the verb”) tells the server what the +clients wants to <em>do</em> with the requested page. The following methods are +very common:</p> +<dl class="docutils"> +<dt><cite>GET</cite></dt> +<dd>The browser tells the server to just <em>get</em> the information stored on +that page and send it. This is probably the most common method.</dd> +<dt><cite>HEAD</cite></dt> +<dd>The browser tells the server to get the information, but it is only +interested in the <em>headers</em>, not the content of the page. An +application is supposed to handle that as if a <cite>GET</cite> request was +received but to not deliver the actual content. In Flask you don’t +have to deal with that at all, the underlying Werkzeug library handles +that for you.</dd> +<dt><cite>POST</cite></dt> +<dd>The browser tells the server that it wants to <em>post</em> some new +information to that URL and that the server must ensure the data is +stored and only stored once. This is how HTML forms are usually +transmitting data to the server.</dd> +<dt><cite>PUT</cite></dt> +<dd>Similar to <cite>POST</cite> but the server might trigger the store procedure +multiple times by overwriting the old values more than once. Now you +might be asking why is this useful, but there are some good reasons +to do it this way. Consider that the connection gets lost during +transmission: in this situation a system between the browser and the +server might receive the request safely a second time without breaking +things. With <cite>POST</cite> that would not be possible because it must only +be triggered once.</dd> +<dt><cite>DELETE</cite></dt> +<dd>Remove the information at the given location.</dd> +<dt><cite>OPTIONS</cite></dt> +<dd>Provides a quick way for a client to figure out which methods are +supported by this URL. Starting with Flask 0.6, this is implemented +for you automatically.</dd> +</dl> +<p>Now the interesting part is that in HTML4 and XHTML1, the only methods a +form can submit to the server are <cite>GET</cite> and <cite>POST</cite>. But with JavaScript +and future HTML standards you can use the other methods as well. Furthermore +HTTP has become quite popular lately and browsers are no longer the only +clients that are using HTTP. For instance, many revision control system +use it.</p> +</div> +</div> +<div class="section" id="static-files"> +<h2>Static Files<a class="headerlink" href="#static-files" title="Permalink to this headline">¶</a></h2> +<p>Dynamic web applications need static files as well. That’s usually where +the CSS and JavaScript files are coming from. Ideally your web server is +configured to serve them for you, but during development Flask can do that +as well. Just create a folder called <cite>static</cite> in your package or next to +your module and it will be available at <cite>/static</cite> on the application.</p> +<p>To generate URLs to that part of the URL, use the special <tt class="docutils literal"><span class="pre">'static'</span></tt> URL +name:</p> +<div class="highlight-python"><div class="highlight"><pre><span class="n">url_for</span><span class="p">(</span><span class="s">'static'</span><span class="p">,</span> <span class="n">filename</span><span class="o">=</span><span class="s">'style.css'</span><span class="p">)</span> +</pre></div> +</div> +<p>The file has to be stored on the filesystem as <tt class="docutils literal"><span class="pre">static/style.css</span></tt>.</p> +</div> +<div class="section" id="rendering-templates"> +<h2>Rendering Templates<a class="headerlink" href="#rendering-templates" title="Permalink to this headline">¶</a></h2> +<p>Generating HTML from within Python is not fun, and actually pretty +cumbersome because you have to do the HTML escaping on your own to keep +the application secure. Because of that Flask configures the <a class="reference external" href="http://jinja.pocoo.org/2/">Jinja2</a> template engine for you automatically.</p> +<p>To render a template you can use the <a class="reference internal" href="api.html#flask.render_template" title="flask.render_template"><tt class="xref py py-func docutils literal"><span class="pre">render_template()</span></tt></a> +method. All you have to do is to provide the name of the template and the +variables you want to pass to the template engine as keyword arguments. +Here’s a simple example of how to render a template:</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">render_template</span> + +<span class="nd">@app.route</span><span class="p">(</span><span class="s">'/hello/'</span><span class="p">)</span> +<span class="nd">@app.route</span><span class="p">(</span><span class="s">'/hello/<name>'</span><span class="p">)</span> +<span class="k">def</span> <span class="nf">hello</span><span class="p">(</span><span class="n">name</span><span class="o">=</span><span class="bp">None</span><span class="p">):</span> + <span class="k">return</span> <span class="n">render_template</span><span class="p">(</span><span class="s">'hello.html'</span><span class="p">,</span> <span class="n">name</span><span class="o">=</span><span class="n">name</span><span class="p">)</span> +</pre></div> +</div> +<p>Flask will look for templates in the <cite>templates</cite> folder. So if your +application is a module, that folder is next to that module, if it’s a +package it’s actually inside your package:</p> +<p><strong>Case 1</strong>: a module:</p> +<div class="highlight-python"><pre>/application.py +/templates + /hello.html</pre> +</div> +<p><strong>Case 2</strong>: a package:</p> +<div class="highlight-python"><pre>/application + /__init__.py + /templates + /hello.html</pre> +</div> +<p>For templates you can use the full power of Jinja2 templates. Head over +to the the official <a class="reference external" href="http://jinja.pocoo.org/2/documentation/templates">Jinja2 Template Documentation</a> for more information.</p> +<p>Here is an example template:</p> +<div class="highlight-html+jinja"><div class="highlight"><pre><span class="cp"><!doctype html></span> +<span class="nt"><title></span>Hello from Flask<span class="nt"></title></span> +<span class="cp">{%</span> <span class="k">if</span> <span class="nv">name</span> <span class="cp">%}</span> + <span class="nt"><h1></span>Hello <span class="cp">{{</span> <span class="nv">name</span> <span class="cp">}}</span>!<span class="nt"></h1></span> +<span class="cp">{%</span> <span class="k">else</span> <span class="cp">%}</span> + <span class="nt"><h1></span>Hello World!<span class="nt"></h1></span> +<span class="cp">{%</span> <span class="k">endif</span> <span class="cp">%}</span> +</pre></div> +</div> +<p>Inside templates you also have access to the <a class="reference internal" href="api.html#flask.request" title="flask.request"><tt class="xref py py-class docutils literal"><span class="pre">request</span></tt></a>, +<a class="reference internal" href="api.html#flask.session" title="flask.session"><tt class="xref py py-class docutils literal"><span class="pre">session</span></tt></a> and <a class="reference internal" href="api.html#flask.g" title="flask.g"><tt class="xref py py-class docutils literal"><span class="pre">g</span></tt></a> <a class="footnote-reference" href="#id4" id="id3">[1]</a> objects +as well as the <a class="reference internal" href="api.html#flask.get_flashed_messages" title="flask.get_flashed_messages"><tt class="xref py py-func docutils literal"><span class="pre">get_flashed_messages()</span></tt></a> function.</p> +<p>Templates are especially useful if inheritance is used. If you want to +know how that works, head over to the <a class="reference internal" href="patterns/templateinheritance.html#template-inheritance"><em>Template Inheritance</em></a> pattern +documentation. Basically template inheritance makes it possible to keep +certain elements on each page (like header, navigation and footer).</p> +<p>Automatic escaping is enabled, so if name contains HTML it will be escaped +automatically. If you can trust a variable and you know that it will be +safe HTML (because for example it came from a module that converts wiki +markup to HTML) you can mark it as safe by using the +<tt class="xref py py-class docutils literal"><span class="pre">Markup</span></tt> class or by using the <tt class="docutils literal"><span class="pre">|safe</span></tt> filter in the +template. Head over to the Jinja 2 documentation for more examples.</p> +<p>Here is a basic introduction to how the <tt class="xref py py-class docutils literal"><span class="pre">Markup</span></tt> class works:</p> +<div class="highlight-python"><div class="highlight"><pre><span class="gp">>>> </span><span class="kn">from</span> <span class="nn">flask</span> <span class="kn">import</span> <span class="n">Markup</span> +<span class="gp">>>> </span><span class="n">Markup</span><span class="p">(</span><span class="s">'<strong>Hello </span><span class="si">%s</span><span class="s">!</strong>'</span><span class="p">)</span> <span class="o">%</span> <span class="s">'<blink>hacker</blink>'</span> +<span class="go">Markup(u'<strong>Hello &lt;blink&gt;hacker&lt;/blink&gt;!</strong>')</span> +<span class="gp">>>> </span><span class="n">Markup</span><span class="o">.</span><span class="n">escape</span><span class="p">(</span><span class="s">'<blink>hacker</blink>'</span><span class="p">)</span> +<span class="go">Markup(u'&lt;blink&gt;hacker&lt;/blink&gt;')</span> +<span class="gp">>>> </span><span class="n">Markup</span><span class="p">(</span><span class="s">'<em>Marked up</em> &raquo; HTML'</span><span class="p">)</span><span class="o">.</span><span class="n">striptags</span><span class="p">()</span> +<span class="go">u'Marked up \xbb HTML'</span> +</pre></div> +</div> +<p class="versionchanged"> +<span class="versionmodified">Changed in version 0.5.</span></p> +<table class="docutils footnote" frame="void" id="id4" rules="none"> +<colgroup><col class="label" /><col /></colgroup> +<tbody valign="top"> +<tr><td class="label"><a class="fn-backref" href="#id3">[1]</a></td><td>Unsure what that <a class="reference internal" href="api.html#flask.g" title="flask.g"><tt class="xref py py-class docutils literal"><span class="pre">g</span></tt></a> object is? It’s something in which +you can store information for your own needs, check the documentation of +that object (<a class="reference internal" href="api.html#flask.g" title="flask.g"><tt class="xref py py-class docutils literal"><span class="pre">g</span></tt></a>) and the <a class="reference internal" href="patterns/sqlite3.html#sqlite3"><em>Using SQLite 3 with Flask</em></a> for more +information.</td></tr> +</tbody> +</table> +</div> +<div class="section" id="accessing-request-data"> +<h2>Accessing Request Data<a class="headerlink" href="#accessing-request-data" title="Permalink to this headline">¶</a></h2> +<p>For web applications it’s crucial to react to the data a client sent to +the server. In Flask this information is provided by the global +<a class="reference internal" href="api.html#flask.request" title="flask.request"><tt class="xref py py-class docutils literal"><span class="pre">request</span></tt></a> object. If you have some experience with Python +you might be wondering how that object can be global and how Flask +manages to still be threadsafe. The answer are context locals:</p> +<div class="section" id="context-locals"> +<span id="id5"></span><h3>Context Locals<a class="headerlink" href="#context-locals" title="Permalink to this headline">¶</a></h3> +<div class="admonition-insider-information admonition "> +<p class="first admonition-title">Insider Information</p> +<p class="last">If you want to understand how that works and how you can implement +tests with context locals, read this section, otherwise just skip it.</p> +</div> +<p>Certain objects in Flask are global objects, but not of the usual kind. +These objects are actually proxies to objects that are local to a specific +context. What a mouthful. But that is actually quite easy to understand.</p> +<p>Imagine the context being the handling thread. A request comes in and the +webserver decides to spawn a new thread (or something else, the +underlying object is capable of dealing with other concurrency systems +than threads as well). When Flask starts its internal request handling it +figures out that the current thread is the active context and binds the +current application and the WSGI environments to that context (thread). +It does that in an intelligent way that one application can invoke another +application without breaking.</p> +<p>So what does this mean to you? Basically you can completely ignore that +this is the case unless you are doing something like unittesting. You +will notice that code that depends on a request object will suddenly break +because there is no request object. The solution is creating a request +object yourself and binding it to the context. The easiest solution for +unittesting is by using the <a class="reference internal" href="api.html#flask.Flask.test_request_context" title="flask.Flask.test_request_context"><tt class="xref py py-meth docutils literal"><span class="pre">test_request_context()</span></tt></a> +context manager. In combination with the <cite>with</cite> statement it will bind a +test request so that you can interact with it. Here is an example:</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">request</span> + +<span class="k">with</span> <span class="n">app</span><span class="o">.</span><span class="n">test_request_context</span><span class="p">(</span><span class="s">'/hello'</span><span class="p">,</span> <span class="n">method</span><span class="o">=</span><span class="s">'POST'</span><span class="p">):</span> + <span class="c"># now you can do something with the request until the</span> + <span class="c"># end of the with block, such as basic assertions:</span> + <span class="k">assert</span> <span class="n">request</span><span class="o">.</span><span class="n">path</span> <span class="o">==</span> <span class="s">'/hello'</span> + <span class="k">assert</span> <span class="n">request</span><span class="o">.</span><span class="n">method</span> <span class="o">==</span> <span class="s">'POST'</span> +</pre></div> +</div> +<p>The other possibility is passing a whole WSGI environment to the +<a class="reference internal" href="api.html#flask.Flask.request_context" title="flask.Flask.request_context"><tt class="xref py py-meth docutils literal"><span class="pre">request_context()</span></tt></a> method:</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">request</span> + +<span class="k">with</span> <span class="n">app</span><span class="o">.</span><span class="n">request_context</span><span class="p">(</span><span class="n">environ</span><span class="p">):</span> + <span class="k">assert</span> <span class="n">request</span><span class="o">.</span><span class="n">method</span> <span class="o">==</span> <span class="s">'POST'</span> +</pre></div> +</div> +</div> +<div class="section" id="the-request-object"> +<h3>The Request Object<a class="headerlink" href="#the-request-object" title="Permalink to this headline">¶</a></h3> +<p>The request object is documented in the API section and we will not cover +it here in detail (see <a class="reference internal" href="api.html#flask.request" title="flask.request"><tt class="xref py py-class docutils literal"><span class="pre">request</span></tt></a>). Here is a broad overview of +some of the most common operations. First of all you have to import it from +the <cite>flask</cite> module:</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">request</span> +</pre></div> +</div> +<p>The current request method is available by using the +<tt class="xref py py-attr docutils literal"><span class="pre">method</span></tt> attribute. To access form data (data +transmitted in a <cite>POST</cite> or <cite>PUT</cite> request) you can use the +<tt class="xref py py-attr docutils literal"><span class="pre">form</span></tt> attribute. Here is a full example of the two +attributes mentioned above:</p> +<div class="highlight-python"><div class="highlight"><pre><span class="nd">@app.route</span><span class="p">(</span><span class="s">'/login'</span><span class="p">,</span> <span class="n">methods</span><span class="o">=</span><span class="p">[</span><span class="s">'POST'</span><span class="p">,</span> <span class="s">'GET'</span><span class="p">])</span> +<span class="k">def</span> <span class="nf">login</span><span class="p">():</span> + <span class="n">error</span> <span class="o">=</span> <span class="bp">None</span> + <span class="k">if</span> <span class="n">request</span><span class="o">.</span><span class="n">method</span> <span class="o">==</span> <span class="s">'POST'</span><span class="p">:</span> + <span class="k">if</span> <span class="n">valid_login</span><span class="p">(</span><span class="n">request</span><span class="o">.</span><span class="n">form</span><span class="p">[</span><span class="s">'username'</span><span class="p">],</span> + <span class="n">request</span><span class="o">.</span><span class="n">form</span><span class="p">[</span><span class="s">'password'</span><span class="p">]):</span> + <span class="k">return</span> <span class="n">log_the_user_in</span><span class="p">(</span><span class="n">request</span><span class="o">.</span><span class="n">form</span><span class="p">[</span><span class="s">'username'</span><span class="p">])</span> + <span class="k">else</span><span class="p">:</span> + <span class="n">error</span> <span class="o">=</span> <span class="s">'Invalid username/password'</span> + <span class="c"># this is executed if the request method was GET or the</span> + <span class="c"># credentials were invalid</span> +</pre></div> +</div> +<p>What happens if the key does not exist in the <cite>form</cite> attribute? In that +case a special <a class="reference external" href="http://docs.python.org/dev/library/exceptions.html#KeyError" title="(in Python v3.3)"><tt class="xref py py-exc docutils literal"><span class="pre">KeyError</span></tt></a> is raised. You can catch it like a +standard <a class="reference external" href="http://docs.python.org/dev/library/exceptions.html#KeyError" title="(in Python v3.3)"><tt class="xref py py-exc docutils literal"><span class="pre">KeyError</span></tt></a> but if you don’t do that, a HTTP 400 Bad Request +error page is shown instead. So for many situations you don’t have to +deal with that problem.</p> +<p>To access parameters submitted in the URL (<tt class="docutils literal"><span class="pre">?key=value</span></tt>) you can use the +<tt class="xref py py-attr docutils literal"><span class="pre">args</span></tt> attribute:</p> +<div class="highlight-python"><div class="highlight"><pre><span class="n">searchword</span> <span class="o">=</span> <span class="n">request</span><span class="o">.</span><span class="n">args</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s">'q'</span><span class="p">,</span> <span class="s">''</span><span class="p">)</span> +</pre></div> +</div> +<p>We recommend accessing URL parameters with <cite>get</cite> or by catching the +<cite>KeyError</cite> because users might change the URL and presenting them a 400 +bad request page in that case is not user friendly.</p> +<p>For a full list of methods and attributes of the request object, head over +to the <a class="reference internal" href="api.html#flask.request" title="flask.request"><tt class="xref py py-class docutils literal"><span class="pre">request</span></tt></a> documentation.</p> +</div> +<div class="section" id="file-uploads"> +<h3>File Uploads<a class="headerlink" href="#file-uploads" title="Permalink to this headline">¶</a></h3> +<p>You can handle uploaded files with Flask easily. Just make sure not to +forget to set the <tt class="docutils literal"><span class="pre">enctype="multipart/form-data"</span></tt> attribute on your HTML +form, otherwise the browser will not transmit your files at all.</p> +<p>Uploaded files are stored in memory or at a temporary location on the +filesystem. You can access those files by looking at the +<tt class="xref py py-attr docutils literal"><span class="pre">files</span></tt> attribute on the request object. Each +uploaded file is stored in that dictionary. It behaves just like a +standard Python <tt class="xref py py-class docutils literal"><span class="pre">file</span></tt> object, but it also has a +<a class="reference external" href="http://werkzeug.pocoo.org/docs/datastructures/#werkzeug.datastructures.FileStorage.save" title="(in Werkzeug v0.7)"><tt class="xref py py-meth docutils literal"><span class="pre">save()</span></tt></a> method that allows you to store that +file on the filesystem of the server. Here is a simple example showing how +that works:</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">request</span> + +<span class="nd">@app.route</span><span class="p">(</span><span class="s">'/upload'</span><span class="p">,</span> <span class="n">methods</span><span class="o">=</span><span class="p">[</span><span class="s">'GET'</span><span class="p">,</span> <span class="s">'POST'</span><span class="p">])</span> +<span class="k">def</span> <span class="nf">upload_file</span><span class="p">():</span> + <span class="k">if</span> <span class="n">request</span><span class="o">.</span><span class="n">method</span> <span class="o">==</span> <span class="s">'POST'</span><span class="p">:</span> + <span class="n">f</span> <span class="o">=</span> <span class="n">request</span><span class="o">.</span><span class="n">files</span><span class="p">[</span><span class="s">'the_file'</span><span class="p">]</span> + <span class="n">f</span><span class="o">.</span><span class="n">save</span><span class="p">(</span><span class="s">'/var/www/uploads/uploaded_file.txt'</span><span class="p">)</span> + <span class="o">...</span> +</pre></div> +</div> +<p>If you want to know how the file was named on the client before it was +uploaded to your application, you can access the +<a class="reference external" href="http://werkzeug.pocoo.org/docs/datastructures/#werkzeug.datastructures.FileStorage.filename" title="(in Werkzeug v0.7)"><tt class="xref py py-attr docutils literal"><span class="pre">filename</span></tt></a> attribute. However please keep in +mind that this value can be forged so never ever trust that value. If you +want to use the filename of the client to store the file on the server, +pass it through the <a class="reference external" href="http://werkzeug.pocoo.org/docs/utils/#werkzeug.utils.secure_filename" title="(in Werkzeug v0.7)"><tt class="xref py py-func docutils literal"><span class="pre">secure_filename()</span></tt></a> function that +Werkzeug provides for you:</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">request</span> +<span class="kn">from</span> <span class="nn">werkzeug</span> <span class="kn">import</span> <span class="n">secure_filename</span> + +<span class="nd">@app.route</span><span class="p">(</span><span class="s">'/upload'</span><span class="p">,</span> <span class="n">methods</span><span class="o">=</span><span class="p">[</span><span class="s">'GET'</span><span class="p">,</span> <span class="s">'POST'</span><span class="p">])</span> +<span class="k">def</span> <span class="nf">upload_file</span><span class="p">():</span> + <span class="k">if</span> <span class="n">request</span><span class="o">.</span><span class="n">method</span> <span class="o">==</span> <span class="s">'POST'</span><span class="p">:</span> + <span class="n">f</span> <span class="o">=</span> <span class="n">request</span><span class="o">.</span><span class="n">files</span><span class="p">[</span><span class="s">'the_file'</span><span class="p">]</span> + <span class="n">f</span><span class="o">.</span><span class="n">save</span><span class="p">(</span><span class="s">'/var/www/uploads/'</span> <span class="o">+</span> <span class="n">secure_filename</span><span class="p">(</span><span class="n">f</span><span class="o">.</span><span class="n">filename</span><span class="p">))</span> + <span class="o">...</span> +</pre></div> +</div> +<p>For some better examples, checkout the <a class="reference internal" href="patterns/fileuploads.html#uploading-files"><em>Uploading Files</em></a> pattern.</p> +</div> +<div class="section" id="cookies"> +<h3>Cookies<a class="headerlink" href="#cookies" title="Permalink to this headline">¶</a></h3> +<p>To access cookies you can use the <a class="reference internal" href="api.html#flask.Request.cookies" title="flask.Request.cookies"><tt class="xref py py-attr docutils literal"><span class="pre">cookies</span></tt></a> +attribute. To set cookies you can use the +<a class="reference internal" href="api.html#flask.Response.set_cookie" title="flask.Response.set_cookie"><tt class="xref py py-attr docutils literal"><span class="pre">set_cookie</span></tt></a> method of response objects. The +<a class="reference internal" href="api.html#flask.Request.cookies" title="flask.Request.cookies"><tt class="xref py py-attr docutils literal"><span class="pre">cookies</span></tt></a> attribute of request objects is a +dictionary with all the cookies the client transmits. If you want to use +sessions, do not use the cookies directly but instead use the +<a class="reference internal" href="#sessions"><em>Sessions</em></a> in Flask that add some security on top of cookies for you.</p> +<p>Reading cookies:</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">request</span> + +<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">index</span><span class="p">():</span> + <span class="n">username</span> <span class="o">=</span> <span class="n">request</span><span class="o">.</span><span class="n">cookies</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s">'username'</span><span class="p">)</span> + <span class="c"># use cookies.get(key) instead of cookies[key] to not get a</span> + <span class="c"># KeyError if the cookie is missing.</span> +</pre></div> +</div> +<p>Storing cookies:</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">make_response</span> + +<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">index</span><span class="p">():</span> + <span class="n">resp</span> <span class="o">=</span> <span class="n">make_response</span><span class="p">(</span><span class="n">render_template</span><span class="p">(</span><span class="o">...</span><span class="p">))</span> + <span class="n">resp</span><span class="o">.</span><span class="n">set_cookie</span><span class="p">(</span><span class="s">'username'</span><span class="p">,</span> <span class="s">'the username'</span><span class="p">)</span> + <span class="k">return</span> <span class="n">resp</span> +</pre></div> +</div> +<p>Note that cookies are set on response objects. Since you normally you +just return strings from the view functions Flask will convert them into +response objects for you. If you explicitly want to do that you can use +the <a class="reference internal" href="api.html#flask.make_response" title="flask.make_response"><tt class="xref py py-meth docutils literal"><span class="pre">make_response()</span></tt></a> function and then modify it.</p> +<p>Sometimes you might want to set a cookie at a point where the response +object does not exist yet. This is possible by utilizing the +<a class="reference internal" href="patterns/deferredcallbacks.html#deferred-callbacks"><em>Deferred Request Callbacks</em></a> pattern.</p> +<p>For this also see <a class="reference internal" href="#about-responses"><em>About Responses</em></a>.</p> +</div> +</div> +<div class="section" id="redirects-and-errors"> +<h2>Redirects and Errors<a class="headerlink" href="#redirects-and-errors" title="Permalink to this headline">¶</a></h2> +<p>To redirect a user to somewhere else you can use the +<a class="reference internal" href="api.html#flask.redirect" title="flask.redirect"><tt class="xref py py-func docutils literal"><span class="pre">redirect()</span></tt></a> function. To abort a request early with an error +code use the <a class="reference internal" href="api.html#flask.abort" title="flask.abort"><tt class="xref py py-func docutils literal"><span class="pre">abort()</span></tt></a> function. Here an example how this works:</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">abort</span><span class="p">,</span> <span class="n">redirect</span><span class="p">,</span> <span class="n">url_for</span> + +<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">index</span><span class="p">():</span> + <span class="k">return</span> <span class="n">redirect</span><span class="p">(</span><span class="n">url_for</span><span class="p">(</span><span class="s">'login'</span><span class="p">))</span> + +<span class="nd">@app.route</span><span class="p">(</span><span class="s">'/login'</span><span class="p">)</span> +<span class="k">def</span> <span class="nf">login</span><span class="p">():</span> + <span class="n">abort</span><span class="p">(</span><span class="mi">401</span><span class="p">)</span> + <span class="n">this_is_never_executed</span><span class="p">()</span> +</pre></div> +</div> +<p>This is a rather pointless example because a user will be redirected from +the index to a page they cannot access (401 means access denied) but it +shows how that works.</p> +<p>By default a black and white error page is shown for each error code. If +you want to customize the error page, you can use the +<a class="reference internal" href="api.html#flask.Flask.errorhandler" title="flask.Flask.errorhandler"><tt class="xref py py-meth docutils literal"><span class="pre">errorhandler()</span></tt></a> decorator:</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">render_template</span> + +<span class="nd">@app.errorhandler</span><span class="p">(</span><span class="mi">404</span><span class="p">)</span> +<span class="k">def</span> <span class="nf">page_not_found</span><span class="p">(</span><span class="n">error</span><span class="p">):</span> + <span class="k">return</span> <span class="n">render_template</span><span class="p">(</span><span class="s">'page_not_found.html'</span><span class="p">),</span> <span class="mi">404</span> +</pre></div> +</div> +<p>Note the <tt class="docutils literal"><span class="pre">404</span></tt> after the <a class="reference internal" href="api.html#flask.render_template" title="flask.render_template"><tt class="xref py py-func docutils literal"><span class="pre">render_template()</span></tt></a> call. This +tells Flask that the status code of that page should be 404 which means +not found. By default 200 is assumed which translates to: all went well.</p> +</div> +<div class="section" id="about-responses"> +<span id="id6"></span><h2>About Responses<a class="headerlink" href="#about-responses" title="Permalink to this headline">¶</a></h2> +<p>The return value from a view function is automatically converted into a +response object for you. If the return value is a string it’s converted +into a response object with the string as response body, an <tt class="docutils literal"><span class="pre">200</span> <span class="pre">OK</span></tt> +error code and a <tt class="docutils literal"><span class="pre">text/html</span></tt> mimetype. The logic that Flask applies to +converting return values into response objects is as follows:</p> +<ol class="arabic simple"> +<li>If a response object of the correct type is returned it’s directly +returned from the view.</li> +<li>If it’s a string, a response object is created with that data and the +default parameters.</li> +<li>If a tuple is returned the response object is created by passing the +tuple as arguments to the response object’s constructor.</li> +<li>If neither of that works, Flask will assume the return value is a +valid WSGI application and converts that into a response object.</li> +</ol> +<p>If you want to get hold of the resulting response object inside the view +you can use the <a class="reference internal" href="api.html#flask.make_response" title="flask.make_response"><tt class="xref py py-func docutils literal"><span class="pre">make_response()</span></tt></a> function.</p> +<p>Imagine you have a view like this:</p> +<div class="highlight-python"><div class="highlight"><pre><span class="nd">@app.errorhandler</span><span class="p">(</span><span class="mi">404</span><span class="p">)</span> +<span class="k">def</span> <span class="nf">not_found</span><span class="p">(</span><span class="n">error</span><span class="p">):</span> + <span class="k">return</span> <span class="n">render_template</span><span class="p">(</span><span class="s">'error.html'</span><span class="p">),</span> <span class="mi">404</span> +</pre></div> +</div> +<p>You just need to wrap the return expression with +<a class="reference internal" href="api.html#flask.make_response" title="flask.make_response"><tt class="xref py py-func docutils literal"><span class="pre">make_response()</span></tt></a> and get the result object to modify it, then +return it:</p> +<div class="highlight-python"><div class="highlight"><pre><span class="nd">@app.errorhandler</span><span class="p">(</span><span class="mi">404</span><span class="p">)</span> +<span class="k">def</span> <span class="nf">not_found</span><span class="p">(</span><span class="n">error</span><span class="p">):</span> + <span class="n">resp</span> <span class="o">=</span> <span class="n">make_response</span><span class="p">(</span><span class="n">render_template</span><span class="p">(</span><span class="s">'error.html'</span><span class="p">),</span> <span class="mi">404</span><span class="p">)</span> + <span class="n">resp</span><span class="o">.</span><span class="n">headers</span><span class="p">[</span><span class="s">'X-Something'</span><span class="p">]</span> <span class="o">=</span> <span class="s">'A value'</span> + <span class="k">return</span> <span class="n">resp</span> +</pre></div> +</div> +</div> +<div class="section" id="sessions"> +<span id="id7"></span><h2>Sessions<a class="headerlink" href="#sessions" title="Permalink to this headline">¶</a></h2> +<p>Besides the request object there is also a second object called +<a class="reference internal" href="api.html#flask.session" title="flask.session"><tt class="xref py py-class docutils literal"><span class="pre">session</span></tt></a> that allows you to store information specific to a +user from one request to the next. This is implemented on top of cookies +for you and signs the cookies cryptographically. What this means is that +the user could look at the contents of your cookie but not modify it, +unless they know the secret key used for signing.</p> +<p>In order to use sessions you have to set a secret key. Here is how +sessions work:</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="p">,</span> <span class="n">session</span><span class="p">,</span> <span class="n">redirect</span><span class="p">,</span> <span class="n">url_for</span><span class="p">,</span> <span class="n">escape</span><span class="p">,</span> <span class="n">request</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="nd">@app.route</span><span class="p">(</span><span class="s">'/'</span><span class="p">)</span> +<span class="k">def</span> <span class="nf">index</span><span class="p">():</span> + <span class="k">if</span> <span class="s">'username'</span> <span class="ow">in</span> <span class="n">session</span><span class="p">:</span> + <span class="k">return</span> <span class="s">'Logged in as </span><span class="si">%s</span><span class="s">'</span> <span class="o">%</span> <span class="n">escape</span><span class="p">(</span><span class="n">session</span><span class="p">[</span><span class="s">'username'</span><span class="p">])</span> + <span class="k">return</span> <span class="s">'You are not logged in'</span> + +<span class="nd">@app.route</span><span class="p">(</span><span class="s">'/login'</span><span class="p">,</span> <span class="n">methods</span><span class="o">=</span><span class="p">[</span><span class="s">'GET'</span><span class="p">,</span> <span class="s">'POST'</span><span class="p">])</span> +<span class="k">def</span> <span class="nf">login</span><span class="p">():</span> + <span class="k">if</span> <span class="n">request</span><span class="o">.</span><span class="n">method</span> <span class="o">==</span> <span class="s">'POST'</span><span class="p">:</span> + <span class="n">session</span><span class="p">[</span><span class="s">'username'</span><span class="p">]</span> <span class="o">=</span> <span class="n">request</span><span class="o">.</span><span class="n">form</span><span class="p">[</span><span class="s">'username'</span><span class="p">]</span> + <span class="k">return</span> <span class="n">redirect</span><span class="p">(</span><span class="n">url_for</span><span class="p">(</span><span class="s">'index'</span><span class="p">))</span> + <span class="k">return</span> <span class="s">'''</span> +<span class="s"> <form action="" method="post"></span> +<span class="s"> <p><input type=text name=username></span> +<span class="s"> <p><input type=submit value=Login></span> +<span class="s"> </form></span> +<span class="s"> '''</span> + +<span class="nd">@app.route</span><span class="p">(</span><span class="s">'/logout'</span><span class="p">)</span> +<span class="k">def</span> <span class="nf">logout</span><span class="p">():</span> + <span class="c"># remove the username from the session if its there</span> + <span class="n">session</span><span class="o">.</span><span class="n">pop</span><span class="p">(</span><span class="s">'username'</span><span class="p">,</span> <span class="bp">None</span><span class="p">)</span> + <span class="k">return</span> <span class="n">redirect</span><span class="p">(</span><span class="n">url_for</span><span class="p">(</span><span class="s">'index'</span><span class="p">))</span> + +<span class="c"># set the secret key. keep this really secret:</span> +<span class="n">app</span><span class="o">.</span><span class="n">secret_key</span> <span class="o">=</span> <span class="s">'A0Zr98j/3yX R~XHH!jmN]LWX/,?RT'</span> +</pre></div> +</div> +<p>The here mentioned <a class="reference internal" href="api.html#flask.escape" title="flask.escape"><tt class="xref py py-func docutils literal"><span class="pre">escape()</span></tt></a> does escaping for you if you are +not using the template engine (like in this example).</p> +<div class="admonition-how-to-generate-good-secret-keys admonition "> +<p class="first admonition-title">How to generate good secret keys</p> +<p>The problem with random is that it’s hard to judge what random is. And +a secret key should be as random as possible. Your operating system +has ways to generate pretty random stuff based on a cryptographic +random generator which can be used to get such a key:</p> +<div class="highlight-python"><div class="highlight"><pre><span class="gp">>>> </span><span class="kn">import</span> <span class="nn">os</span> +<span class="gp">>>> </span><span class="n">os</span><span class="o">.</span><span class="n">urandom</span><span class="p">(</span><span class="mi">24</span><span class="p">)</span> +<span class="go">'\xfd{H\xe5<\x95\xf9\xe3\x96.5\xd1\x01O<!\xd5\xa2\xa0\x9fR"\xa1\xa8'</span> +</pre></div> +</div> +<p class="last">Just take that thing and copy/paste it into your code and you’re done.</p> +</div> +</div> +<div class="section" id="message-flashing"> +<h2>Message Flashing<a class="headerlink" href="#message-flashing" title="Permalink to this headline">¶</a></h2> +<p>Good applications and user interfaces are all about feedback. If the user +does not get enough feedback they will probably end up hating the +application. Flask provides a really simple way to give feedback to a +user with the flashing system. The flashing system basically makes it +possible to record a message at the end of a request and access it next +request and only next request. This is usually combined with a layout +template that does this.</p> +<p>To flash a message use the <a class="reference internal" href="api.html#flask.flash" title="flask.flash"><tt class="xref py py-func docutils literal"><span class="pre">flash()</span></tt></a> method, to get hold of the +messages you can use <a class="reference internal" href="api.html#flask.get_flashed_messages" title="flask.get_flashed_messages"><tt class="xref py py-func docutils literal"><span class="pre">get_flashed_messages()</span></tt></a> which is also +available in the templates. Check out the <a class="reference internal" href="patterns/flashing.html#message-flashing-pattern"><em>Message Flashing</em></a> +for a full example.</p> +</div> +<div class="section" id="logging"> +<h2>Logging<a class="headerlink" href="#logging" title="Permalink to this headline">¶</a></h2> +<p class="versionadded"> +<span class="versionmodified">New in version 0.3.</span></p> +<p>Sometimes you might be in a situation where you deal with data that +should be correct, but actually is not. For example you may have some client +side code that sends an HTTP request to the server but it’s obviously +malformed. This might be caused by a user tempering with the data, or the +client code failing. Most of the time, it’s okay to reply with <tt class="docutils literal"><span class="pre">400</span> <span class="pre">Bad</span> +<span class="pre">Request</span></tt> in that situation, but sometimes that won’t do and the code has +to continue working.</p> +<p>You may still want to log that something fishy happened. This is where +loggers come in handy. As of Flask 0.3 a logger is preconfigured for you +to use.</p> +<p>Here are some example log calls:</p> +<div class="highlight-python"><div class="highlight"><pre><span class="n">app</span><span class="o">.</span><span class="n">logger</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s">'A value for debugging'</span><span class="p">)</span> +<span class="n">app</span><span class="o">.</span><span class="n">logger</span><span class="o">.</span><span class="n">warning</span><span class="p">(</span><span class="s">'A warning occurred (</span><span class="si">%d</span><span class="s"> apples)'</span><span class="p">,</span> <span class="mi">42</span><span class="p">)</span> +<span class="n">app</span><span class="o">.</span><span class="n">logger</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="s">'An error occurred'</span><span class="p">)</span> +</pre></div> +</div> +<p>The attached <a class="reference internal" href="api.html#flask.Flask.logger" title="flask.Flask.logger"><tt class="xref py py-attr docutils literal"><span class="pre">logger</span></tt></a> is a standard logging +<a class="reference external" href="http://docs.python.org/dev/library/logging.html#logging.Logger" title="(in Python v3.3)"><tt class="xref py py-class docutils literal"><span class="pre">Logger</span></tt></a>, so head over to the official <a class="reference external" href="http://docs.python.org/library/logging.html">logging +documentation</a> for more +information.</p> +</div> +<div class="section" id="hooking-in-wsgi-middlewares"> +<h2>Hooking in WSGI Middlewares<a class="headerlink" href="#hooking-in-wsgi-middlewares" title="Permalink to this headline">¶</a></h2> +<p>If you want to add a WSGI middleware to your application you can wrap the +internal WSGI application. For example if you want to use one of the +middlewares from the Werkzeug package to work around bugs in lighttpd, you +can do it like this:</p> +<div class="highlight-python"><div class="highlight"><pre><span class="kn">from</span> <span class="nn">werkzeug.contrib.fixers</span> <span class="kn">import</span> <span class="n">LighttpdCGIRootFix</span> +<span class="n">app</span><span class="o">.</span><span class="n">wsgi_app</span> <span class="o">=</span> <span class="n">LighttpdCGIRootFix</span><span class="p">(</span><span class="n">app</span><span class="o">.</span><span class="n">wsgi_app</span><span class="p">)</span> +</pre></div> +</div> +</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="#">Quickstart</a><ul> +<li><a class="reference internal" href="#a-minimal-application">A Minimal Application</a></li> +<li><a class="reference internal" href="#debug-mode">Debug Mode</a></li> +<li><a class="reference internal" href="#routing">Routing</a><ul> +<li><a class="reference internal" href="#variable-rules">Variable Rules</a></li> +<li><a class="reference internal" href="#url-building">URL Building</a></li> +<li><a class="reference internal" href="#http-methods">HTTP Methods</a></li> +</ul> +</li> +<li><a class="reference internal" href="#static-files">Static Files</a></li> +<li><a class="reference internal" href="#rendering-templates">Rendering Templates</a></li> +<li><a class="reference internal" href="#accessing-request-data">Accessing Request Data</a><ul> +<li><a class="reference internal" href="#context-locals">Context Locals</a></li> +<li><a class="reference internal" href="#the-request-object">The Request Object</a></li> +<li><a class="reference internal" href="#file-uploads">File Uploads</a></li> +<li><a class="reference internal" href="#cookies">Cookies</a></li> +</ul> +</li> +<li><a class="reference internal" href="#redirects-and-errors">Redirects and Errors</a></li> +<li><a class="reference internal" href="#about-responses">About Responses</a></li> +<li><a class="reference internal" href="#sessions">Sessions</a></li> +<li><a class="reference internal" href="#message-flashing">Message Flashing</a></li> +<li><a class="reference internal" href="#logging">Logging</a></li> +<li><a class="reference internal" href="#hooking-in-wsgi-middlewares">Hooking in WSGI Middlewares</a></li> +</ul> +</li> +</ul> +<h3>Related Topics</h3> +<ul> + <li><a href="index.html">Documentation overview</a><ul> + <li>Previous: <a href="installation.html" title="previous chapter">Installation</a></li> + <li>Next: <a href="tutorial/index.html" title="next chapter">Tutorial</a></li> + </ul></li> +</ul> + <h3>This Page</h3> + <ul class="this-page-menu"> + <li><a href="_sources/quickstart.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 |