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, 0 insertions, 875 deletions
diff --git a/app/static/doc/flask-docs/quickstart.html b/app/static/doc/flask-docs/quickstart.html deleted file mode 100644 index 4a26798..0000000 --- a/app/static/doc/flask-docs/quickstart.html +++ /dev/null @@ -1,875 +0,0 @@ - -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" - "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> - - -<html xmlns="http://www.w3.org/1999/xhtml"> - <head> - <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> - - <title>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 |