Files
responder/quickstart.html
T
2023-11-21 08:14:10 +00:00

623 lines
32 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="en" data-content_root="./">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Quick Start! &#8212; responder 2.0.7 documentation</title>
<link rel="stylesheet" type="text/css" href="_static/pygments.css?v=4f649999" />
<link rel="stylesheet" type="text/css" href="_static/alabaster.css?v=039e1c02" />
<script src="_static/documentation_options.js?v=9a3ee07e"></script>
<script src="_static/doctools.js?v=888ff710"></script>
<script src="_static/sphinx_highlight.js?v=dc90522c"></script>
<link rel="index" title="Index" href="genindex.html" />
<link rel="search" title="Search" href="search.html" />
<link rel="next" title="Feature Tour" href="tour.html" />
<link rel="prev" title="A familiar HTTP Service Framework" href="index.html" />
<link rel="stylesheet" href="_static/custom.css" type="text/css" />
<meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" />
</head><body>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<section id="quick-start">
<h1>Quick Start!<a class="headerlink" href="#quick-start" title="Link to this heading"></a></h1>
<p>This section of the documentation exists to provide an introduction to the Responder interface,
as well as educate the user on basic functionality.</p>
<section id="declare-a-web-service">
<h2>Declare a Web Service<a class="headerlink" href="#declare-a-web-service" title="Link to this heading"></a></h2>
<p>The first thing you need to do is declare a web service:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">responder</span>
<span class="n">api</span> <span class="o">=</span> <span class="n">responder</span><span class="o">.</span><span class="n">API</span><span class="p">()</span>
</pre></div>
</div>
</section>
<section id="hello-world">
<h2>Hello World!<a class="headerlink" href="#hello-world" title="Link to this heading"></a></h2>
<p>Then, you can add a view / route to it.</p>
<p>Here, well make the root URL say “hello world!”:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="nd">@api</span><span class="o">.</span><span class="n">route</span><span class="p">(</span><span class="s2">&quot;/&quot;</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">hello_world</span><span class="p">(</span><span class="n">req</span><span class="p">,</span> <span class="n">resp</span><span class="p">):</span>
<span class="n">resp</span><span class="o">.</span><span class="n">text</span> <span class="o">=</span> <span class="s2">&quot;hello, world!&quot;</span>
</pre></div>
</div>
</section>
<section id="run-the-server">
<h2>Run the Server<a class="headerlink" href="#run-the-server" title="Link to this heading"></a></h2>
<p>Next, we can run our web service easily, with <code class="docutils literal notranslate"><span class="pre">api.run()</span></code>:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">api</span><span class="o">.</span><span class="n">run</span><span class="p">()</span>
</pre></div>
</div>
<p>This will spin up a production web server on port <code class="docutils literal notranslate"><span class="pre">5042</span></code>, ready for incoming HTTP requests.</p>
<p>Note: you can pass <code class="docutils literal notranslate"><span class="pre">port=5000</span></code> if you want to customize the port. The <code class="docutils literal notranslate"><span class="pre">PORT</span></code> environment variable for established web service providers (e.g. Heroku) will automatically be honored and will set the listening address to <code class="docutils literal notranslate"><span class="pre">0.0.0.0</span></code> automatically (also configurable through the <code class="docutils literal notranslate"><span class="pre">address</span></code> keyword argument).</p>
</section>
<section id="accept-route-arguments">
<h2>Accept Route Arguments<a class="headerlink" href="#accept-route-arguments" title="Link to this heading"></a></h2>
<p>If you want dynamic URLs, you can use Pythons familiar <em>f-string syntax</em> to declare variables in your routes:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="nd">@api</span><span class="o">.</span><span class="n">route</span><span class="p">(</span><span class="s2">&quot;/hello/</span><span class="si">{who}</span><span class="s2">&quot;</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">hello_to</span><span class="p">(</span><span class="n">req</span><span class="p">,</span> <span class="n">resp</span><span class="p">,</span> <span class="o">*</span><span class="p">,</span> <span class="n">who</span><span class="p">):</span>
<span class="n">resp</span><span class="o">.</span><span class="n">text</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">&quot;hello, </span><span class="si">{</span><span class="n">who</span><span class="si">}</span><span class="s2">!&quot;</span>
</pre></div>
</div>
<p>A <code class="docutils literal notranslate"><span class="pre">GET</span></code> request to <code class="docutils literal notranslate"><span class="pre">/hello/brettcannon</span></code> will result in a response of <code class="docutils literal notranslate"><span class="pre">hello,</span> <span class="pre">brettcannon!</span></code>.</p>
<p>Type convertors are also available:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="nd">@api</span><span class="o">.</span><span class="n">route</span><span class="p">(</span><span class="s2">&quot;/add/{a:int}/{b:int}&quot;</span><span class="p">)</span>
<span class="k">async</span> <span class="k">def</span> <span class="nf">add</span><span class="p">(</span><span class="n">req</span><span class="p">,</span> <span class="n">resp</span><span class="p">,</span> <span class="o">*</span><span class="p">,</span> <span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">):</span>
<span class="n">resp</span><span class="o">.</span><span class="n">text</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="n">a</span><span class="si">}</span><span class="s2"> + </span><span class="si">{</span><span class="n">b</span><span class="si">}</span><span class="s2"> = </span><span class="si">{</span><span class="n">a</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">b</span><span class="si">}</span><span class="s2">&quot;</span>
</pre></div>
</div>
<p>Supported types: <code class="docutils literal notranslate"><span class="pre">str</span></code>, <code class="docutils literal notranslate"><span class="pre">int</span></code> and <code class="docutils literal notranslate"><span class="pre">float</span></code>.</p>
</section>
<section id="returning-json-yaml">
<h2>Returning JSON / YAML<a class="headerlink" href="#returning-json-yaml" title="Link to this heading"></a></h2>
<p>If you want your API to send back JSON, simply set the <code class="docutils literal notranslate"><span class="pre">resp.media</span></code> property to a JSON-serializable Python object:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="nd">@api</span><span class="o">.</span><span class="n">route</span><span class="p">(</span><span class="s2">&quot;/hello/</span><span class="si">{who}</span><span class="s2">/json&quot;</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">hello_to</span><span class="p">(</span><span class="n">req</span><span class="p">,</span> <span class="n">resp</span><span class="p">,</span> <span class="o">*</span><span class="p">,</span> <span class="n">who</span><span class="p">):</span>
<span class="n">resp</span><span class="o">.</span><span class="n">media</span> <span class="o">=</span> <span class="p">{</span><span class="s2">&quot;hello&quot;</span><span class="p">:</span> <span class="n">who</span><span class="p">}</span>
</pre></div>
</div>
<p>A <code class="docutils literal notranslate"><span class="pre">GET</span></code> request to <code class="docutils literal notranslate"><span class="pre">/hello/guido/json</span></code> will result in a response of <code class="docutils literal notranslate"><span class="pre">{'hello':</span> <span class="pre">'guido'}</span></code>.</p>
<p>If the client requests YAML instead (with a header of <code class="docutils literal notranslate"><span class="pre">Accept:</span> <span class="pre">application/x-yaml</span></code>), YAML will be sent.</p>
</section>
<section id="rendering-a-template">
<h2>Rendering a Template<a class="headerlink" href="#rendering-a-template" title="Link to this heading"></a></h2>
<p>Responder provides a built-in light <a class="reference external" href="http://jinja.pocoo.org/docs/">jinja2</a> wrapper <code class="docutils literal notranslate"><span class="pre">templates.Templates</span></code></p>
<p>Usage:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">responder.templates</span> <span class="kn">import</span> <span class="n">Templates</span>
<span class="n">templates</span> <span class="o">=</span> <span class="n">Templates</span><span class="p">()</span>
<span class="nd">@api</span><span class="o">.</span><span class="n">route</span><span class="p">(</span><span class="s2">&quot;/hello/</span><span class="si">{name}</span><span class="s2">/html&quot;</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">hello</span><span class="p">(</span><span class="n">req</span><span class="p">,</span> <span class="n">resp</span><span class="p">,</span> <span class="n">name</span><span class="p">):</span>
<span class="n">resp</span><span class="o">.</span><span class="n">html</span> <span class="o">=</span> <span class="n">templates</span><span class="o">.</span><span class="n">render</span><span class="p">(</span><span class="s2">&quot;hello.html&quot;</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>Also a <code class="docutils literal notranslate"><span class="pre">render_async</span></code> is available:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">templates</span> <span class="o">=</span> <span class="n">Templates</span><span class="p">(</span><span class="n">enable_async</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
<span class="n">resp</span><span class="o">.</span><span class="n">html</span> <span class="o">=</span> <span class="k">await</span> <span class="n">templates</span><span class="o">.</span><span class="n">render_async</span><span class="p">(</span><span class="s2">&quot;hello.html&quot;</span><span class="p">,</span> <span class="n">who</span><span class="o">=</span><span class="n">who</span><span class="p">)</span>
</pre></div>
</div>
<p>You can also use the existing <code class="docutils literal notranslate"><span class="pre">api.template(filename,</span> <span class="pre">*args,</span> <span class="pre">**kwargs)</span></code> to render templates:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="nd">@api</span><span class="o">.</span><span class="n">route</span><span class="p">(</span><span class="s2">&quot;/hello/</span><span class="si">{who}</span><span class="s2">/html&quot;</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">hello_html</span><span class="p">(</span><span class="n">req</span><span class="p">,</span> <span class="n">resp</span><span class="p">,</span> <span class="o">*</span><span class="p">,</span> <span class="n">who</span><span class="p">):</span>
<span class="n">resp</span><span class="o">.</span><span class="n">html</span> <span class="o">=</span> <span class="n">api</span><span class="o">.</span><span class="n">template</span><span class="p">(</span><span class="s1">&#39;hello.html&#39;</span><span class="p">,</span> <span class="n">who</span><span class="o">=</span><span class="n">who</span><span class="p">)</span>
</pre></div>
</div>
</section>
<section id="setting-response-status-code">
<h2>Setting Response Status Code<a class="headerlink" href="#setting-response-status-code" title="Link to this heading"></a></h2>
<p>If you want to set the response status code, simply set <code class="docutils literal notranslate"><span class="pre">resp.status_code</span></code>:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="nd">@api</span><span class="o">.</span><span class="n">route</span><span class="p">(</span><span class="s2">&quot;/416&quot;</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">teapot</span><span class="p">(</span><span class="n">req</span><span class="p">,</span> <span class="n">resp</span><span class="p">):</span>
<span class="n">resp</span><span class="o">.</span><span class="n">status_code</span> <span class="o">=</span> <span class="n">api</span><span class="o">.</span><span class="n">status_codes</span><span class="o">.</span><span class="n">HTTP_416</span> <span class="c1"># ...or 416</span>
</pre></div>
</div>
</section>
<section id="setting-response-headers">
<h2>Setting Response Headers<a class="headerlink" href="#setting-response-headers" title="Link to this heading"></a></h2>
<p>If you want to set a response header, like <code class="docutils literal notranslate"><span class="pre">X-Pizza:</span> <span class="pre">42</span></code>, simply modify the <code class="docutils literal notranslate"><span class="pre">resp.headers</span></code> dictionary:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="nd">@api</span><span class="o">.</span><span class="n">route</span><span class="p">(</span><span class="s2">&quot;/pizza&quot;</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">pizza_pizza</span><span class="p">(</span><span class="n">req</span><span class="p">,</span> <span class="n">resp</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="s1">&#39;X-Pizza&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="s1">&#39;42&#39;</span>
</pre></div>
</div>
<p>Thats it!</p>
</section>
<section id="receiving-data-background-tasks">
<h2>Receiving Data &amp; Background Tasks<a class="headerlink" href="#receiving-data-background-tasks" title="Link to this heading"></a></h2>
<p>If youre expecting to read any request data, on the server, you need to declare your view as async and await the content.</p>
<p>Here, well process our data in the background, while responding immediately to the client:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">time</span>
<span class="nd">@api</span><span class="o">.</span><span class="n">route</span><span class="p">(</span><span class="s2">&quot;/incoming&quot;</span><span class="p">)</span>
<span class="k">async</span> <span class="k">def</span> <span class="nf">receive_incoming</span><span class="p">(</span><span class="n">req</span><span class="p">,</span> <span class="n">resp</span><span class="p">):</span>
<span class="nd">@api</span><span class="o">.</span><span class="n">background</span><span class="o">.</span><span class="n">task</span>
<span class="k">def</span> <span class="nf">process_data</span><span class="p">(</span><span class="n">data</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;Just sleeps for three seconds, as a demo.&quot;&quot;&quot;</span>
<span class="n">time</span><span class="o">.</span><span class="n">sleep</span><span class="p">(</span><span class="mi">3</span><span class="p">)</span>
<span class="c1"># Parse the incoming data as form-encoded.</span>
<span class="c1"># Note: &#39;json&#39; and &#39;yaml&#39; formats are also automatically supported.</span>
<span class="n">data</span> <span class="o">=</span> <span class="k">await</span> <span class="n">req</span><span class="o">.</span><span class="n">media</span><span class="p">()</span>
<span class="c1"># Process the data (in the background).</span>
<span class="n">process_data</span><span class="p">(</span><span class="n">data</span><span class="p">)</span>
<span class="c1"># Immediately respond that upload was successful.</span>
<span class="n">resp</span><span class="o">.</span><span class="n">media</span> <span class="o">=</span> <span class="p">{</span><span class="s1">&#39;success&#39;</span><span class="p">:</span> <span class="kc">True</span><span class="p">}</span>
</pre></div>
</div>
<p>A <code class="docutils literal notranslate"><span class="pre">POST</span></code> request to <code class="docutils literal notranslate"><span class="pre">/incoming</span></code> will result in an immediate response of <code class="docutils literal notranslate"><span class="pre">{'success':</span> <span class="pre">true}</span></code>.</p>
<p>Heres a sample code to post a file with background:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="nd">@api</span><span class="o">.</span><span class="n">route</span><span class="p">(</span><span class="s2">&quot;/&quot;</span><span class="p">)</span>
<span class="k">async</span> <span class="k">def</span> <span class="nf">upload_file</span><span class="p">(</span><span class="n">req</span><span class="p">,</span> <span class="n">resp</span><span class="p">):</span>
<span class="nd">@api</span><span class="o">.</span><span class="n">background</span><span class="o">.</span><span class="n">task</span>
<span class="k">def</span> <span class="nf">process_data</span><span class="p">(</span><span class="n">data</span><span class="p">):</span>
<span class="n">f</span> <span class="o">=</span> <span class="nb">open</span><span class="p">(</span><span class="s1">&#39;./</span><span class="si">{}</span><span class="s1">&#39;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">data</span><span class="p">[</span><span class="s1">&#39;file&#39;</span><span class="p">][</span><span class="s1">&#39;filename&#39;</span><span class="p">]),</span> <span class="s1">&#39;w&#39;</span><span class="p">)</span>
<span class="n">f</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">data</span><span class="p">[</span><span class="s1">&#39;file&#39;</span><span class="p">][</span><span class="s1">&#39;content&#39;</span><span class="p">]</span><span class="o">.</span><span class="n">decode</span><span class="p">(</span><span class="s1">&#39;utf-8&#39;</span><span class="p">))</span>
<span class="n">f</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
<span class="n">data</span> <span class="o">=</span> <span class="k">await</span> <span class="n">req</span><span class="o">.</span><span class="n">media</span><span class="p">(</span><span class="nb">format</span><span class="o">=</span><span class="s1">&#39;files&#39;</span><span class="p">)</span>
<span class="n">process_data</span><span class="p">(</span><span class="n">data</span><span class="p">)</span>
<span class="n">resp</span><span class="o">.</span><span class="n">media</span> <span class="o">=</span> <span class="p">{</span><span class="s1">&#39;success&#39;</span><span class="p">:</span> <span class="s1">&#39;ok&#39;</span><span class="p">}</span>
</pre></div>
</div>
<p>You can send a file easily with requests:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">requests</span>
<span class="n">data</span> <span class="o">=</span> <span class="p">{</span><span class="s1">&#39;file&#39;</span><span class="p">:</span> <span class="p">(</span><span class="s1">&#39;hello.txt&#39;</span><span class="p">,</span> <span class="s1">&#39;hello, world!&#39;</span><span class="p">,</span> <span class="s2">&quot;text/plain&quot;</span><span class="p">)}</span>
<span class="n">r</span> <span class="o">=</span> <span class="n">requests</span><span class="o">.</span><span class="n">post</span><span class="p">(</span><span class="s1">&#39;http://127.0.0.1:8210/file&#39;</span><span class="p">,</span> <span class="n">files</span><span class="o">=</span><span class="n">data</span><span class="p">)</span>
<span class="nb">print</span><span class="p">(</span><span class="n">r</span><span class="o">.</span><span class="n">text</span><span class="p">)</span>
</pre></div>
</div>
</section>
</section>
</div>
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper"><p class="logo">
<a href="index.html">
<img
class="logo"
src="_static/responder.png"
title="https://kennethreitz.org/tattoos"
/>
</a>
</p>
<p>
<iframe
src="https://ghbtns.com/github-btn.html?user=kennethreitz&repo=responder&type=watch&count=true&size=large"
allowtransparency="true"
frameborder="0"
scrolling="0"
width="200px"
height="35px"
></iframe>
</p>
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/docsearch.js@2/dist/cdn/docsearch.min.css"
/>
<style>
.algolia-autocomplete {
width: 100%;
height: 1.5em;
}
.algolia-autocomplete a {
border-bottom: none !important;
}
#doc_search {
width: 100%;
height: 100%;
}
</style>
<input id="doc_search" placeholder="Search the doc" autofocus />
<script
type="text/javascript"
src="https://cdn.jsdelivr.net/npm/docsearch.js@2/dist/cdn/docsearch.min.js"
onload="docsearch({
apiKey: 'ac965312db252e0496283c75c6f76f0b',
indexName: 'python-responder',
inputSelector: '#doc_search',
debug: false // Set debug to true if you want to inspect the dropdown
})"
async
></script>
<script type="text/javascript">
var _gauges = _gauges || [];
(function () {
var t = document.createElement("script");
t.type = "text/javascript";
t.async = true;
t.id = "gauges-tracker";
t.setAttribute("data-site-id", "6553701284ca0b3e73d095ed");
t.setAttribute("data-track-path", "https://track.gaug.es/track.gif");
t.src = "https://d2fuc4clr7gvcn.cloudfront.net/track.js";
var s = document.getElementsByTagName("script")[0];
s.parentNode.insertBefore(t, s);
})();
</script>
<p>
<strong>Responder</strong> is a web service framework, written for human
beings.
</p>
<h3>Stay Informed</h3>
<p>Receive updates on new releases and upcoming projects.</p>
<p>
<iframe
src="https://ghbtns.com/github-btn.html?user=kennethreitz&type=follow&count=true"
allowtransparency="true"
frameborder="0"
scrolling="0"
width="200"
height="20"
></iframe>
</p>
<p>
<a
href="https://twitter.com/kennethreitz42"
class="twitter-follow-button"
data-show-count="false"
>Follow @kennethreitz</a
>
<script>
!(function (d, s, id) {
var js,
fjs = d.getElementsByTagName(s)[0],
p = /^http:/.test(d.location) ? "http" : "https";
if (!d.getElementById(id)) {
js = d.createElement(s);
js.id = id;
js.src = p + "://platform.twitter.com/widgets.js";
fjs.parentNode.insertBefore(js, fjs);
}
})(document, "script", "twitter-wjs");
</script>
</p>
<h3>Useful Links</h3>
<ul>
<li>
<a href="http://github.com/kennethreitz/responder">Responder @ GitHub</a>
</li>
<li><a href="http://pypi.python.org/pypi/responder">Responder @ PyPI</a></li>
<li>
<a href="http://github.com/kennethreitz/responder/issues">Issue Tracker</a>
</li>
</ul>
<div>
<h3><a href="index.html">Table of Contents</a></h3>
<ul>
<li><a class="reference internal" href="#">Quick Start!</a><ul>
<li><a class="reference internal" href="#declare-a-web-service">Declare a Web Service</a></li>
<li><a class="reference internal" href="#hello-world">Hello World!</a></li>
<li><a class="reference internal" href="#run-the-server">Run the Server</a></li>
<li><a class="reference internal" href="#accept-route-arguments">Accept Route Arguments</a></li>
<li><a class="reference internal" href="#returning-json-yaml">Returning JSON / YAML</a></li>
<li><a class="reference internal" href="#rendering-a-template">Rendering a Template</a></li>
<li><a class="reference internal" href="#setting-response-status-code">Setting Response Status Code</a></li>
<li><a class="reference internal" href="#setting-response-headers">Setting Response Headers</a></li>
<li><a class="reference internal" href="#receiving-data-background-tasks">Receiving Data &amp; Background Tasks</a></li>
</ul>
</li>
</ul>
</div><div class="relations">
<h3>Related Topics</h3>
<ul>
<li><a href="index.html">Documentation overview</a><ul>
<li>Previous: <a href="index.html" title="previous chapter">A familiar HTTP Service Framework</a></li>
<li>Next: <a href="tour.html" title="next chapter">Feature Tour</a></li>
</ul></li>
</ul>
</div>
<div role="note" aria-label="source link">
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="_sources/quickstart.rst.txt"
rel="nofollow">Show Source</a></li>
</ul>
</div>
<div id="searchbox" style="display: none" role="search">
<h3 id="searchlabel">Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="search.html" method="get">
<input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/>
<input type="submit" value="Go" />
</form>
</div>
</div>
<script>document.getElementById('searchbox').style.display = "block"</script><link
rel="stylesheet"
type="text/css"
href="https://cloud.typography.com/7584432/7586812/css/fonts.css"
/>
<script type="text/javascript">
$("#searchbox").hide(0);
</script>
<!--Alabaster (krTheme++) Hacks -->
<!-- CSS Adjustments (I'm very picky.) -->
<style type="text/css">
/* Rezzy requires precise alignment. */
img.logo {
margin-left: -20px !important;
}
h1 {
font-family: "Mercury Text G1 A", "Mercury Text G1 B" !important;
font-style: normal !important;
font-weight: 600 !important;
}
.section {
font-family: "Mercury Text G1 A", "Mercury Text G1 B" !important;
font-style: normal !important;
font-weight: 400 !important;
}
pre,
.pre,
.class em,
.descname,
.method em {
font-family: "Operator Mono SSm A", "Operator Mono SSm B", monospace !important;
font-weight: 400 !important;
}
.property {
color: lightgrey !important;
}
.method .descname {
color: #220a54;
}
.method {
margin-bottom: 2em;
}
.si,
.s2,
.s1,
.method em,
.class em {
font-style: italic !important;
color: grey;
}
.method em,
.class em {
margin-left: 0.3em;
margin-right: 0.3em;
}
.method p,
.class p {
font-family: "Mercury Text G1 A", "Mercury Text G1 B";
font-style: italic !important;
font-weight: 400 !important;
font-size: 1.15em;
}
.method p:first,
.class p:first {
background: #fffcbf;
}
.class .property {
display: none;
}
#testimonials p.attribution {
margin-top: -1em;
}
/* "Quick Search" should be not be shown for now. */
div#searchbox h3 {
display: none;
}
/* Make the document a little wider, less code is cut-off. */
div.document {
width: 1008px;
}
/* Much-improved spacing around code blocks. */
div.highlight pre {
padding: 11px 14px;
}
/* Remain Responsive! */
@media screen and (max-width: 1008px) {
div.sphinxsidebar {
display: none;
}
div.document {
width: 100% !important;
}
/* Have code blocks escape the document right-margin. */
div.highlight pre {
margin-right: -30px;
}
}
</style>
<!-- Analytics tracking for Kenneth. -->
<script
async
src="https://www.googletagmanager.com/gtag/js?id=UA-127383416-1"
></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag() {
dataLayer.push(arguments);
}
gtag("js", new Date());
gtag("config", "UA-127383416-1");
</script>
<!-- There are no more hacks. -->
<!-- இڿڰۣ-ڰۣ— -->
<!-- Love, Kenneth Reitz -->
<script src="_static//konami.js"></script>
<script>
var easter_egg = new Konami(
"https://www.myfortunecookie.co.uk/fortunes/" +
(Math.floor(Math.random() * 152) + 1)
);
</script>
<style>
.injected {
display: none !important;
}
</style>
<!-- GitHub Logo -->
<a
href="https://github.com/kennethreitz/responder"
class="github-corner"
aria-label="View source on GitHub"
>
<svg
width="80"
height="80"
viewBox="0 0 250 250"
style="
fill: #151513;
color: #fff;
position: absolute;
top: 0;
border: 0;
right: 0;
"
aria-hidden="true"
>
<path d="M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z"></path>
<path
d="M128.3,109.0 C113.8,99.7 119.0,89.6 119.0,89.6 C122.0,82.7 120.5,78.6 120.5,78.6 C119.2,72.0 123.4,76.3 123.4,76.3 C127.3,80.9 125.5,87.3 125.5,87.3 C122.9,97.6 130.6,101.9 134.4,103.2"
fill="currentColor"
style="transform-origin: 130px 106px"
class="octo-arm"
></path>
<path
d="M115.0,115.0 C114.9,115.1 118.7,116.5 119.8,115.4 L133.7,101.6 C136.9,99.2 139.9,98.4 142.2,98.6 C133.8,88.0 127.5,74.4 143.8,58.0 C148.5,53.4 154.0,51.2 159.7,51.0 C160.3,49.4 163.2,43.6 171.4,40.1 C171.4,40.1 176.1,42.5 178.8,56.2 C183.1,58.6 187.2,61.8 190.9,65.4 C194.5,69.0 197.7,73.2 200.1,77.6 C213.8,80.2 216.3,84.9 216.3,84.9 C212.7,93.1 206.9,96.0 205.4,96.6 C205.1,102.4 203.0,107.8 198.3,112.5 C181.9,128.9 168.3,122.5 157.7,114.1 C157.9,116.9 156.7,120.9 152.7,124.9 L141.0,136.5 C139.8,137.7 141.6,141.9 141.8,141.8 Z"
fill="currentColor"
class="octo-body"
></path>
</svg>
</a>
<style>
.github-corner:hover .octo-arm {
animation: octocat-wave 560ms ease-in-out;
}
@keyframes octocat-wave {
0%,
100% {
transform: rotate(0);
}
20%,
60% {
transform: rotate(-25deg);
}
40%,
80% {
transform: rotate(10deg);
}
}
@media (max-width: 500px) {
.github-corner:hover .octo-arm {
animation: none;
}
.github-corner .octo-arm {
animation: octocat-wave 560ms ease-in-out;
}
}
</style>
<!-- That was not a hack. That was art.
<!-- UserVoice JavaScript SDK (only needed once on a page) -->
<script>
(function () {
var uv = document.createElement("script");
uv.type = "text/javascript";
uv.async = true;
uv.src = "//widget.uservoice.com/f4AQraEfwInlMzkexfRLg.js";
var s = document.getElementsByTagName("script")[0];
s.parentNode.insertBefore(uv, s);
})();
</script>
<!-- A tab to launch the Classic Widget -->
<script>
UserVoice = window.UserVoice || [];
UserVoice.push([
"showTab",
"classic_widget",
{
mode: "feedback",
primary_color: "#fa8c28",
link_color: "#0a8cc6",
forum_id: 913660,
tab_label: "Got feedback?",
tab_color: "#00994f",
tab_position: "bottom-left",
tab_inverted: true,
},
]);
</script>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="footer">
&copy;2018, A Kenneth Reitz project.
|
<a href="_sources/quickstart.rst.txt"
rel="nofollow">Page source</a>
</div>
</body>
</html>