<!DOCTYPE html> <!--[if IE 8]><html class="no-js lt-ie9" lang="en" > <![endif]--> <!--[if gt IE 8]><!--> <html class="no-js" lang="en" > <!--<![endif]--> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Python API Reference — nghttp2 1.38.0 documentation</title> <link rel="stylesheet" href="_static/css/theme.css" type="text/css" /> <link rel="index" title="Index" href="genindex.html"/> <link rel="search" title="Search" href="search.html"/> <link rel="top" title="nghttp2 1.38.0 documentation" href="index.html"/> <link rel="next" title="nghttp2.h" href="nghttp2.h.html"/> <link rel="prev" title="libnghttp2_asio: High level HTTP/2 C++ library" href="libnghttp2_asio.html"/> <script src="_static/js/modernizr.min.js"></script> </head> <body class="wy-body-for-nav" role="document"> <div class="wy-grid-for-nav"> <nav data-toggle="wy-nav-shift" class="wy-nav-side"> <div class="wy-side-scroll"> <div class="wy-side-nav-search"> <a href="index.html" class="icon icon-home"> nghttp2 </a> <div class="version"> 1.38.0 </div> <div role="search"> <form id="rtd-search-form" class="wy-form" action="search.html" method="get"> <input type="text" name="q" placeholder="Search docs" /> <input type="hidden" name="check_keywords" value="yes" /> <input type="hidden" name="area" value="default" /> </form> </div> </div> <div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="main navigation"> <ul class="current"> <li class="toctree-l1"><a class="reference internal" href="package_README.html">nghttp2 - HTTP/2 C Library</a></li> <li class="toctree-l1"><a class="reference internal" href="contribute.html">Contribution Guidelines</a></li> <li class="toctree-l1"><a class="reference internal" href="building-android-binary.html">Building Android binary</a></li> <li class="toctree-l1"><a class="reference internal" href="tutorial-client.html">Tutorial: HTTP/2 client</a></li> <li class="toctree-l1"><a class="reference internal" href="tutorial-server.html">Tutorial: HTTP/2 server</a></li> <li class="toctree-l1"><a class="reference internal" href="tutorial-hpack.html">Tutorial: HPACK API</a></li> <li class="toctree-l1"><a class="reference internal" href="nghttp.1.html">nghttp(1)</a></li> <li class="toctree-l1"><a class="reference internal" href="nghttpd.1.html">nghttpd(1)</a></li> <li class="toctree-l1"><a class="reference internal" href="nghttpx.1.html">nghttpx(1)</a></li> <li class="toctree-l1"><a class="reference internal" href="h2load.1.html">h2load(1)</a></li> <li class="toctree-l1"><a class="reference internal" href="nghttpx-howto.html">nghttpx - HTTP/2 proxy - HOW-TO</a></li> <li class="toctree-l1"><a class="reference internal" href="h2load-howto.html">h2load - HTTP/2 benchmarking tool - HOW-TO</a></li> <li class="toctree-l1"><a class="reference internal" href="programmers-guide.html">Programmers’ Guide</a></li> <li class="toctree-l1"><a class="reference internal" href="apiref.html">API Reference</a></li> <li class="toctree-l1"><a class="reference internal" href="libnghttp2_asio.html">libnghttp2_asio: High level HTTP/2 C++ library</a></li> <li class="toctree-l1 current"><a class="current reference internal" href="#">Python API Reference</a><ul> <li class="toctree-l2"><a class="reference internal" href="#hpack-api">HPACK API</a></li> <li class="toctree-l2"><a class="reference internal" href="#http-2-servers">HTTP/2 servers</a></li> </ul> </li> <li class="toctree-l1"><a class="reference internal" href="nghttp2.h.html">nghttp2.h</a></li> <li class="toctree-l1"><a class="reference internal" href="nghttp2ver.h.html">nghttp2ver.h</a></li> <li class="toctree-l1"><a class="reference internal" href="asio_http2_server.h.html">asio_http2_server.h</a></li> <li class="toctree-l1"><a class="reference internal" href="asio_http2_client.h.html">asio_http2_client.h</a></li> <li class="toctree-l1"><a class="reference internal" href="asio_http2.h.html">asio_http2.h</a></li> <li class="toctree-l1"><a class="reference external" href="https://github.com/nghttp2/nghttp2">Source</a></li> <li class="toctree-l1"><a class="reference external" href="https://github.com/nghttp2/nghttp2/issues">Issues</a></li> <li class="toctree-l1"><a class="reference external" href="https://nghttp2.org/">nghttp2.org</a></li> </ul> </div> </div> </nav> <section data-toggle="wy-nav-shift" class="wy-nav-content-wrap"> <nav class="wy-nav-top" role="navigation" aria-label="top navigation"> <i data-toggle="wy-nav-top" class="fa fa-bars"></i> <a href="index.html">nghttp2</a> </nav> <div class="wy-nav-content"> <div class="rst-content"> <div role="navigation" aria-label="breadcrumbs navigation"> <ul class="wy-breadcrumbs"> <li><a href="index.html">Docs</a> »</li> <li>Python API Reference</li> <li class="wy-breadcrumbs-aside"> </li> </ul> <hr/> </div> <div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article"> <div itemprop="articleBody"> <div class="section" id="module-nghttp2"> <span id="python-api-reference"></span><h1>Python API Reference<a class="headerlink" href="#module-nghttp2" title="Permalink to this headline">¶</a></h1> <p>nghttp2 offers some high level Python API to C library. The bindings currently provide HPACK compressor and decompressor classes and HTTP/2 server class.</p> <p>The extension module is called <code class="docutils literal notranslate"><span class="pre">nghttp2</span></code>.</p> <p><code class="docutils literal notranslate"><span class="pre">make</span></code> will build the bindings. The target Python version is determined by configure script. If the detected Python version is not what you expect, specify a path to Python executable in <code class="docutils literal notranslate"><span class="pre">PYTHON</span></code> variable as an argument to configure script (e.g., <code class="docutils literal notranslate"><span class="pre">./configure</span> <span class="pre">PYTHON=/usr/bin/python3.5</span></code>).</p> <div class="section" id="hpack-api"> <h2>HPACK API<a class="headerlink" href="#hpack-api" title="Permalink to this headline">¶</a></h2> <dl class="class"> <dt id="nghttp2.HDDeflater"> <em class="property">class </em><code class="descclassname">nghttp2.</code><code class="descname">HDDeflater</code><span class="sig-paren">(</span><em>hd_table_bufsize_max=DEFLATE_MAX_HEADER_TABLE_SIZE</em><span class="sig-paren">)</span><a class="headerlink" href="#nghttp2.HDDeflater" title="Permalink to this definition">¶</a></dt> <dd><p>This class is used to perform header compression. The <em>hd_table_bufsize_max</em> limits the usage of header table in the given amount of bytes. The default value is <a class="reference internal" href="#nghttp2.DEFLATE_MAX_HEADER_TABLE_SIZE" title="nghttp2.DEFLATE_MAX_HEADER_TABLE_SIZE"><code class="xref py py-data docutils literal notranslate"><span class="pre">DEFLATE_MAX_HEADER_TABLE_SIZE</span></code></a>. This is necessary because the deflater and inflater share the same amount of header table and the inflater decides that number. The deflater may not want to use all header table size because of limited memory availability. In that case, <em>hd_table_bufsize_max</em> can be used to cap the upper limit of table size whatever the header table size is chosen by the inflater.</p> <dl class="method"> <dt id="nghttp2.HDDeflater.deflate"> <code class="descname">deflate</code><span class="sig-paren">(</span><em>headers</em><span class="sig-paren">)</span><a class="headerlink" href="#nghttp2.HDDeflater.deflate" title="Permalink to this definition">¶</a></dt> <dd><p>Deflates the <em>headers</em>. The <em>headers</em> must be sequence of tuple of name/value pair, which are byte strings (not unicode string).</p> <p>This method returns the deflated header block in byte string. Raises the exception if any error occurs.</p> </dd></dl> <dl class="method"> <dt id="nghttp2.HDDeflater.set_no_refset"> <code class="descname">set_no_refset</code><span class="sig-paren">(</span><em>no_refset</em><span class="sig-paren">)</span><a class="headerlink" href="#nghttp2.HDDeflater.set_no_refset" title="Permalink to this definition">¶</a></dt> <dd><p>Tells the deflater not to use reference set if <em>no_refset</em> is evaluated to <code class="docutils literal notranslate"><span class="pre">True</span></code>. If that happens, on each subsequent invocation of <a class="reference internal" href="#nghttp2.HDDeflater.deflate" title="nghttp2.HDDeflater.deflate"><code class="xref py py-meth docutils literal notranslate"><span class="pre">deflate()</span></code></a>, deflater will clear up refersent set.</p> </dd></dl> <dl class="method"> <dt id="nghttp2.HDDeflater.change_table_size"> <code class="descname">change_table_size</code><span class="sig-paren">(</span><em>hd_table_bufsize_max</em><span class="sig-paren">)</span><a class="headerlink" href="#nghttp2.HDDeflater.change_table_size" title="Permalink to this definition">¶</a></dt> <dd><p>Changes header table size to <em>hd_table_bufsize_max</em> byte. if <em>hd_table_bufsize_max</em> is strictly larger than <code class="docutils literal notranslate"><span class="pre">hd_table_bufsize_max</span></code> given in constructor, <code class="docutils literal notranslate"><span class="pre">hd_table_bufsize_max</span></code> is used as header table size instead.</p> <p>Raises the exception if any error occurs.</p> </dd></dl> <dl class="method"> <dt id="nghttp2.HDDeflater.get_hd_table"> <code class="descname">get_hd_table</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#nghttp2.HDDeflater.get_hd_table" title="Permalink to this definition">¶</a></dt> <dd><p>Returns copy of current dynamic header table.</p> </dd></dl> </dd></dl> <p>The following example shows how to deflate header name/value pairs:</p> <div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">binascii</span><span class="o">,</span> <span class="nn">nghttp2</span> <span class="n">deflater</span> <span class="o">=</span> <span class="n">nghttp2</span><span class="o">.</span><span class="n">HDDeflater</span><span class="p">()</span> <span class="n">res</span> <span class="o">=</span> <span class="n">deflater</span><span class="o">.</span><span class="n">deflate</span><span class="p">([(</span><span class="sa">b</span><span class="s1">'foo'</span><span class="p">,</span> <span class="sa">b</span><span class="s1">'bar'</span><span class="p">),</span> <span class="p">(</span><span class="sa">b</span><span class="s1">'baz'</span><span class="p">,</span> <span class="sa">b</span><span class="s1">'buz'</span><span class="p">)])</span> <span class="k">print</span><span class="p">(</span><span class="n">binascii</span><span class="o">.</span><span class="n">b2a_hex</span><span class="p">(</span><span class="n">res</span><span class="p">))</span> </pre></div> </div> <dl class="class"> <dt id="nghttp2.HDInflater"> <em class="property">class </em><code class="descclassname">nghttp2.</code><code class="descname">HDInflater</code><a class="headerlink" href="#nghttp2.HDInflater" title="Permalink to this definition">¶</a></dt> <dd><p>This class is used to perform header decompression.</p> <dl class="method"> <dt id="nghttp2.HDInflater.inflate"> <code class="descname">inflate</code><span class="sig-paren">(</span><em>data</em><span class="sig-paren">)</span><a class="headerlink" href="#nghttp2.HDInflater.inflate" title="Permalink to this definition">¶</a></dt> <dd><p>Inflates the deflated header block <em>data</em>. The <em>data</em> must be byte string.</p> <p>Raises the exception if any error occurs.</p> </dd></dl> <dl class="method"> <dt id="nghttp2.HDInflater.change_table_size"> <code class="descname">change_table_size</code><span class="sig-paren">(</span><em>hd_table_bufsize_max</em><span class="sig-paren">)</span><a class="headerlink" href="#nghttp2.HDInflater.change_table_size" title="Permalink to this definition">¶</a></dt> <dd><p>Changes header table size to <em>hd_table_bufsize_max</em> byte.</p> <p>Raises the exception if any error occurs.</p> </dd></dl> <dl class="method"> <dt id="nghttp2.HDInflater.get_hd_table"> <code class="descname">get_hd_table</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#nghttp2.HDInflater.get_hd_table" title="Permalink to this definition">¶</a></dt> <dd><p>Returns copy of current dynamic header table.</p> </dd></dl> </dd></dl> <p>The following example shows how to inflate deflated header block:</p> <div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">deflater</span> <span class="o">=</span> <span class="n">nghttp2</span><span class="o">.</span><span class="n">HDDeflater</span><span class="p">()</span> <span class="n">data</span> <span class="o">=</span> <span class="n">deflater</span><span class="o">.</span><span class="n">deflate</span><span class="p">([(</span><span class="sa">b</span><span class="s1">'foo'</span><span class="p">,</span> <span class="sa">b</span><span class="s1">'bar'</span><span class="p">),</span> <span class="p">(</span><span class="sa">b</span><span class="s1">'baz'</span><span class="p">,</span> <span class="sa">b</span><span class="s1">'buz'</span><span class="p">)])</span> <span class="n">inflater</span> <span class="o">=</span> <span class="n">nghttp2</span><span class="o">.</span><span class="n">HDInflater</span><span class="p">()</span> <span class="n">hdrs</span> <span class="o">=</span> <span class="n">inflater</span><span class="o">.</span><span class="n">inflate</span><span class="p">(</span><span class="n">data</span><span class="p">)</span> <span class="k">print</span><span class="p">(</span><span class="n">hdrs</span><span class="p">)</span> </pre></div> </div> <dl class="function"> <dt id="nghttp2.print_hd_table"> <code class="descclassname">nghttp2.</code><code class="descname">print_hd_table</code><span class="sig-paren">(</span><em>hdtable</em><span class="sig-paren">)</span><a class="headerlink" href="#nghttp2.print_hd_table" title="Permalink to this definition">¶</a></dt> <dd><p>Convenient function to print <em>hdtable</em> to the standard output. The <em>hdtable</em> is the one retrieved by <a class="reference internal" href="#nghttp2.HDDeflater.get_hd_table" title="nghttp2.HDDeflater.get_hd_table"><code class="xref py py-meth docutils literal notranslate"><span class="pre">HDDeflater.get_hd_table()</span></code></a> or <a class="reference internal" href="#nghttp2.HDInflater.get_hd_table" title="nghttp2.HDInflater.get_hd_table"><code class="xref py py-meth docutils literal notranslate"><span class="pre">HDInflater.get_hd_table()</span></code></a>. This function does not work if header name/value cannot be decoded using UTF-8 encoding.</p> <p>In output, <code class="docutils literal notranslate"><span class="pre">s=N</span></code> means the entry occupies <code class="docutils literal notranslate"><span class="pre">N</span></code> bytes in header table. If <code class="docutils literal notranslate"><span class="pre">r=y</span></code>, then the entry is in the reference set.</p> </dd></dl> <dl class="data"> <dt id="nghttp2.DEFAULT_HEADER_TABLE_SIZE"> <code class="descclassname">nghttp2.</code><code class="descname">DEFAULT_HEADER_TABLE_SIZE</code><a class="headerlink" href="#nghttp2.DEFAULT_HEADER_TABLE_SIZE" title="Permalink to this definition">¶</a></dt> <dd><p>The default header table size, which is 4096 as per HTTP/2 specification.</p> </dd></dl> <dl class="data"> <dt id="nghttp2.DEFLATE_MAX_HEADER_TABLE_SIZE"> <code class="descclassname">nghttp2.</code><code class="descname">DEFLATE_MAX_HEADER_TABLE_SIZE</code><a class="headerlink" href="#nghttp2.DEFLATE_MAX_HEADER_TABLE_SIZE" title="Permalink to this definition">¶</a></dt> <dd><p>The default header table size for deflater. The initial value is 4096.</p> </dd></dl> </div> <div class="section" id="http-2-servers"> <h2>HTTP/2 servers<a class="headerlink" href="#http-2-servers" title="Permalink to this headline">¶</a></h2> <div class="admonition note"> <p class="first admonition-title">Note</p> <p>We use <code class="xref py py-mod docutils literal notranslate"><span class="pre">asyncio</span></code> for HTTP/2 server classes, and ALPN. Therefore, Python 3.5 or later is required to use these objects. To explicitly configure nghttp2 build to use Python 3.5, specify the <code class="docutils literal notranslate"><span class="pre">PYTHON</span></code> variable to the path to Python 3.5 executable when invoking configure script like this:</p> <div class="last highlight-text notranslate"><div class="highlight"><pre><span></span>$ ./configure PYTHON=/usr/bin/python3.5 </pre></div> </div> </div> <dl class="class"> <dt id="nghttp2.HTTP2Server"> <em class="property">class </em><code class="descclassname">nghttp2.</code><code class="descname">HTTP2Server</code><span class="sig-paren">(</span><em>address</em>, <em>RequestHandlerClass</em>, <em>ssl=None</em><span class="sig-paren">)</span><a class="headerlink" href="#nghttp2.HTTP2Server" title="Permalink to this definition">¶</a></dt> <dd><p>This class builds on top of the <code class="xref py py-mod docutils literal notranslate"><span class="pre">asyncio</span></code> event loop. On construction, <em>RequestHandlerClass</em> must be given, which must be a subclass of <a class="reference internal" href="#nghttp2.BaseRequestHandler" title="nghttp2.BaseRequestHandler"><code class="xref py py-class docutils literal notranslate"><span class="pre">BaseRequestHandler</span></code></a> class.</p> <p>The <em>address</em> must be a tuple of hostname/IP address and port to bind. If hostname/IP address is <code class="docutils literal notranslate"><span class="pre">None</span></code>, all interfaces are assumed.</p> <p>To enable SSL/TLS, specify instance of <code class="xref py py-class docutils literal notranslate"><span class="pre">ssl.SSLContext</span></code> in <em>ssl</em>. Before passing <em>ssl</em> to <code class="xref py py-func docutils literal notranslate"><span class="pre">BaseEventLoop.create_server()</span></code>, ALPN protocol identifiers are set using <code class="xref py py-meth docutils literal notranslate"><span class="pre">ssl.SSLContext.set_npn_protocols()</span></code>.</p> <p>To disable SSL/TLS, omit <em>ssl</em> or specify <code class="docutils literal notranslate"><span class="pre">None</span></code>.</p> <dl class="method"> <dt id="nghttp2.HTTP2Server.serve_forever"> <code class="descname">serve_forever</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#nghttp2.HTTP2Server.serve_forever" title="Permalink to this definition">¶</a></dt> <dd><p>Runs server and processes incoming requests forever.</p> </dd></dl> </dd></dl> <dl class="class"> <dt id="nghttp2.BaseRequestHandler"> <em class="property">class </em><code class="descclassname">nghttp2.</code><code class="descname">BaseRequestHandler</code><span class="sig-paren">(</span><em>http2</em>, <em>stream_id</em><span class="sig-paren">)</span><a class="headerlink" href="#nghttp2.BaseRequestHandler" title="Permalink to this definition">¶</a></dt> <dd><p>The class is used to handle the single HTTP/2 stream. By default, it does not nothing. It must be subclassed to handle each event callback method.</p> <p>The first callback method invoked is <a class="reference internal" href="#nghttp2.BaseRequestHandler.on_headers" title="nghttp2.BaseRequestHandler.on_headers"><code class="xref py py-meth docutils literal notranslate"><span class="pre">on_headers()</span></code></a>. It is called when HEADERS frame, which includes request header fields, is arrived.</p> <p>If request has request body, <a class="reference internal" href="#nghttp2.BaseRequestHandler.on_data" title="nghttp2.BaseRequestHandler.on_data"><code class="xref py py-meth docutils literal notranslate"><span class="pre">on_data()</span></code></a> is invoked for each chunk of received data chunk.</p> <p>When whole request is received, <a class="reference internal" href="#nghttp2.BaseRequestHandler.on_request_done" title="nghttp2.BaseRequestHandler.on_request_done"><code class="xref py py-meth docutils literal notranslate"><span class="pre">on_request_done()</span></code></a> is invoked.</p> <p>When stream is closed, <a class="reference internal" href="#nghttp2.BaseRequestHandler.on_close" title="nghttp2.BaseRequestHandler.on_close"><code class="xref py py-meth docutils literal notranslate"><span class="pre">on_close()</span></code></a> is called.</p> <p>The application can send response using <a class="reference internal" href="#nghttp2.BaseRequestHandler.send_response" title="nghttp2.BaseRequestHandler.send_response"><code class="xref py py-meth docutils literal notranslate"><span class="pre">send_response()</span></code></a> method. It can be used in <a class="reference internal" href="#nghttp2.BaseRequestHandler.on_headers" title="nghttp2.BaseRequestHandler.on_headers"><code class="xref py py-meth docutils literal notranslate"><span class="pre">on_headers()</span></code></a>, <a class="reference internal" href="#nghttp2.BaseRequestHandler.on_data" title="nghttp2.BaseRequestHandler.on_data"><code class="xref py py-meth docutils literal notranslate"><span class="pre">on_data()</span></code></a> or <a class="reference internal" href="#nghttp2.BaseRequestHandler.on_request_done" title="nghttp2.BaseRequestHandler.on_request_done"><code class="xref py py-meth docutils literal notranslate"><span class="pre">on_request_done()</span></code></a>.</p> <p>The application can push resource using <a class="reference internal" href="#nghttp2.BaseRequestHandler.push" title="nghttp2.BaseRequestHandler.push"><code class="xref py py-meth docutils literal notranslate"><span class="pre">push()</span></code></a> method. It must be used before <a class="reference internal" href="#nghttp2.BaseRequestHandler.send_response" title="nghttp2.BaseRequestHandler.send_response"><code class="xref py py-meth docutils literal notranslate"><span class="pre">send_response()</span></code></a> call.</p> <p>A <a class="reference internal" href="#nghttp2.BaseRequestHandler" title="nghttp2.BaseRequestHandler"><code class="xref py py-class docutils literal notranslate"><span class="pre">BaseRequestHandler</span></code></a> has the following instance variables:</p> <dl class="attribute"> <dt id="nghttp2.BaseRequestHandler.client_address"> <code class="descname">client_address</code><a class="headerlink" href="#nghttp2.BaseRequestHandler.client_address" title="Permalink to this definition">¶</a></dt> <dd><p>Contains a tuple of the form <code class="docutils literal notranslate"><span class="pre">(host,</span> <span class="pre">port)</span></code> referring to the client’s address.</p> </dd></dl> <dl class="attribute"> <dt id="nghttp2.BaseRequestHandler.stream_id"> <code class="descname">stream_id</code><a class="headerlink" href="#nghttp2.BaseRequestHandler.stream_id" title="Permalink to this definition">¶</a></dt> <dd><p>Stream ID of this stream</p> </dd></dl> <dl class="attribute"> <dt id="nghttp2.BaseRequestHandler.scheme"> <code class="descname">scheme</code><a class="headerlink" href="#nghttp2.BaseRequestHandler.scheme" title="Permalink to this definition">¶</a></dt> <dd><p>Scheme of the request URI. This is a value of <code class="docutils literal notranslate"><span class="pre">:scheme</span></code> header field.</p> </dd></dl> <dl class="attribute"> <dt id="nghttp2.BaseRequestHandler.method"> <code class="descname">method</code><a class="headerlink" href="#nghttp2.BaseRequestHandler.method" title="Permalink to this definition">¶</a></dt> <dd><p>Method of this stream. This is a value of <code class="docutils literal notranslate"><span class="pre">:method</span></code> header field.</p> </dd></dl> <dl class="attribute"> <dt id="nghttp2.BaseRequestHandler.host"> <code class="descname">host</code><a class="headerlink" href="#nghttp2.BaseRequestHandler.host" title="Permalink to this definition">¶</a></dt> <dd><p>This is a value of <code class="docutils literal notranslate"><span class="pre">:authority</span></code> or <code class="docutils literal notranslate"><span class="pre">host</span></code> header field.</p> </dd></dl> <dl class="attribute"> <dt id="nghttp2.BaseRequestHandler.path"> <code class="descname">path</code><a class="headerlink" href="#nghttp2.BaseRequestHandler.path" title="Permalink to this definition">¶</a></dt> <dd><p>This is a value of <code class="docutils literal notranslate"><span class="pre">:path</span></code> header field.</p> </dd></dl> <dl class="attribute"> <dt id="nghttp2.BaseRequestHandler.headers"> <code class="descname">headers</code><a class="headerlink" href="#nghttp2.BaseRequestHandler.headers" title="Permalink to this definition">¶</a></dt> <dd><p>Request header fields.</p> </dd></dl> <p>A <a class="reference internal" href="#nghttp2.BaseRequestHandler" title="nghttp2.BaseRequestHandler"><code class="xref py py-class docutils literal notranslate"><span class="pre">BaseRequestHandler</span></code></a> has the following methods:</p> <dl class="method"> <dt id="nghttp2.BaseRequestHandler.on_headers"> <code class="descname">on_headers</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#nghttp2.BaseRequestHandler.on_headers" title="Permalink to this definition">¶</a></dt> <dd><p>Called when request HEADERS is arrived. By default, this method does nothing.</p> </dd></dl> <dl class="method"> <dt id="nghttp2.BaseRequestHandler.on_data"> <code class="descname">on_data</code><span class="sig-paren">(</span><em>data</em><span class="sig-paren">)</span><a class="headerlink" href="#nghttp2.BaseRequestHandler.on_data" title="Permalink to this definition">¶</a></dt> <dd><p>Called when a chunk of request body <em>data</em> is arrived. This method will be called multiple times until all data are received. By default, this method does nothing.</p> </dd></dl> <dl class="method"> <dt id="nghttp2.BaseRequestHandler.on_request_done"> <code class="descname">on_request_done</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#nghttp2.BaseRequestHandler.on_request_done" title="Permalink to this definition">¶</a></dt> <dd><p>Called when whole request was received. By default, this method does nothing.</p> </dd></dl> <dl class="method"> <dt id="nghttp2.BaseRequestHandler.on_close"> <code class="descname">on_close</code><span class="sig-paren">(</span><em>error_code</em><span class="sig-paren">)</span><a class="headerlink" href="#nghttp2.BaseRequestHandler.on_close" title="Permalink to this definition">¶</a></dt> <dd><p>Called when stream is about to close. The <em>error_code</em> indicates the reason of closure. If it is <code class="docutils literal notranslate"><span class="pre">0</span></code>, the stream is going to close without error.</p> </dd></dl> <dl class="method"> <dt id="nghttp2.BaseRequestHandler.send_response"> <code class="descname">send_response</code><span class="sig-paren">(</span><em>status=200</em>, <em>headers=None</em>, <em>body=None</em><span class="sig-paren">)</span><a class="headerlink" href="#nghttp2.BaseRequestHandler.send_response" title="Permalink to this definition">¶</a></dt> <dd><p>Send response. The <em>status</em> is HTTP status code. The <em>headers</em> is additional response headers. The <em>:status</em> header field will be appended by the library. The <em>body</em> is the response body. It could be <code class="docutils literal notranslate"><span class="pre">None</span></code> if response body is empty. Or it must be instance of either <code class="docutils literal notranslate"><span class="pre">str</span></code>, <code class="docutils literal notranslate"><span class="pre">bytes</span></code>, <code class="xref py py-class docutils literal notranslate"><span class="pre">io.IOBase</span></code> or callable, called body generator, which takes one parameter, size. The body generator generates response body. It can pause generation of response so that it can wait for slow backend data generation. When invoked, it should return tuple, byte string at most size length and flag. The flag is either <a class="reference internal" href="#nghttp2.DATA_OK" title="nghttp2.DATA_OK"><code class="xref py py-data docutils literal notranslate"><span class="pre">DATA_OK</span></code></a>, <a class="reference internal" href="#nghttp2.DATA_EOF" title="nghttp2.DATA_EOF"><code class="xref py py-data docutils literal notranslate"><span class="pre">DATA_EOF</span></code></a> or <a class="reference internal" href="#nghttp2.DATA_DEFERRED" title="nghttp2.DATA_DEFERRED"><code class="xref py py-data docutils literal notranslate"><span class="pre">DATA_DEFERRED</span></code></a>. For non-empty byte string and it is not the last chunk of response, <a class="reference internal" href="#nghttp2.DATA_OK" title="nghttp2.DATA_OK"><code class="xref py py-data docutils literal notranslate"><span class="pre">DATA_OK</span></code></a> must be returned as flag. If this is the last chunk of the response (byte string could be <code class="docutils literal notranslate"><span class="pre">None</span></code>), <a class="reference internal" href="#nghttp2.DATA_EOF" title="nghttp2.DATA_EOF"><code class="xref py py-data docutils literal notranslate"><span class="pre">DATA_EOF</span></code></a> must be returned as flag. If there is no data available right now, but additional data are anticipated, return tuple (<code class="docutils literal notranslate"><span class="pre">None</span></code>, <a class="reference internal" href="#nghttp2.DATA_DEFERRED" title="nghttp2.DATA_DEFERRED"><code class="xref py py-data docutils literal notranslate"><span class="pre">DATA_DEFERRED</span></code></a>). When data arrived, call <a class="reference internal" href="#nghttp2.BaseRequestHandler.resume" title="nghttp2.BaseRequestHandler.resume"><code class="xref py py-meth docutils literal notranslate"><span class="pre">resume()</span></code></a> and restart response body transmission.</p> <p>Only the body generator can pause response body generation; instance of <code class="xref py py-class docutils literal notranslate"><span class="pre">io.IOBase</span></code> must not block.</p> <p>If instance of <code class="docutils literal notranslate"><span class="pre">str</span></code> is specified as <em>body</em>, it will be encoded using UTF-8.</p> <p>The <em>headers</em> is a list of tuple of the form <code class="docutils literal notranslate"><span class="pre">(name,</span> <span class="pre">value)</span></code>. The <code class="docutils literal notranslate"><span class="pre">name</span></code> and <code class="docutils literal notranslate"><span class="pre">value</span></code> can be either byte string or unicode string. In the latter case, they will be encoded using UTF-8.</p> <p>Raises the exception if any error occurs.</p> </dd></dl> <dl class="method"> <dt id="nghttp2.BaseRequestHandler.push"> <code class="descname">push</code><span class="sig-paren">(</span><em>path</em>, <em>method='GET'</em>, <em>request_headers=None</em>, <em>status=200</em>, <em>headers=None</em>, <em>body=None</em><span class="sig-paren">)</span><a class="headerlink" href="#nghttp2.BaseRequestHandler.push" title="Permalink to this definition">¶</a></dt> <dd><p>Push a specified resource. The <em>path</em> is a path portion of request URI for this resource. The <em>method</em> is a method to access this resource. The <em>request_headers</em> is additional request headers to access this resource. The <code class="docutils literal notranslate"><span class="pre">:scheme</span></code>, <code class="docutils literal notranslate"><span class="pre">:method</span></code>, <code class="docutils literal notranslate"><span class="pre">:authority</span></code> and <code class="docutils literal notranslate"><span class="pre">:path</span></code> are appended by the library. The <code class="docutils literal notranslate"><span class="pre">:scheme</span></code> and <code class="docutils literal notranslate"><span class="pre">:authority</span></code> are inherited from request header fields of the associated stream.</p> <p>The <em>status</em> is HTTP status code. The <em>headers</em> is additional response headers. The <code class="docutils literal notranslate"><span class="pre">:status</span></code> header field is appended by the library. The <em>body</em> is the response body. It has the same semantics of <em>body</em> parameter of <a class="reference internal" href="#nghttp2.BaseRequestHandler.send_response" title="nghttp2.BaseRequestHandler.send_response"><code class="xref py py-meth docutils literal notranslate"><span class="pre">send_response()</span></code></a>.</p> <p>The headers and request_headers are a list of tuple of the form <code class="docutils literal notranslate"><span class="pre">(name,</span> <span class="pre">value)</span></code>. The <code class="docutils literal notranslate"><span class="pre">name</span></code> and <code class="docutils literal notranslate"><span class="pre">value</span></code> can be either byte string or unicode string. In the latter case, they will be encoded using UTF-8.</p> <p>Returns an instance of <code class="docutils literal notranslate"><span class="pre">RequestHandlerClass</span></code> specified in <a class="reference internal" href="#nghttp2.HTTP2Server" title="nghttp2.HTTP2Server"><code class="xref py py-class docutils literal notranslate"><span class="pre">HTTP2Server</span></code></a> constructor for the pushed resource.</p> <p>Raises the exception if any error occurs.</p> </dd></dl> <dl class="method"> <dt id="nghttp2.BaseRequestHandler.resume"> <code class="descname">resume</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#nghttp2.BaseRequestHandler.resume" title="Permalink to this definition">¶</a></dt> <dd><p>Signals the restarting of response body transmission paused by <code class="docutils literal notranslate"><span class="pre">DATA_DEFERRED</span></code> from the body generator (see <a class="reference internal" href="#nghttp2.BaseRequestHandler.send_response" title="nghttp2.BaseRequestHandler.send_response"><code class="xref py py-meth docutils literal notranslate"><span class="pre">send_response()</span></code></a> about the body generator). It is not an error calling this method while response body transmission is not paused.</p> </dd></dl> </dd></dl> <dl class="data"> <dt id="nghttp2.DATA_OK"> <code class="descclassname">nghttp2.</code><code class="descname">DATA_OK</code><a class="headerlink" href="#nghttp2.DATA_OK" title="Permalink to this definition">¶</a></dt> <dd><p><code class="docutils literal notranslate"><span class="pre">DATA_OK</span></code> indicates non empty data is generated from body generator.</p> </dd></dl> <dl class="data"> <dt id="nghttp2.DATA_EOF"> <code class="descclassname">nghttp2.</code><code class="descname">DATA_EOF</code><a class="headerlink" href="#nghttp2.DATA_EOF" title="Permalink to this definition">¶</a></dt> <dd><p><code class="docutils literal notranslate"><span class="pre">DATA_EOF</span></code> indicates the end of response body.</p> </dd></dl> <dl class="data"> <dt id="nghttp2.DATA_DEFERRED"> <code class="descclassname">nghttp2.</code><code class="descname">DATA_DEFERRED</code><a class="headerlink" href="#nghttp2.DATA_DEFERRED" title="Permalink to this definition">¶</a></dt> <dd><p><code class="docutils literal notranslate"><span class="pre">DATA_DEFERRED</span></code> indicates that data are not available right now and response should be paused.</p> </dd></dl> <p>The following example illustrates <a class="reference internal" href="#nghttp2.HTTP2Server" title="nghttp2.HTTP2Server"><code class="xref py py-class docutils literal notranslate"><span class="pre">HTTP2Server</span></code></a> and <a class="reference internal" href="#nghttp2.BaseRequestHandler" title="nghttp2.BaseRequestHandler"><code class="xref py py-class docutils literal notranslate"><span class="pre">BaseRequestHandler</span></code></a> usage:</p> <div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="ch">#!/usr/bin/env python</span> <span class="kn">import</span> <span class="nn">io</span><span class="o">,</span> <span class="nn">ssl</span> <span class="kn">import</span> <span class="nn">nghttp2</span> <span class="k">class</span> <span class="nc">Handler</span><span class="p">(</span><span class="n">nghttp2</span><span class="o">.</span><span class="n">BaseRequestHandler</span><span class="p">):</span> <span class="k">def</span> <span class="nf">on_headers</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> <span class="bp">self</span><span class="o">.</span><span class="n">push</span><span class="p">(</span><span class="n">path</span><span class="o">=</span><span class="s1">'/css/style.css'</span><span class="p">,</span> <span class="n">request_headers</span> <span class="o">=</span> <span class="p">[(</span><span class="s1">'content-type'</span><span class="p">,</span> <span class="s1">'text/css'</span><span class="p">)],</span> <span class="n">status</span><span class="o">=</span><span class="mi">200</span><span class="p">,</span> <span class="n">body</span><span class="o">=</span><span class="s1">'body{margin:0;}'</span><span class="p">)</span> <span class="bp">self</span><span class="o">.</span><span class="n">send_response</span><span class="p">(</span><span class="n">status</span><span class="o">=</span><span class="mi">200</span><span class="p">,</span> <span class="n">headers</span> <span class="o">=</span> <span class="p">[(</span><span class="s1">'content-type'</span><span class="p">,</span> <span class="s1">'text/plain'</span><span class="p">)],</span> <span class="n">body</span><span class="o">=</span><span class="n">io</span><span class="o">.</span><span class="n">BytesIO</span><span class="p">(</span><span class="sa">b</span><span class="s1">'nghttp2-python FTW'</span><span class="p">))</span> <span class="n">ctx</span> <span class="o">=</span> <span class="n">ssl</span><span class="o">.</span><span class="n">SSLContext</span><span class="p">(</span><span class="n">ssl</span><span class="o">.</span><span class="n">PROTOCOL_SSLv23</span><span class="p">)</span> <span class="n">ctx</span><span class="o">.</span><span class="n">options</span> <span class="o">=</span> <span class="n">ssl</span><span class="o">.</span><span class="n">OP_ALL</span> <span class="o">|</span> <span class="n">ssl</span><span class="o">.</span><span class="n">OP_NO_SSLv2</span> <span class="o">|</span> <span class="n">ssl</span><span class="o">.</span><span class="n">OP_NO_SSLv3</span> <span class="n">ctx</span><span class="o">.</span><span class="n">load_cert_chain</span><span class="p">(</span><span class="s1">'server.crt'</span><span class="p">,</span> <span class="s1">'server.key'</span><span class="p">)</span> <span class="c1"># give None to ssl to make the server non-SSL/TLS</span> <span class="n">server</span> <span class="o">=</span> <span class="n">nghttp2</span><span class="o">.</span><span class="n">HTTP2Server</span><span class="p">((</span><span class="s1">'127.0.0.1'</span><span class="p">,</span> <span class="mi">8443</span><span class="p">),</span> <span class="n">Handler</span><span class="p">,</span> <span class="n">ssl</span><span class="o">=</span><span class="n">ctx</span><span class="p">)</span> <span class="n">server</span><span class="o">.</span><span class="n">serve_forever</span><span class="p">()</span> </pre></div> </div> <p>The following example illustrates HTTP/2 server using asynchronous response body generation. This is simplified reverse proxy:</p> <div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="ch">#!/usr/bin/env python</span> <span class="kn">import</span> <span class="nn">ssl</span> <span class="kn">import</span> <span class="nn">os</span> <span class="kn">import</span> <span class="nn">urllib</span> <span class="kn">import</span> <span class="nn">asyncio</span> <span class="kn">import</span> <span class="nn">io</span> <span class="kn">import</span> <span class="nn">nghttp2</span> <span class="nd">@asyncio.coroutine</span> <span class="k">def</span> <span class="nf">get_http_header</span><span class="p">(</span><span class="n">handler</span><span class="p">,</span> <span class="n">url</span><span class="p">):</span> <span class="n">url</span> <span class="o">=</span> <span class="n">urllib</span><span class="o">.</span><span class="n">parse</span><span class="o">.</span><span class="n">urlsplit</span><span class="p">(</span><span class="n">url</span><span class="p">)</span> <span class="n">ssl</span> <span class="o">=</span> <span class="n">url</span><span class="o">.</span><span class="n">scheme</span> <span class="o">==</span> <span class="s1">'https'</span> <span class="k">if</span> <span class="n">url</span><span class="o">.</span><span class="n">port</span> <span class="o">==</span> <span class="bp">None</span><span class="p">:</span> <span class="k">if</span> <span class="n">url</span><span class="o">.</span><span class="n">scheme</span> <span class="o">==</span> <span class="s1">'https'</span><span class="p">:</span> <span class="n">port</span> <span class="o">=</span> <span class="mi">443</span> <span class="k">else</span><span class="p">:</span> <span class="n">port</span> <span class="o">=</span> <span class="mi">80</span> <span class="k">else</span><span class="p">:</span> <span class="n">port</span> <span class="o">=</span> <span class="n">url</span><span class="o">.</span><span class="n">port</span> <span class="n">connect</span> <span class="o">=</span> <span class="n">asyncio</span><span class="o">.</span><span class="n">open_connection</span><span class="p">(</span><span class="n">url</span><span class="o">.</span><span class="n">hostname</span><span class="p">,</span> <span class="n">port</span><span class="p">,</span> <span class="n">ssl</span><span class="o">=</span><span class="n">ssl</span><span class="p">)</span> <span class="n">reader</span><span class="p">,</span> <span class="n">writer</span> <span class="o">=</span> <span class="k">yield from</span> <span class="n">connect</span> <span class="n">req</span> <span class="o">=</span> <span class="s1">'GET {path} HTTP/1.0</span><span class="se">\r\n\r\n</span><span class="s1">'</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">path</span><span class="o">=</span><span class="n">url</span><span class="o">.</span><span class="n">path</span> <span class="ow">or</span> <span class="s1">'/'</span><span class="p">)</span> <span class="n">writer</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">req</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s1">'utf-8'</span><span class="p">))</span> <span class="c1"># skip response header fields</span> <span class="k">while</span> <span class="bp">True</span><span class="p">:</span> <span class="n">line</span> <span class="o">=</span> <span class="k">yield from</span> <span class="n">reader</span><span class="o">.</span><span class="n">readline</span><span class="p">()</span> <span class="n">line</span> <span class="o">=</span> <span class="n">line</span><span class="o">.</span><span class="n">rstrip</span><span class="p">()</span> <span class="k">if</span> <span class="ow">not</span> <span class="n">line</span><span class="p">:</span> <span class="k">break</span> <span class="c1"># read body</span> <span class="k">while</span> <span class="bp">True</span><span class="p">:</span> <span class="n">b</span> <span class="o">=</span> <span class="k">yield from</span> <span class="n">reader</span><span class="o">.</span><span class="n">read</span><span class="p">(</span><span class="mi">4096</span><span class="p">)</span> <span class="k">if</span> <span class="ow">not</span> <span class="n">b</span><span class="p">:</span> <span class="k">break</span> <span class="n">handler</span><span class="o">.</span><span class="n">buf</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">b</span><span class="p">)</span> <span class="n">writer</span><span class="o">.</span><span class="n">close</span><span class="p">()</span> <span class="n">handler</span><span class="o">.</span><span class="n">buf</span><span class="o">.</span><span class="n">seek</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span> <span class="n">handler</span><span class="o">.</span><span class="n">eof</span> <span class="o">=</span> <span class="bp">True</span> <span class="n">handler</span><span class="o">.</span><span class="n">resume</span><span class="p">()</span> <span class="k">class</span> <span class="nc">Body</span><span class="p">:</span> <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">handler</span><span class="p">):</span> <span class="bp">self</span><span class="o">.</span><span class="n">handler</span> <span class="o">=</span> <span class="n">handler</span> <span class="bp">self</span><span class="o">.</span><span class="n">handler</span><span class="o">.</span><span class="n">eof</span> <span class="o">=</span> <span class="bp">False</span> <span class="bp">self</span><span class="o">.</span><span class="n">handler</span><span class="o">.</span><span class="n">buf</span> <span class="o">=</span> <span class="n">io</span><span class="o">.</span><span class="n">BytesIO</span><span class="p">()</span> <span class="k">def</span> <span class="nf">generate</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">n</span><span class="p">):</span> <span class="n">buf</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">handler</span><span class="o">.</span><span class="n">buf</span> <span class="n">data</span> <span class="o">=</span> <span class="n">buf</span><span class="o">.</span><span class="n">read1</span><span class="p">(</span><span class="n">n</span><span class="p">)</span> <span class="k">if</span> <span class="ow">not</span> <span class="n">data</span> <span class="ow">and</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">handler</span><span class="o">.</span><span class="n">eof</span><span class="p">:</span> <span class="k">return</span> <span class="bp">None</span><span class="p">,</span> <span class="n">nghttp2</span><span class="o">.</span><span class="n">DATA_DEFERRED</span> <span class="k">return</span> <span class="n">data</span><span class="p">,</span> <span class="n">nghttp2</span><span class="o">.</span><span class="n">DATA_EOF</span> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">handler</span><span class="o">.</span><span class="n">eof</span> <span class="k">else</span> <span class="n">nghttp2</span><span class="o">.</span><span class="n">DATA_OK</span> <span class="k">class</span> <span class="nc">Handler</span><span class="p">(</span><span class="n">nghttp2</span><span class="o">.</span><span class="n">BaseRequestHandler</span><span class="p">):</span> <span class="k">def</span> <span class="nf">on_headers</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> <span class="n">body</span> <span class="o">=</span> <span class="n">Body</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="n">asyncio</span><span class="o">.</span><span class="n">async</span><span class="p">(</span><span class="n">get_http_header</span><span class="p">(</span> <span class="bp">self</span><span class="p">,</span> <span class="s1">'http://localhost'</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">decode</span><span class="p">(</span><span class="s1">'utf-8'</span><span class="p">)))</span> <span class="bp">self</span><span class="o">.</span><span class="n">send_response</span><span class="p">(</span><span class="n">status</span><span class="o">=</span><span class="mi">200</span><span class="p">,</span> <span class="n">body</span><span class="o">=</span><span class="n">body</span><span class="o">.</span><span class="n">generate</span><span class="p">)</span> <span class="n">ctx</span> <span class="o">=</span> <span class="n">ssl</span><span class="o">.</span><span class="n">SSLContext</span><span class="p">(</span><span class="n">ssl</span><span class="o">.</span><span class="n">PROTOCOL_SSLv23</span><span class="p">)</span> <span class="n">ctx</span><span class="o">.</span><span class="n">options</span> <span class="o">=</span> <span class="n">ssl</span><span class="o">.</span><span class="n">OP_ALL</span> <span class="o">|</span> <span class="n">ssl</span><span class="o">.</span><span class="n">OP_NO_SSLv2</span> <span class="o">|</span> <span class="n">ssl</span><span class="o">.</span><span class="n">OP_NO_SSLv3</span> <span class="n">ctx</span><span class="o">.</span><span class="n">load_cert_chain</span><span class="p">(</span><span class="s1">'server.crt'</span><span class="p">,</span> <span class="s1">'server.key'</span><span class="p">)</span> <span class="n">server</span> <span class="o">=</span> <span class="n">nghttp2</span><span class="o">.</span><span class="n">HTTP2Server</span><span class="p">((</span><span class="s1">'127.0.0.1'</span><span class="p">,</span> <span class="mi">8443</span><span class="p">),</span> <span class="n">Handler</span><span class="p">,</span> <span class="n">ssl</span><span class="o">=</span><span class="n">ctx</span><span class="p">)</span> <span class="n">server</span><span class="o">.</span><span class="n">serve_forever</span><span class="p">()</span> </pre></div> </div> </div> </div> </div> </div> <footer> <div class="rst-footer-buttons" role="navigation" aria-label="footer navigation"> <a href="nghttp2.h.html" class="btn btn-neutral float-right" title="nghttp2.h" accesskey="n">Next <span class="fa fa-arrow-circle-right"></span></a> <a href="libnghttp2_asio.html" class="btn btn-neutral" title="libnghttp2_asio: High level HTTP/2 C++ library" accesskey="p"><span class="fa fa-arrow-circle-left"></span> Previous</a> </div> <hr/> <div role="contentinfo"> <p> © Copyright 2012, 2015, 2016, Tatsuhiro Tsujikawa. </p> </div> Built with <a href="http://sphinx-doc.org/">Sphinx</a> using a <a href="https://github.com/snide/sphinx_rtd_theme">theme</a> provided by <a href="https://readthedocs.org">Read the Docs</a>. </footer> </div> </div> </section> </div> <script type="text/javascript"> var DOCUMENTATION_OPTIONS = { URL_ROOT:'./', VERSION:'1.38.0', COLLAPSE_INDEX:false, FILE_SUFFIX:'.html', HAS_SOURCE: false }; </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> <script type="text/javascript" src="_static/language_data.js"></script> <script type="text/javascript" src="_static/js/theme.js"></script> <script type="text/javascript"> jQuery(function () { SphinxRtdTheme.StickyNav.enable(); }); </script> </body> </html>