python-peps/pep-0333/index.html

1689 lines
138 KiB
HTML
Raw Permalink 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">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="color-scheme" content="light dark">
<title>PEP 333 Python Web Server Gateway Interface v1.0 | peps.python.org</title>
<link rel="shortcut icon" href="../_static/py.png">
<link rel="canonical" href="https://peps.python.org/pep-0333/">
<link rel="stylesheet" href="../_static/style.css" type="text/css">
<link rel="stylesheet" href="../_static/mq.css" type="text/css">
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" media="(prefers-color-scheme: light)" id="pyg-light">
<link rel="stylesheet" href="../_static/pygments_dark.css" type="text/css" media="(prefers-color-scheme: dark)" id="pyg-dark">
<link rel="alternate" type="application/rss+xml" title="Latest PEPs" href="https://peps.python.org/peps.rss">
<meta property="og:title" content='PEP 333 Python Web Server Gateway Interface v1.0 | peps.python.org'>
<meta property="og:description" content="This document specifies a proposed standard interface between web servers and Python web applications or frameworks, to promote web application portability across a variety of web servers.">
<meta property="og:type" content="website">
<meta property="og:url" content="https://peps.python.org/pep-0333/">
<meta property="og:site_name" content="Python Enhancement Proposals (PEPs)">
<meta property="og:image" content="https://peps.python.org/_static/og-image.png">
<meta property="og:image:alt" content="Python PEPs">
<meta property="og:image:width" content="200">
<meta property="og:image:height" content="200">
<meta name="description" content="This document specifies a proposed standard interface between web servers and Python web applications or frameworks, to promote web application portability across a variety of web servers.">
<meta name="theme-color" content="#3776ab">
</head>
<body>
<svg xmlns="http://www.w3.org/2000/svg" style="display: none;">
<symbol id="svg-sun-half" viewBox="0 0 24 24" pointer-events="all">
<title>Following system colour scheme</title>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none"
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<circle cx="12" cy="12" r="9"></circle>
<path d="M12 3v18m0-12l4.65-4.65M12 14.3l7.37-7.37M12 19.6l8.85-8.85"></path>
</svg>
</symbol>
<symbol id="svg-moon" viewBox="0 0 24 24" pointer-events="all">
<title>Selected dark colour scheme</title>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none"
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
<path d="M12 3c.132 0 .263 0 .393 0a7.5 7.5 0 0 0 7.92 12.446a9 9 0 1 1 -8.313 -12.454z"></path>
</svg>
</symbol>
<symbol id="svg-sun" viewBox="0 0 24 24" pointer-events="all">
<title>Selected light colour scheme</title>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none"
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<circle cx="12" cy="12" r="5"></circle>
<line x1="12" y1="1" x2="12" y2="3"></line>
<line x1="12" y1="21" x2="12" y2="23"></line>
<line x1="4.22" y1="4.22" x2="5.64" y2="5.64"></line>
<line x1="18.36" y1="18.36" x2="19.78" y2="19.78"></line>
<line x1="1" y1="12" x2="3" y2="12"></line>
<line x1="21" y1="12" x2="23" y2="12"></line>
<line x1="4.22" y1="19.78" x2="5.64" y2="18.36"></line>
<line x1="18.36" y1="5.64" x2="19.78" y2="4.22"></line>
</svg>
</symbol>
</svg>
<script>
document.documentElement.dataset.colour_scheme = localStorage.getItem("colour_scheme") || "auto"
</script>
<section id="pep-page-section">
<header>
<h1>Python Enhancement Proposals</h1>
<ul class="breadcrumbs">
<li><a href="https://www.python.org/" title="The Python Programming Language">Python</a> &raquo; </li>
<li><a href="../pep-0000/">PEP Index</a> &raquo; </li>
<li>PEP 333</li>
</ul>
<button id="colour-scheme-cycler" onClick="setColourScheme(nextColourScheme())">
<svg aria-hidden="true" class="colour-scheme-icon-when-auto"><use href="#svg-sun-half"></use></svg>
<svg aria-hidden="true" class="colour-scheme-icon-when-dark"><use href="#svg-moon"></use></svg>
<svg aria-hidden="true" class="colour-scheme-icon-when-light"><use href="#svg-sun"></use></svg>
<span class="visually-hidden">Toggle light / dark / auto colour theme</span>
</button>
</header>
<article>
<section id="pep-content">
<h1 class="page-title">PEP 333 Python Web Server Gateway Interface v1.0</h1>
<dl class="rfc2822 field-list simple">
<dt class="field-odd">Author<span class="colon">:</span></dt>
<dd class="field-odd">Phillip J. Eby &lt;pje&#32;&#97;t&#32;telecommunity.com&gt;</dd>
<dt class="field-even">Discussions-To<span class="colon">:</span></dt>
<dd class="field-even"><a class="reference external" href="https://mail.python.org/mailman/listinfo/web-sig">Web-SIG list</a></dd>
<dt class="field-odd">Status<span class="colon">:</span></dt>
<dd class="field-odd"><abbr title="Accepted and implementation complete, or no longer active">Final</abbr></dd>
<dt class="field-even">Type<span class="colon">:</span></dt>
<dd class="field-even"><abbr title="Non-normative PEP containing background, guidelines or other information relevant to the Python ecosystem">Informational</abbr></dd>
<dt class="field-odd">Created<span class="colon">:</span></dt>
<dd class="field-odd">07-Dec-2003</dd>
<dt class="field-even">Post-History<span class="colon">:</span></dt>
<dd class="field-even">07-Dec-2003, 08-Aug-2004, 20-Aug-2004, 27-Aug-2004, 27-Sep-2010</dd>
<dt class="field-odd">Superseded-By<span class="colon">:</span></dt>
<dd class="field-odd"><a class="reference external" href="../pep-3333/">3333</a></dd>
</dl>
<hr class="docutils" />
<section id="contents">
<details><summary>Table of Contents</summary><ul class="simple">
<li><a class="reference internal" href="#preface">Preface</a></li>
<li><a class="reference internal" href="#abstract">Abstract</a></li>
<li><a class="reference internal" href="#rationale-and-goals">Rationale and Goals</a></li>
<li><a class="reference internal" href="#specification-overview">Specification Overview</a><ul>
<li><a class="reference internal" href="#the-application-framework-side">The Application/Framework Side</a></li>
<li><a class="reference internal" href="#the-server-gateway-side">The Server/Gateway Side</a></li>
<li><a class="reference internal" href="#middleware-components-that-play-both-sides">Middleware: Components that Play Both Sides</a></li>
</ul>
</li>
<li><a class="reference internal" href="#specification-details">Specification Details</a><ul>
<li><a class="reference internal" href="#environ-variables"><code class="docutils literal notranslate"><span class="pre">environ</span></code> Variables</a><ul>
<li><a class="reference internal" href="#input-and-error-streams">Input and Error Streams</a></li>
</ul>
</li>
<li><a class="reference internal" href="#the-start-response-callable">The <code class="docutils literal notranslate"><span class="pre">start_response()</span></code> Callable</a><ul>
<li><a class="reference internal" href="#handling-the-content-length-header">Handling the <code class="docutils literal notranslate"><span class="pre">Content-Length</span></code> Header</a></li>
</ul>
</li>
<li><a class="reference internal" href="#buffering-and-streaming">Buffering and Streaming</a><ul>
<li><a class="reference internal" href="#middleware-handling-of-block-boundaries">Middleware Handling of Block Boundaries</a></li>
<li><a class="reference internal" href="#the-write-callable">The <code class="docutils literal notranslate"><span class="pre">write()</span></code> Callable</a></li>
</ul>
</li>
<li><a class="reference internal" href="#unicode-issues">Unicode Issues</a></li>
<li><a class="reference internal" href="#error-handling">Error Handling</a></li>
<li><a class="reference internal" href="#http-1-1-expect-continue">HTTP 1.1 Expect/Continue</a></li>
<li><a class="reference internal" href="#other-http-features">Other HTTP Features</a></li>
<li><a class="reference internal" href="#thread-support">Thread Support</a></li>
</ul>
</li>
<li><a class="reference internal" href="#implementation-application-notes">Implementation/Application Notes</a><ul>
<li><a class="reference internal" href="#server-extension-apis">Server Extension APIs</a></li>
<li><a class="reference internal" href="#application-configuration">Application Configuration</a></li>
<li><a class="reference internal" href="#url-reconstruction">URL Reconstruction</a></li>
<li><a class="reference internal" href="#supporting-older-2-2-versions-of-python">Supporting Older (&lt;2.2) Versions of Python</a></li>
<li><a class="reference internal" href="#optional-platform-specific-file-handling">Optional Platform-Specific File Handling</a></li>
</ul>
</li>
<li><a class="reference internal" href="#questions-and-answers">Questions and Answers</a></li>
<li><a class="reference internal" href="#proposed-under-discussion">Proposed/Under Discussion</a></li>
<li><a class="reference internal" href="#acknowledgements">Acknowledgements</a></li>
<li><a class="reference internal" href="#references">References</a></li>
<li><a class="reference internal" href="#copyright">Copyright</a></li>
</ul>
</details></section>
<section id="preface">
<h2><a class="toc-backref" href="#preface" role="doc-backlink">Preface</a></h2>
<p>Note: For an updated version of this spec that supports Python 3.x and
includes community errata, addenda, and clarifications, please
see <a class="pep reference internal" href="../pep-3333/" title="PEP 3333 Python Web Server Gateway Interface v1.0.1">PEP 3333</a> instead.</p>
</section>
<section id="abstract">
<h2><a class="toc-backref" href="#abstract" role="doc-backlink">Abstract</a></h2>
<p>This document specifies a proposed standard interface between web
servers and Python web applications or frameworks, to promote web
application portability across a variety of web servers.</p>
</section>
<section id="rationale-and-goals">
<h2><a class="toc-backref" href="#rationale-and-goals" role="doc-backlink">Rationale and Goals</a></h2>
<p>Python currently boasts a wide variety of web application frameworks,
such as Zope, Quixote, Webware, SkunkWeb, PSO, and Twisted Web to
name just a few <a class="footnote-reference brackets" href="#id4" id="id1">[1]</a>. This wide variety of choices can be a problem
for new Python users, because generally speaking, their choice of web
framework will limit their choice of usable web servers, and vice
versa.</p>
<p>By contrast, although Java has just as many web application frameworks
available, Javas “servlet” API makes it possible for applications
written with any Java web application framework to run in any web
server that supports the servlet API.</p>
<p>The availability and widespread use of such an API in web servers for
Python whether those servers are written in Python (e.g. Medusa),
embed Python (e.g. mod_python), or invoke Python via a gateway
protocol (e.g. CGI, FastCGI, etc.) would separate choice of
framework from choice of web server, freeing users to choose a pairing
that suits them, while freeing framework and server developers to
focus on their preferred area of specialization.</p>
<p>This PEP, therefore, proposes a simple and universal interface between
web servers and web applications or frameworks: the Python Web Server
Gateway Interface (WSGI).</p>
<p>But the mere existence of a WSGI spec does nothing to address the
existing state of servers and frameworks for Python web applications.
Server and framework authors and maintainers must actually implement
WSGI for there to be any effect.</p>
<p>However, since no existing servers or frameworks support WSGI, there
is little immediate reward for an author who implements WSGI support.
Thus, WSGI <strong>must</strong> be easy to implement, so that an authors initial
investment in the interface can be reasonably low.</p>
<p>Thus, simplicity of implementation on <em>both</em> the server and framework
sides of the interface is absolutely critical to the utility of the
WSGI interface, and is therefore the principal criterion for any
design decisions.</p>
<p>Note, however, that simplicity of implementation for a framework
author is not the same thing as ease of use for a web application
author. WSGI presents an absolutely “no frills” interface to the
framework author, because bells and whistles like response objects and
cookie handling would just get in the way of existing frameworks
handling of these issues. Again, the goal of WSGI is to facilitate
easy interconnection of existing servers and applications or
frameworks, not to create a new web framework.</p>
<p>Note also that this goal precludes WSGI from requiring anything that
is not already available in deployed versions of Python. Therefore,
new standard library modules are not proposed or required by this
specification, and nothing in WSGI requires a Python version greater
than 2.2.2. (It would be a good idea, however, for future versions
of Python to include support for this interface in web servers
provided by the standard library.)</p>
<p>In addition to ease of implementation for existing and future
frameworks and servers, it should also be easy to create request
preprocessors, response postprocessors, and other WSGI-based
“middleware” components that look like an application to their
containing server, while acting as a server for their contained
applications.</p>
<p>If middleware can be both simple and robust, and WSGI is widely
available in servers and frameworks, it allows for the possibility
of an entirely new kind of Python web application framework: one
consisting of loosely-coupled WSGI middleware components. Indeed,
existing framework authors may even choose to refactor their
frameworks existing services to be provided in this way, becoming
more like libraries used with WSGI, and less like monolithic
frameworks. This would then allow application developers to choose
“best-of-breed” components for specific functionality, rather than
having to commit to all the pros and cons of a single framework.</p>
<p>Of course, as of this writing, that day is doubtless quite far off.
In the meantime, it is a sufficient short-term goal for WSGI to
enable the use of any framework with any server.</p>
<p>Finally, it should be mentioned that the current version of WSGI
does not prescribe any particular mechanism for “deploying” an
application for use with a web server or server gateway. At the
present time, this is necessarily implementation-defined by the
server or gateway. After a sufficient number of servers and
frameworks have implemented WSGI to provide field experience with
varying deployment requirements, it may make sense to create
another PEP, describing a deployment standard for WSGI servers and
application frameworks.</p>
</section>
<section id="specification-overview">
<h2><a class="toc-backref" href="#specification-overview" role="doc-backlink">Specification Overview</a></h2>
<p>The WSGI interface has two sides: the “server” or “gateway” side, and
the “application” or “framework” side. The server side invokes a
callable object that is provided by the application side. The
specifics of how that object is provided are up to the server or
gateway. It is assumed that some servers or gateways will require an
applications deployer to write a short script to create an instance
of the server or gateway, and supply it with the application object.
Other servers and gateways may use configuration files or other
mechanisms to specify where an application object should be
imported from, or otherwise obtained.</p>
<p>In addition to “pure” servers/gateways and applications/frameworks,
it is also possible to create “middleware” components that implement
both sides of this specification. Such components act as an
application to their containing server, and as a server to a
contained application, and can be used to provide extended APIs,
content transformation, navigation, and other useful functions.</p>
<p>Throughout this specification, we will use the term “a callable” to
mean “a function, method, class, or an instance with a <code class="docutils literal notranslate"><span class="pre">__call__</span></code>
method”. It is up to the server, gateway, or application implementing
the callable to choose the appropriate implementation technique for
their needs. Conversely, a server, gateway, or application that is
invoking a callable <strong>must not</strong> have any dependency on what kind of
callable was provided to it. Callables are only to be called, not
introspected upon.</p>
<section id="the-application-framework-side">
<h3><a class="toc-backref" href="#the-application-framework-side" role="doc-backlink">The Application/Framework Side</a></h3>
<p>The application object is simply a callable object that accepts
two arguments. The term “object” should not be misconstrued as
requiring an actual object instance: a function, method, class,
or instance with a <code class="docutils literal notranslate"><span class="pre">__call__</span></code> method are all acceptable for
use as an application object. Application objects must be able
to be invoked more than once, as virtually all servers/gateways
(other than CGI) will make such repeated requests.</p>
<p>(Note: although we refer to it as an “application” object, this
should not be construed to mean that application developers will use
WSGI as a web programming API! It is assumed that application
developers will continue to use existing, high-level framework
services to develop their applications. WSGI is a tool for
framework and server developers, and is not intended to directly
support application developers.)</p>
<p>Here are two example application objects; one is a function, and the
other is a class:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">simple_app</span><span class="p">(</span><span class="n">environ</span><span class="p">,</span> <span class="n">start_response</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;Simplest possible application object&quot;&quot;&quot;</span>
<span class="n">status</span> <span class="o">=</span> <span class="s1">&#39;200 OK&#39;</span>
<span class="n">response_headers</span> <span class="o">=</span> <span class="p">[(</span><span class="s1">&#39;Content-type&#39;</span><span class="p">,</span> <span class="s1">&#39;text/plain&#39;</span><span class="p">)]</span>
<span class="n">start_response</span><span class="p">(</span><span class="n">status</span><span class="p">,</span> <span class="n">response_headers</span><span class="p">)</span>
<span class="k">return</span> <span class="p">[</span><span class="s1">&#39;Hello world!</span><span class="se">\n</span><span class="s1">&#39;</span><span class="p">]</span>
<span class="k">class</span> <span class="nc">AppClass</span><span class="p">:</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;Produce the same output, but using a class</span>
<span class="sd"> (Note: &#39;AppClass&#39; is the &quot;application&quot; here, so calling it</span>
<span class="sd"> returns an instance of &#39;AppClass&#39;, which is then the iterable</span>
<span class="sd"> return value of the &quot;application callable&quot; as required by</span>
<span class="sd"> the spec.</span>
<span class="sd"> If we wanted to use *instances* of &#39;AppClass&#39; as application</span>
<span class="sd"> objects instead, we would have to implement a &#39;__call__&#39;</span>
<span class="sd"> method, which would be invoked to execute the application,</span>
<span class="sd"> and we would need to create an instance for use by the</span>
<span class="sd"> server or gateway.</span>
<span class="sd"> &quot;&quot;&quot;</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">environ</span><span class="p">,</span> <span class="n">start_response</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">environ</span> <span class="o">=</span> <span class="n">environ</span>
<span class="bp">self</span><span class="o">.</span><span class="n">start</span> <span class="o">=</span> <span class="n">start_response</span>
<span class="k">def</span> <span class="fm">__iter__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="n">status</span> <span class="o">=</span> <span class="s1">&#39;200 OK&#39;</span>
<span class="n">response_headers</span> <span class="o">=</span> <span class="p">[(</span><span class="s1">&#39;Content-type&#39;</span><span class="p">,</span> <span class="s1">&#39;text/plain&#39;</span><span class="p">)]</span>
<span class="bp">self</span><span class="o">.</span><span class="n">start</span><span class="p">(</span><span class="n">status</span><span class="p">,</span> <span class="n">response_headers</span><span class="p">)</span>
<span class="k">yield</span> <span class="s2">&quot;Hello world!</span><span class="se">\n</span><span class="s2">&quot;</span>
</pre></div>
</div>
</section>
<section id="the-server-gateway-side">
<h3><a class="toc-backref" href="#the-server-gateway-side" role="doc-backlink">The Server/Gateway Side</a></h3>
<p>The server or gateway invokes the application callable once for each
request it receives from an HTTP client, that is directed at the
application. To illustrate, here is a simple CGI gateway, implemented
as a function taking an application object. Note that this simple
example has limited error handling, because by default an uncaught
exception will be dumped to <code class="docutils literal notranslate"><span class="pre">sys.stderr</span></code> and logged by the web
server.</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">os</span><span class="o">,</span> <span class="nn">sys</span>
<span class="k">def</span> <span class="nf">run_with_cgi</span><span class="p">(</span><span class="n">application</span><span class="p">):</span>
<span class="n">environ</span> <span class="o">=</span> <span class="nb">dict</span><span class="p">(</span><span class="n">os</span><span class="o">.</span><span class="n">environ</span><span class="o">.</span><span class="n">items</span><span class="p">())</span>
<span class="n">environ</span><span class="p">[</span><span class="s1">&#39;wsgi.input&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="n">sys</span><span class="o">.</span><span class="n">stdin</span>
<span class="n">environ</span><span class="p">[</span><span class="s1">&#39;wsgi.errors&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="n">sys</span><span class="o">.</span><span class="n">stderr</span>
<span class="n">environ</span><span class="p">[</span><span class="s1">&#39;wsgi.version&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span>
<span class="n">environ</span><span class="p">[</span><span class="s1">&#39;wsgi.multithread&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="kc">False</span>
<span class="n">environ</span><span class="p">[</span><span class="s1">&#39;wsgi.multiprocess&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="kc">True</span>
<span class="n">environ</span><span class="p">[</span><span class="s1">&#39;wsgi.run_once&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="kc">True</span>
<span class="k">if</span> <span class="n">environ</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">&#39;HTTPS&#39;</span><span class="p">,</span> <span class="s1">&#39;off&#39;</span><span class="p">)</span> <span class="ow">in</span> <span class="p">(</span><span class="s1">&#39;on&#39;</span><span class="p">,</span> <span class="s1">&#39;1&#39;</span><span class="p">):</span>
<span class="n">environ</span><span class="p">[</span><span class="s1">&#39;wsgi.url_scheme&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="s1">&#39;https&#39;</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">environ</span><span class="p">[</span><span class="s1">&#39;wsgi.url_scheme&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="s1">&#39;http&#39;</span>
<span class="n">headers_set</span> <span class="o">=</span> <span class="p">[]</span>
<span class="n">headers_sent</span> <span class="o">=</span> <span class="p">[]</span>
<span class="k">def</span> <span class="nf">write</span><span class="p">(</span><span class="n">data</span><span class="p">):</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">headers_set</span><span class="p">:</span>
<span class="k">raise</span> <span class="ne">AssertionError</span><span class="p">(</span><span class="s2">&quot;write() before start_response()&quot;</span><span class="p">)</span>
<span class="k">elif</span> <span class="ow">not</span> <span class="n">headers_sent</span><span class="p">:</span>
<span class="c1"># Before the first output, send the stored headers</span>
<span class="n">status</span><span class="p">,</span> <span class="n">response_headers</span> <span class="o">=</span> <span class="n">headers_sent</span><span class="p">[:]</span> <span class="o">=</span> <span class="n">headers_set</span>
<span class="n">sys</span><span class="o">.</span><span class="n">stdout</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s1">&#39;Status: </span><span class="si">%s</span><span class="se">\r\n</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="n">status</span><span class="p">)</span>
<span class="k">for</span> <span class="n">header</span> <span class="ow">in</span> <span class="n">response_headers</span><span class="p">:</span>
<span class="n">sys</span><span class="o">.</span><span class="n">stdout</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s1">&#39;</span><span class="si">%s</span><span class="s1">: </span><span class="si">%s</span><span class="se">\r\n</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="n">header</span><span class="p">)</span>
<span class="n">sys</span><span class="o">.</span><span class="n">stdout</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s1">&#39;</span><span class="se">\r\n</span><span class="s1">&#39;</span><span class="p">)</span>
<span class="n">sys</span><span class="o">.</span><span class="n">stdout</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="n">sys</span><span class="o">.</span><span class="n">stdout</span><span class="o">.</span><span class="n">flush</span><span class="p">()</span>
<span class="k">def</span> <span class="nf">start_response</span><span class="p">(</span><span class="n">status</span><span class="p">,</span> <span class="n">response_headers</span><span class="p">,</span> <span class="n">exc_info</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
<span class="k">if</span> <span class="n">exc_info</span><span class="p">:</span>
<span class="k">try</span><span class="p">:</span>
<span class="k">if</span> <span class="n">headers_sent</span><span class="p">:</span>
<span class="c1"># Re-raise original exception if headers sent</span>
<span class="k">raise</span> <span class="n">exc_info</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">exc_info</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">exc_info</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span>
<span class="k">finally</span><span class="p">:</span>
<span class="n">exc_info</span> <span class="o">=</span> <span class="kc">None</span> <span class="c1"># avoid dangling circular ref</span>
<span class="k">elif</span> <span class="n">headers_set</span><span class="p">:</span>
<span class="k">raise</span> <span class="ne">AssertionError</span><span class="p">(</span><span class="s2">&quot;Headers already set!&quot;</span><span class="p">)</span>
<span class="n">headers_set</span><span class="p">[:]</span> <span class="o">=</span> <span class="p">[</span><span class="n">status</span><span class="p">,</span> <span class="n">response_headers</span><span class="p">]</span>
<span class="k">return</span> <span class="n">write</span>
<span class="n">result</span> <span class="o">=</span> <span class="n">application</span><span class="p">(</span><span class="n">environ</span><span class="p">,</span> <span class="n">start_response</span><span class="p">)</span>
<span class="k">try</span><span class="p">:</span>
<span class="k">for</span> <span class="n">data</span> <span class="ow">in</span> <span class="n">result</span><span class="p">:</span>
<span class="k">if</span> <span class="n">data</span><span class="p">:</span> <span class="c1"># don&#39;t send headers until body appears</span>
<span class="n">write</span><span class="p">(</span><span class="n">data</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">headers_sent</span><span class="p">:</span>
<span class="n">write</span><span class="p">(</span><span class="s1">&#39;&#39;</span><span class="p">)</span> <span class="c1"># send headers now if body was empty</span>
<span class="k">finally</span><span class="p">:</span>
<span class="k">if</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">result</span><span class="p">,</span> <span class="s1">&#39;close&#39;</span><span class="p">):</span>
<span class="n">result</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
</pre></div>
</div>
</section>
<section id="middleware-components-that-play-both-sides">
<h3><a class="toc-backref" href="#middleware-components-that-play-both-sides" role="doc-backlink">Middleware: Components that Play Both Sides</a></h3>
<p>Note that a single object may play the role of a server with respect
to some application(s), while also acting as an application with
respect to some server(s). Such “middleware” components can perform
such functions as:</p>
<ul class="simple">
<li>Routing a request to different application objects based on the
target URL, after rewriting the <code class="docutils literal notranslate"><span class="pre">environ</span></code> accordingly.</li>
<li>Allowing multiple applications or frameworks to run side by side
in the same process</li>
<li>Load balancing and remote processing, by forwarding requests and
responses over a network</li>
<li>Perform content postprocessing, such as applying XSL stylesheets</li>
</ul>
<p>The presence of middleware in general is transparent to both the
“server/gateway” and the “application/framework” sides of the
interface, and should require no special support. A user who
desires to incorporate middleware into an application simply
provides the middleware component to the server, as if it were
an application, and configures the middleware component to
invoke the application, as if the middleware component were a
server. Of course, the “application” that the middleware wraps
may in fact be another middleware component wrapping another
application, and so on, creating what is referred to as a
“middleware stack”.</p>
<p>For the most part, middleware must conform to the restrictions
and requirements of both the server and application sides of
WSGI. In some cases, however, requirements for middleware
are more stringent than for a “pure” server or application,
and these points will be noted in the specification.</p>
<p>Here is a (tongue-in-cheek) example of a middleware component that
converts <code class="docutils literal notranslate"><span class="pre">text/plain</span></code> responses to pig Latin, using Joe Strouts
<code class="docutils literal notranslate"><span class="pre">piglatin.py</span></code>. (Note: a “real” middleware component would
probably use a more robust way of checking the content type, and
should also check for a content encoding. Also, this simple
example ignores the possibility that a word might be split across
a block boundary.)</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">piglatin</span> <span class="kn">import</span> <span class="n">piglatin</span>
<span class="k">class</span> <span class="nc">LatinIter</span><span class="p">:</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;Transform iterated output to piglatin, if it&#39;s okay to do so</span>
<span class="sd"> Note that the &quot;okayness&quot; can change until the application yields</span>
<span class="sd"> its first non-empty string, so &#39;transform_ok&#39; has to be a mutable</span>
<span class="sd"> truth value.</span>
<span class="sd"> &quot;&quot;&quot;</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">result</span><span class="p">,</span> <span class="n">transform_ok</span><span class="p">):</span>
<span class="k">if</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">result</span><span class="p">,</span> <span class="s1">&#39;close&#39;</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">close</span> <span class="o">=</span> <span class="n">result</span><span class="o">.</span><span class="n">close</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_next</span> <span class="o">=</span> <span class="nb">iter</span><span class="p">(</span><span class="n">result</span><span class="p">)</span><span class="o">.</span><span class="n">next</span>
<span class="bp">self</span><span class="o">.</span><span class="n">transform_ok</span> <span class="o">=</span> <span class="n">transform_ok</span>
<span class="k">def</span> <span class="fm">__iter__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">return</span> <span class="bp">self</span>
<span class="k">def</span> <span class="nf">next</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">transform_ok</span><span class="p">:</span>
<span class="k">return</span> <span class="n">piglatin</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_next</span><span class="p">())</span>
<span class="k">else</span><span class="p">:</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_next</span><span class="p">()</span>
<span class="k">class</span> <span class="nc">Latinator</span><span class="p">:</span>
<span class="c1"># by default, don&#39;t transform output</span>
<span class="n">transform</span> <span class="o">=</span> <span class="kc">False</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">application</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">application</span> <span class="o">=</span> <span class="n">application</span>
<span class="k">def</span> <span class="fm">__call__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">environ</span><span class="p">,</span> <span class="n">start_response</span><span class="p">):</span>
<span class="n">transform_ok</span> <span class="o">=</span> <span class="p">[]</span>
<span class="k">def</span> <span class="nf">start_latin</span><span class="p">(</span><span class="n">status</span><span class="p">,</span> <span class="n">response_headers</span><span class="p">,</span> <span class="n">exc_info</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
<span class="c1"># Reset ok flag, in case this is a repeat call</span>
<span class="k">del</span> <span class="n">transform_ok</span><span class="p">[:]</span>
<span class="k">for</span> <span class="n">name</span><span class="p">,</span> <span class="n">value</span> <span class="ow">in</span> <span class="n">response_headers</span><span class="p">:</span>
<span class="k">if</span> <span class="n">name</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span> <span class="o">==</span> <span class="s1">&#39;content-type&#39;</span> <span class="ow">and</span> <span class="n">value</span> <span class="o">==</span> <span class="s1">&#39;text/plain&#39;</span><span class="p">:</span>
<span class="n">transform_ok</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="kc">True</span><span class="p">)</span>
<span class="c1"># Strip content-length if present, else it&#39;ll be wrong</span>
<span class="n">response_headers</span> <span class="o">=</span> <span class="p">[(</span><span class="n">name</span><span class="p">,</span> <span class="n">value</span><span class="p">)</span>
<span class="k">for</span> <span class="n">name</span><span class="p">,</span> <span class="n">value</span> <span class="ow">in</span> <span class="n">response_headers</span>
<span class="k">if</span> <span class="n">name</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span> <span class="o">!=</span> <span class="s1">&#39;content-length&#39;</span>
<span class="p">]</span>
<span class="k">break</span>
<span class="n">write</span> <span class="o">=</span> <span class="n">start_response</span><span class="p">(</span><span class="n">status</span><span class="p">,</span> <span class="n">response_headers</span><span class="p">,</span> <span class="n">exc_info</span><span class="p">)</span>
<span class="k">if</span> <span class="n">transform_ok</span><span class="p">:</span>
<span class="k">def</span> <span class="nf">write_latin</span><span class="p">(</span><span class="n">data</span><span class="p">):</span>
<span class="n">write</span><span class="p">(</span><span class="n">piglatin</span><span class="p">(</span><span class="n">data</span><span class="p">))</span>
<span class="k">return</span> <span class="n">write_latin</span>
<span class="k">else</span><span class="p">:</span>
<span class="k">return</span> <span class="n">write</span>
<span class="k">return</span> <span class="n">LatinIter</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">application</span><span class="p">(</span><span class="n">environ</span><span class="p">,</span> <span class="n">start_latin</span><span class="p">),</span> <span class="n">transform_ok</span><span class="p">)</span>
<span class="c1"># Run foo_app under a Latinator&#39;s control, using the example CGI gateway</span>
<span class="kn">from</span> <span class="nn">foo_app</span> <span class="kn">import</span> <span class="n">foo_app</span>
<span class="n">run_with_cgi</span><span class="p">(</span><span class="n">Latinator</span><span class="p">(</span><span class="n">foo_app</span><span class="p">))</span>
</pre></div>
</div>
</section>
</section>
<section id="specification-details">
<h2><a class="toc-backref" href="#specification-details" role="doc-backlink">Specification Details</a></h2>
<p>The application object must accept two positional arguments. For
the sake of illustration, we have named them <code class="docutils literal notranslate"><span class="pre">environ</span></code> and
<code class="docutils literal notranslate"><span class="pre">start_response</span></code>, but they are not required to have these names.
A server or gateway <strong>must</strong> invoke the application object using
positional (not keyword) arguments. (E.g. by calling
<code class="docutils literal notranslate"><span class="pre">result</span> <span class="pre">=</span> <span class="pre">application(environ,</span> <span class="pre">start_response)</span></code> as shown above.)</p>
<p>The <code class="docutils literal notranslate"><span class="pre">environ</span></code> parameter is a dictionary object, containing CGI-style
environment variables. This object <strong>must</strong> be a builtin Python
dictionary (<em>not</em> a subclass, <code class="docutils literal notranslate"><span class="pre">UserDict</span></code> or other dictionary
emulation), and the application is allowed to modify the dictionary
in any way it desires. The dictionary must also include certain
WSGI-required variables (described in a later section), and may
also include server-specific extension variables, named according
to a convention that will be described below.</p>
<p>The <code class="docutils literal notranslate"><span class="pre">start_response</span></code> parameter is a callable accepting two
required positional arguments, and one optional argument. For the sake
of illustration, we have named these arguments <code class="docutils literal notranslate"><span class="pre">status</span></code>,
<code class="docutils literal notranslate"><span class="pre">response_headers</span></code>, and <code class="docutils literal notranslate"><span class="pre">exc_info</span></code>, but they are not required to
have these names, and the application <strong>must</strong> invoke the
<code class="docutils literal notranslate"><span class="pre">start_response</span></code> callable using positional arguments (e.g.
<code class="docutils literal notranslate"><span class="pre">start_response(status,</span> <span class="pre">response_headers)</span></code>).</p>
<p>The <code class="docutils literal notranslate"><span class="pre">status</span></code> parameter is a status string of the form
<code class="docutils literal notranslate"><span class="pre">&quot;999</span> <span class="pre">Message</span> <span class="pre">here&quot;</span></code>, and <code class="docutils literal notranslate"><span class="pre">response_headers</span></code> is a list of
<code class="docutils literal notranslate"><span class="pre">(header_name,</span> <span class="pre">header_value)</span></code> tuples describing the HTTP response
header. The optional <code class="docutils literal notranslate"><span class="pre">exc_info</span></code> parameter is described below in the
sections on <a class="reference internal" href="#the-start-response-callable">The start_response() Callable</a> and <a class="reference internal" href="#error-handling">Error Handling</a>.
It is used only when the application has trapped an error and is
attempting to display an error message to the browser.</p>
<p>The <code class="docutils literal notranslate"><span class="pre">start_response</span></code> callable must return a <code class="docutils literal notranslate"><span class="pre">write(body_data)</span></code>
callable that takes one positional parameter: a string to be written
as part of the HTTP response body. (Note: the <code class="docutils literal notranslate"><span class="pre">write()</span></code> callable is
provided only to support certain existing frameworks imperative output
APIs; it should not be used by new applications or frameworks if it
can be avoided. See the <a class="reference internal" href="#buffering-and-streaming">Buffering and Streaming</a> section for more
details.)</p>
<p>When called by the server, the application object must return an
iterable yielding zero or more strings. This can be accomplished in a
variety of ways, such as by returning a list of strings, or by the
application being a generator function that yields strings, or
by the application being a class whose instances are iterable.
Regardless of how it is accomplished, the application object must
always return an iterable yielding zero or more strings.</p>
<p>The server or gateway must transmit the yielded strings to the client
in an unbuffered fashion, completing the transmission of each string
before requesting another one. (In other words, applications
<strong>should</strong> perform their own buffering. See the <a class="reference internal" href="#buffering-and-streaming">Buffering and
Streaming</a> section below for more on how application output must be
handled.)</p>
<p>The server or gateway should treat the yielded strings as binary byte
sequences: in particular, it should ensure that line endings are
not altered. The application is responsible for ensuring that the
string(s) to be written are in a format suitable for the client. (The
server or gateway <strong>may</strong> apply HTTP transfer encodings, or perform
other transformations for the purpose of implementing HTTP features
such as byte-range transmission. See <a class="reference internal" href="#other-http-features">Other HTTP Features</a>, below,
for more details.)</p>
<p>If a call to <code class="docutils literal notranslate"><span class="pre">len(iterable)</span></code> succeeds, the server must be able
to rely on the result being accurate. That is, if the iterable
returned by the application provides a working <code class="docutils literal notranslate"><span class="pre">__len__()</span></code>
method, it <strong>must</strong> return an accurate result. (See
the <a class="reference internal" href="#handling-the-content-length-header">Handling the Content-Length Header</a> section for information
on how this would normally be used.)</p>
<p>If the iterable returned by the application has a <code class="docutils literal notranslate"><span class="pre">close()</span></code> method,
the server or gateway <strong>must</strong> call that method upon completion of the
current request, whether the request was completed normally, or
terminated early due to an error (this is to support resource release
by the application). This protocol is intended to complement <a class="pep reference internal" href="../pep-0325/" title="PEP 325 Resource-Release Support for Generators">PEP 325</a>s
generator support, and other common iterables with <code class="docutils literal notranslate"><span class="pre">close()</span></code> methods.</p>
<p>(Note: the application <strong>must</strong> invoke the <code class="docutils literal notranslate"><span class="pre">start_response()</span></code>
callable before the iterable yields its first body string, so that the
server can send the headers before any body content. However, this
invocation <strong>may</strong> be performed by the iterables first iteration, so
servers <strong>must not</strong> assume that <code class="docutils literal notranslate"><span class="pre">start_response()</span></code> has been called
before they begin iterating over the iterable.)</p>
<p>Finally, servers and gateways <strong>must not</strong> directly use any other
attributes of the iterable returned by the application, unless it is an
instance of a type specific to that server or gateway, such as a “file
wrapper” returned by <code class="docutils literal notranslate"><span class="pre">wsgi.file_wrapper</span></code> (see <a class="reference internal" href="#optional-platform-specific-file-handling">Optional
Platform-Specific File Handling</a>). In the general case, only
attributes specified here, or accessed via e.g. the <a class="pep reference internal" href="../pep-0234/" title="PEP 234 Iterators">PEP 234</a> iteration
APIs are acceptable.</p>
<section id="environ-variables">
<h3><a class="toc-backref" href="#environ-variables" role="doc-backlink"><code class="docutils literal notranslate"><span class="pre">environ</span></code> Variables</a></h3>
<p>The <code class="docutils literal notranslate"><span class="pre">environ</span></code> dictionary is required to contain these CGI
environment variables, as defined by the Common Gateway Interface
specification <a class="footnote-reference brackets" href="#id5" id="id2">[2]</a>. The following variables <strong>must</strong> be present,
unless their value would be an empty string, in which case they
<strong>may</strong> be omitted, except as otherwise noted below.</p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">REQUEST_METHOD</span></code></dt><dd>The HTTP request method, such as <code class="docutils literal notranslate"><span class="pre">&quot;GET&quot;</span></code> or <code class="docutils literal notranslate"><span class="pre">&quot;POST&quot;</span></code>. This
cannot ever be an empty string, and so is always required.</dd>
<dt><code class="docutils literal notranslate"><span class="pre">SCRIPT_NAME</span></code></dt><dd>The initial portion of the request URLs “path” that corresponds to
the application object, so that the application knows its virtual
“location”. This <strong>may</strong> be an empty string, if the application
corresponds to the “root” of the server.</dd>
<dt><code class="docutils literal notranslate"><span class="pre">PATH_INFO</span></code></dt><dd>The remainder of the request URLs “path”, designating the virtual
“location” of the requests target within the application. This
<strong>may</strong> be an empty string, if the request URL targets the
application root and does not have a trailing slash.</dd>
<dt><code class="docutils literal notranslate"><span class="pre">QUERY_STRING</span></code></dt><dd>The portion of the request URL that follows the <code class="docutils literal notranslate"><span class="pre">&quot;?&quot;</span></code>, if any.
May be empty or absent.</dd>
<dt><code class="docutils literal notranslate"><span class="pre">CONTENT_TYPE</span></code></dt><dd>The contents of any <code class="docutils literal notranslate"><span class="pre">Content-Type</span></code> fields in the HTTP request.
May be empty or absent.</dd>
<dt><code class="docutils literal notranslate"><span class="pre">CONTENT_LENGTH</span></code></dt><dd>The contents of any <code class="docutils literal notranslate"><span class="pre">Content-Length</span></code> fields in the HTTP request.
May be empty or absent.</dd>
<dt><code class="docutils literal notranslate"><span class="pre">SERVER_NAME</span></code>, <code class="docutils literal notranslate"><span class="pre">SERVER_PORT</span></code></dt><dd>When combined with <code class="docutils literal notranslate"><span class="pre">SCRIPT_NAME</span></code> and <code class="docutils literal notranslate"><span class="pre">PATH_INFO</span></code>, these variables
can be used to complete the URL. Note, however, that <code class="docutils literal notranslate"><span class="pre">HTTP_HOST</span></code>,
if present, should be used in preference to <code class="docutils literal notranslate"><span class="pre">SERVER_NAME</span></code> for
reconstructing the request URL. See the <a class="reference internal" href="#url-reconstruction">URL Reconstruction</a>
section below for more detail. <code class="docutils literal notranslate"><span class="pre">SERVER_NAME</span></code> and <code class="docutils literal notranslate"><span class="pre">SERVER_PORT</span></code>
can never be empty strings, and so are always required.</dd>
<dt><code class="docutils literal notranslate"><span class="pre">SERVER_PROTOCOL</span></code></dt><dd>The version of the protocol the client used to send the request.
Typically this will be something like <code class="docutils literal notranslate"><span class="pre">&quot;HTTP/1.0&quot;</span></code> or <code class="docutils literal notranslate"><span class="pre">&quot;HTTP/1.1&quot;</span></code>
and may be used by the application to determine how to treat any
HTTP request headers. (This variable should probably be called
<code class="docutils literal notranslate"><span class="pre">REQUEST_PROTOCOL</span></code>, since it denotes the protocol used in the
request, and is not necessarily the protocol that will be used in the
servers response. However, for compatibility with CGI we have to
keep the existing name.)</dd>
<dt><code class="docutils literal notranslate"><span class="pre">HTTP_</span></code> Variables</dt><dd>Variables corresponding to the client-supplied HTTP request headers
(i.e., variables whose names begin with <code class="docutils literal notranslate"><span class="pre">&quot;HTTP_&quot;</span></code>). The presence or
absence of these variables should correspond with the presence or
absence of the appropriate HTTP header in the request.</dd>
</dl>
<p>A server or gateway <strong>should</strong> attempt to provide as many other CGI
variables as are applicable. In addition, if SSL is in use, the server
or gateway <strong>should</strong> also provide as many of the Apache SSL environment
variables <a class="footnote-reference brackets" href="#id6" id="id3">[3]</a> as are applicable, such as <code class="docutils literal notranslate"><span class="pre">HTTPS=on</span></code> and
<code class="docutils literal notranslate"><span class="pre">SSL_PROTOCOL</span></code>. Note, however, that an application that uses any CGI
variables other than the ones listed above are necessarily non-portable
to web servers that do not support the relevant extensions. (For
example, web servers that do not publish files will not be able to
provide a meaningful <code class="docutils literal notranslate"><span class="pre">DOCUMENT_ROOT</span></code> or <code class="docutils literal notranslate"><span class="pre">PATH_TRANSLATED</span></code>.)</p>
<p>A WSGI-compliant server or gateway <strong>should</strong> document what variables
it provides, along with their definitions as appropriate. Applications
<strong>should</strong> check for the presence of any variables they require, and
have a fallback plan in the event such a variable is absent.</p>
<p>Note: missing variables (such as <code class="docutils literal notranslate"><span class="pre">REMOTE_USER</span></code> when no
authentication has occurred) should be left out of the <code class="docutils literal notranslate"><span class="pre">environ</span></code>
dictionary. Also note that CGI-defined variables must be strings,
if they are present at all. It is a violation of this specification
for a CGI variables value to be of any type other than <code class="docutils literal notranslate"><span class="pre">str</span></code>.</p>
<p>In addition to the CGI-defined variables, the <code class="docutils literal notranslate"><span class="pre">environ</span></code> dictionary
<strong>may</strong> also contain arbitrary operating-system “environment variables”,
and <strong>must</strong> contain the following WSGI-defined variables:</p>
<table class="docutils align-default">
<thead>
<tr class="row-odd"><th class="head">Variable</th>
<th class="head">Value</th>
</tr>
</thead>
<tbody>
<tr class="row-even"><td><code class="docutils literal notranslate"><span class="pre">wsgi.version</span></code></td>
<td>The tuple <code class="docutils literal notranslate"><span class="pre">(1,</span> <span class="pre">0)</span></code>, representing WSGI
version 1.0.</td>
</tr>
<tr class="row-odd"><td><code class="docutils literal notranslate"><span class="pre">wsgi.url_scheme</span></code></td>
<td>A string representing the “scheme” portion of
the URL at which the application is being
invoked. Normally, this will have the value
<code class="docutils literal notranslate"><span class="pre">&quot;http&quot;</span></code> or <code class="docutils literal notranslate"><span class="pre">&quot;https&quot;</span></code>, as appropriate.</td>
</tr>
<tr class="row-even"><td><code class="docutils literal notranslate"><span class="pre">wsgi.input</span></code></td>
<td>An input stream (file-like object) from which
the HTTP request body can be read. (The server
or gateway may perform reads on-demand as
requested by the application, or it may
pre-read the clients request body and buffer
it in-memory or on disk, or use any other
technique for providing such an input stream,
according to its preference.)</td>
</tr>
<tr class="row-odd"><td><code class="docutils literal notranslate"><span class="pre">wsgi.errors</span></code></td>
<td>An output stream (file-like object) to which
error output can be written, for the purpose of
recording program or other errors in a
standardized and possibly centralized location.
This should be a “text mode” stream; i.e.,
applications should use <code class="docutils literal notranslate"><span class="pre">&quot;\n&quot;</span></code> as a line
ending, and assume that it will be converted to
the correct line ending by the server/gateway.<p>For many servers, <code class="docutils literal notranslate"><span class="pre">wsgi.errors</span></code> will be the
servers main error log. Alternatively, this
may be <code class="docutils literal notranslate"><span class="pre">sys.stderr</span></code>, or a log file of some
sort. The servers documentation should
include an explanation of how to configure this
or where to find the recorded output. A server
or gateway may supply different error streams
to different applications, if this is desired.</p>
</td>
</tr>
<tr class="row-even"><td><code class="docutils literal notranslate"><span class="pre">wsgi.multithread</span></code></td>
<td>This value should evaluate true if the
application object may be simultaneously
invoked by another thread in the same process,
and should evaluate false otherwise.</td>
</tr>
<tr class="row-odd"><td><code class="docutils literal notranslate"><span class="pre">wsgi.multiprocess</span></code></td>
<td>This value should evaluate true if an
equivalent application object may be
simultaneously invoked by another process,
and should evaluate false otherwise.</td>
</tr>
<tr class="row-even"><td><code class="docutils literal notranslate"><span class="pre">wsgi.run_once</span></code></td>
<td>This value should evaluate true if the server
or gateway expects (but does not guarantee!)
that the application will only be invoked this
one time during the life of its containing
process. Normally, this will only be true for
a gateway based on CGI (or something similar).</td>
</tr>
</tbody>
</table>
<p>Finally, the <code class="docutils literal notranslate"><span class="pre">environ</span></code> dictionary may also contain server-defined
variables. These variables should be named using only lower-case
letters, numbers, dots, and underscores, and should be prefixed with
a name that is unique to the defining server or gateway. For
example, <code class="docutils literal notranslate"><span class="pre">mod_python</span></code> might define variables with names like
<code class="docutils literal notranslate"><span class="pre">mod_python.some_variable</span></code>.</p>
<section id="input-and-error-streams">
<h4><a class="toc-backref" href="#input-and-error-streams" role="doc-backlink">Input and Error Streams</a></h4>
<p>The input and error streams provided by the server must support
the following methods:</p>
<table class="docutils align-default">
<thead>
<tr class="row-odd"><th class="head">Method</th>
<th class="head">Stream</th>
<th class="head">Notes</th>
</tr>
</thead>
<tbody>
<tr class="row-even"><td><code class="docutils literal notranslate"><span class="pre">read(size)</span></code></td>
<td><code class="docutils literal notranslate"><span class="pre">input</span></code></td>
<td>1</td>
</tr>
<tr class="row-odd"><td><code class="docutils literal notranslate"><span class="pre">readline()</span></code></td>
<td><code class="docutils literal notranslate"><span class="pre">input</span></code></td>
<td>1, 2</td>
</tr>
<tr class="row-even"><td><code class="docutils literal notranslate"><span class="pre">readlines(hint)</span></code></td>
<td><code class="docutils literal notranslate"><span class="pre">input</span></code></td>
<td>1, 3</td>
</tr>
<tr class="row-odd"><td><code class="docutils literal notranslate"><span class="pre">__iter__()</span></code></td>
<td><code class="docutils literal notranslate"><span class="pre">input</span></code></td>
<td></td>
</tr>
<tr class="row-even"><td><code class="docutils literal notranslate"><span class="pre">flush()</span></code></td>
<td><code class="docutils literal notranslate"><span class="pre">errors</span></code></td>
<td>4</td>
</tr>
<tr class="row-odd"><td><code class="docutils literal notranslate"><span class="pre">write(str)</span></code></td>
<td><code class="docutils literal notranslate"><span class="pre">errors</span></code></td>
<td></td>
</tr>
<tr class="row-even"><td><code class="docutils literal notranslate"><span class="pre">writelines(seq)</span></code></td>
<td><code class="docutils literal notranslate"><span class="pre">errors</span></code></td>
<td></td>
</tr>
</tbody>
</table>
<p>The semantics of each method are as documented in the Python Library
Reference, except for these notes as listed in the table above:</p>
<ol class="arabic simple">
<li>The server is not required to read past the clients specified
<code class="docutils literal notranslate"><span class="pre">Content-Length</span></code>, and is allowed to simulate an end-of-file
condition if the application attempts to read past that point.
The application <strong>should not</strong> attempt to read more data than is
specified by the <code class="docutils literal notranslate"><span class="pre">CONTENT_LENGTH</span></code> variable.</li>
<li>The optional “size” argument to <code class="docutils literal notranslate"><span class="pre">readline()</span></code> is not supported,
as it may be complex for server authors to implement, and is not
often used in practice.</li>
<li>Note that the <code class="docutils literal notranslate"><span class="pre">hint</span></code> argument to <code class="docutils literal notranslate"><span class="pre">readlines()</span></code> is optional for
both caller and implementer. The application is free not to
supply it, and the server or gateway is free to ignore it.</li>
<li>Since the <code class="docutils literal notranslate"><span class="pre">errors</span></code> stream may not be rewound, servers and gateways
are free to forward write operations immediately, without buffering.
In this case, the <code class="docutils literal notranslate"><span class="pre">flush()</span></code> method may be a no-op. Portable
applications, however, cannot assume that output is unbuffered
or that <code class="docutils literal notranslate"><span class="pre">flush()</span></code> is a no-op. They must call <code class="docutils literal notranslate"><span class="pre">flush()</span></code> if
they need to ensure that output has in fact been written. (For
example, to minimize intermingling of data from multiple processes
writing to the same error log.)</li>
</ol>
<p>The methods listed in the table above <strong>must</strong> be supported by all
servers conforming to this specification. Applications conforming
to this specification <strong>must not</strong> use any other methods or attributes
of the <code class="docutils literal notranslate"><span class="pre">input</span></code> or <code class="docutils literal notranslate"><span class="pre">errors</span></code> objects. In particular, applications
<strong>must not</strong> attempt to close these streams, even if they possess
<code class="docutils literal notranslate"><span class="pre">close()</span></code> methods.</p>
</section>
</section>
<section id="the-start-response-callable">
<h3><a class="toc-backref" href="#the-start-response-callable" role="doc-backlink">The <code class="docutils literal notranslate"><span class="pre">start_response()</span></code> Callable</a></h3>
<p>The second parameter passed to the application object is a callable
of the form <code class="docutils literal notranslate"><span class="pre">start_response(status,</span> <span class="pre">response_headers,</span> <span class="pre">exc_info=None)</span></code>.
(As with all WSGI callables, the arguments must be supplied
positionally, not by keyword.) The <code class="docutils literal notranslate"><span class="pre">start_response</span></code> callable is
used to begin the HTTP response, and it must return a
<code class="docutils literal notranslate"><span class="pre">write(body_data)</span></code> callable (see the <a class="reference internal" href="#buffering-and-streaming">Buffering and Streaming</a>
section, below).</p>
<p>The <code class="docutils literal notranslate"><span class="pre">status</span></code> argument is an HTTP “status” string like <code class="docutils literal notranslate"><span class="pre">&quot;200</span> <span class="pre">OK&quot;</span></code>
or <code class="docutils literal notranslate"><span class="pre">&quot;404</span> <span class="pre">Not</span> <span class="pre">Found&quot;</span></code>. That is, it is a string consisting of a
Status-Code and a Reason-Phrase, in that order and separated by a
single space, with no surrounding whitespace or other characters.
(See <span class="target" id="index-0"></span><a class="rfc reference external" href="https://datatracker.ietf.org/doc/html/rfc2616.html"><strong>RFC 2616</strong></a>, Section 6.1.1 for more information.) The string
<strong>must not</strong> contain control characters, and must not be terminated
with a carriage return, linefeed, or combination thereof.</p>
<p>The <code class="docutils literal notranslate"><span class="pre">response_headers</span></code> argument is a list of <code class="docutils literal notranslate"><span class="pre">(header_name,</span>
<span class="pre">header_value)</span></code> tuples. It must be a Python list; i.e.
<code class="docutils literal notranslate"><span class="pre">type(response_headers)</span> <span class="pre">is</span> <span class="pre">ListType</span></code>, and the server <strong>may</strong> change
its contents in any way it desires. Each <code class="docutils literal notranslate"><span class="pre">header_name</span></code> must be a
valid HTTP header field-name (as defined by <span class="target" id="index-1"></span><a class="rfc reference external" href="https://datatracker.ietf.org/doc/html/rfc2616.html"><strong>RFC 2616</strong></a>, Section 4.2),
without a trailing colon or other punctuation.</p>
<p>Each <code class="docutils literal notranslate"><span class="pre">header_value</span></code> <strong>must not</strong> include <em>any</em> control characters,
including carriage returns or linefeeds, either embedded or at the end.
(These requirements are to minimize the complexity of any parsing that
must be performed by servers, gateways, and intermediate response
processors that need to inspect or modify response headers.)</p>
<p>In general, the server or gateway is responsible for ensuring that
correct headers are sent to the client: if the application omits
a header required by HTTP (or other relevant specifications that are in
effect), the server or gateway <strong>must</strong> add it. For example, the HTTP
<code class="docutils literal notranslate"><span class="pre">Date:</span></code> and <code class="docutils literal notranslate"><span class="pre">Server:</span></code> headers would normally be supplied by the
server or gateway.</p>
<p>(A reminder for server/gateway authors: HTTP header names are
case-insensitive, so be sure to take that into consideration when
examining application-supplied headers!)</p>
<p>Applications and middleware are forbidden from using HTTP/1.1
“hop-by-hop” features or headers, any equivalent features in HTTP/1.0,
or any headers that would affect the persistence of the clients
connection to the web server. These features are the
exclusive province of the actual web server, and a server or gateway
<strong>should</strong> consider it a fatal error for an application to attempt
sending them, and raise an error if they are supplied to
<code class="docutils literal notranslate"><span class="pre">start_response()</span></code>. (For more specifics on “hop-by-hop” features and
headers, please see the <a class="reference internal" href="#other-http-features">Other HTTP Features</a> section below.)</p>
<p>The <code class="docutils literal notranslate"><span class="pre">start_response</span></code> callable <strong>must not</strong> actually transmit the
response headers. Instead, it must store them for the server or
gateway to transmit <strong>only</strong> after the first iteration of the
application return value that yields a non-empty string, or upon
the applications first invocation of the <code class="docutils literal notranslate"><span class="pre">write()</span></code> callable. In
other words, response headers must not be sent until there is actual
body data available, or until the applications returned iterable is
exhausted. (The only possible exception to this rule is if the
response headers explicitly include a <code class="docutils literal notranslate"><span class="pre">Content-Length</span></code> of zero.)</p>
<p>This delaying of response header transmission is to ensure that buffered
and asynchronous applications can replace their originally intended
output with error output, up until the last possible moment. For
example, the application may need to change the response status from
“200 OK” to “500 Internal Error”, if an error occurs while the body is
being generated within an application buffer.</p>
<p>The <code class="docutils literal notranslate"><span class="pre">exc_info</span></code> argument, if supplied, must be a Python
<code class="docutils literal notranslate"><span class="pre">sys.exc_info()</span></code> tuple. This argument should be supplied by the
application only if <code class="docutils literal notranslate"><span class="pre">start_response</span></code> is being called by an error
handler. If <code class="docutils literal notranslate"><span class="pre">exc_info</span></code> is supplied, and no HTTP headers have been
output yet, <code class="docutils literal notranslate"><span class="pre">start_response</span></code> should replace the currently-stored
HTTP response headers with the newly-supplied ones, thus allowing the
application to “change its mind” about the output when an error has
occurred.</p>
<p>However, if <code class="docutils literal notranslate"><span class="pre">exc_info</span></code> is provided, and the HTTP headers have already
been sent, <code class="docutils literal notranslate"><span class="pre">start_response</span></code> <strong>must</strong> raise an error, and <strong>should</strong>
raise the <code class="docutils literal notranslate"><span class="pre">exc_info</span></code> tuple. That is:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">raise</span> <span class="n">exc_info</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">exc_info</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">exc_info</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span>
</pre></div>
</div>
<p>This will re-raise the exception trapped by the application, and in
principle should abort the application. (It is not safe for the
application to attempt error output to the browser once the HTTP
headers have already been sent.) The application <strong>must not</strong> trap
any exceptions raised by <code class="docutils literal notranslate"><span class="pre">start_response</span></code>, if it called
<code class="docutils literal notranslate"><span class="pre">start_response</span></code> with <code class="docutils literal notranslate"><span class="pre">exc_info</span></code>. Instead, it should allow
such exceptions to propagate back to the server or gateway. See
<a class="reference internal" href="#error-handling">Error Handling</a> below, for more details.</p>
<p>The application <strong>may</strong> call <code class="docutils literal notranslate"><span class="pre">start_response</span></code> more than once, if and
only if the <code class="docutils literal notranslate"><span class="pre">exc_info</span></code> argument is provided. More precisely, it is
a fatal error to call <code class="docutils literal notranslate"><span class="pre">start_response</span></code> without the <code class="docutils literal notranslate"><span class="pre">exc_info</span></code>
argument if <code class="docutils literal notranslate"><span class="pre">start_response</span></code> has already been called within the
current invocation of the application. (See the example CGI
gateway above for an illustration of the correct logic.)</p>
<p>Note: servers, gateways, or middleware implementing <code class="docutils literal notranslate"><span class="pre">start_response</span></code>
<strong>should</strong> ensure that no reference is held to the <code class="docutils literal notranslate"><span class="pre">exc_info</span></code>
parameter beyond the duration of the functions execution, to avoid
creating a circular reference through the traceback and frames
involved. The simplest way to do this is something like:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">start_response</span><span class="p">(</span><span class="n">status</span><span class="p">,</span> <span class="n">response_headers</span><span class="p">,</span> <span class="n">exc_info</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
<span class="k">if</span> <span class="n">exc_info</span><span class="p">:</span>
<span class="k">try</span><span class="p">:</span>
<span class="c1"># do stuff w/exc_info here</span>
<span class="k">finally</span><span class="p">:</span>
<span class="n">exc_info</span> <span class="o">=</span> <span class="kc">None</span> <span class="c1"># Avoid circular ref.</span>
</pre></div>
</div>
<p>The example CGI gateway provides another illustration of this
technique.</p>
<section id="handling-the-content-length-header">
<h4><a class="toc-backref" href="#handling-the-content-length-header" role="doc-backlink">Handling the <code class="docutils literal notranslate"><span class="pre">Content-Length</span></code> Header</a></h4>
<p>If the application does not supply a <code class="docutils literal notranslate"><span class="pre">Content-Length</span></code> header, a
server or gateway may choose one of several approaches to handling
it. The simplest of these is to close the client connection when
the response is completed.</p>
<p>Under some circumstances, however, the server or gateway may be
able to either generate a <code class="docutils literal notranslate"><span class="pre">Content-Length</span></code> header, or at least
avoid the need to close the client connection. If the application
does <em>not</em> call the <code class="docutils literal notranslate"><span class="pre">write()</span></code> callable, and returns an iterable
whose <code class="docutils literal notranslate"><span class="pre">len()</span></code> is 1, then the server can automatically determine
<code class="docutils literal notranslate"><span class="pre">Content-Length</span></code> by taking the length of the first string yielded
by the iterable.</p>
<p>And, if the server and client both support HTTP/1.1
<span class="target" id="index-2"></span><a class="rfc reference external" href="https://datatracker.ietf.org/doc/html/rfc2616.html#section-3.6.1"><strong>“chunked encoding”</strong></a>,
then the server <strong>may</strong> use chunked encoding to send
a chunk for each <code class="docutils literal notranslate"><span class="pre">write()</span></code> call or string yielded by the iterable,
thus generating a <code class="docutils literal notranslate"><span class="pre">Content-Length</span></code> header for each chunk. This
allows the server to keep the client connection alive, if it wishes
to do so. Note that the server <strong>must</strong> comply fully with <span class="target" id="index-3"></span><a class="rfc reference external" href="https://datatracker.ietf.org/doc/html/rfc2616.html"><strong>RFC 2616</strong></a>
when doing this, or else fall back to one of the other strategies for
dealing with the absence of <code class="docutils literal notranslate"><span class="pre">Content-Length</span></code>.</p>
<p>(Note: applications and middleware <strong>must not</strong> apply any kind of
<code class="docutils literal notranslate"><span class="pre">Transfer-Encoding</span></code> to their output, such as chunking or gzipping;
as “hop-by-hop” operations, these encodings are the province of the
actual web server/gateway. See <a class="reference internal" href="#other-http-features">Other HTTP Features</a> below, for
more details.)</p>
</section>
</section>
<section id="buffering-and-streaming">
<h3><a class="toc-backref" href="#buffering-and-streaming" role="doc-backlink">Buffering and Streaming</a></h3>
<p>Generally speaking, applications will achieve the best throughput
by buffering their (modestly-sized) output and sending it all at
once. This is a common approach in existing frameworks such as
Zope: the output is buffered in a StringIO or similar object, then
transmitted all at once, along with the response headers.</p>
<p>The corresponding approach in WSGI is for the application to simply
return a single-element iterable (such as a list) containing the
response body as a single string. This is the recommended approach
for the vast majority of application functions, that render
HTML pages whose text easily fits in memory.</p>
<p>For large files, however, or for specialized uses of HTTP streaming
(such as multipart “server push”), an application may need to provide
output in smaller blocks (e.g. to avoid loading a large file into
memory). Its also sometimes the case that part of a response may
be time-consuming to produce, but it would be useful to send ahead the
portion of the response that precedes it.</p>
<p>In these cases, applications will usually return an iterator (often
a generator-iterator) that produces the output in a block-by-block
fashion. These blocks may be broken to coincide with multipart
boundaries (for “server push”), or just before time-consuming
tasks (such as reading another block of an on-disk file).</p>
<p>WSGI servers, gateways, and middleware <strong>must not</strong> delay the
transmission of any block; they <strong>must</strong> either fully transmit
the block to the client, or guarantee that they will continue
transmission even while the application is producing its next block.
A server/gateway or middleware may provide this guarantee in one of
three ways:</p>
<ol class="arabic simple">
<li>Send the entire block to the operating system (and request
that any O/S buffers be flushed) before returning control
to the application, OR</li>
<li>Use a different thread to ensure that the block continues
to be transmitted while the application produces the next
block.</li>
<li>(Middleware only) send the entire block to its parent
gateway/server</li>
</ol>
<p>By providing this guarantee, WSGI allows applications to ensure
that transmission will not become stalled at an arbitrary point
in their output data. This is critical for proper functioning
of e.g. multipart “server push” streaming, where data between
multipart boundaries should be transmitted in full to the client.</p>
<section id="middleware-handling-of-block-boundaries">
<h4><a class="toc-backref" href="#middleware-handling-of-block-boundaries" role="doc-backlink">Middleware Handling of Block Boundaries</a></h4>
<p>In order to better support asynchronous applications and servers,
middleware components <strong>must not</strong> block iteration waiting for
multiple values from an application iterable. If the middleware
needs to accumulate more data from the application before it can
produce any output, it <strong>must</strong> yield an empty string.</p>
<p>To put this requirement another way, a middleware component <strong>must
yield at least one value</strong> each time its underlying application
yields a value. If the middleware cannot yield any other value,
it must yield an empty string.</p>
<p>This requirement ensures that asynchronous applications and servers
can conspire to reduce the number of threads that are required
to run a given number of application instances simultaneously.</p>
<p>Note also that this requirement means that middleware <strong>must</strong>
return an iterable as soon as its underlying application returns
an iterable. It is also forbidden for middleware to use the
<code class="docutils literal notranslate"><span class="pre">write()</span></code> callable to transmit data that is yielded by an
underlying application. Middleware may only use their parent
servers <code class="docutils literal notranslate"><span class="pre">write()</span></code> callable to transmit data that the
underlying application sent using a middleware-provided <code class="docutils literal notranslate"><span class="pre">write()</span></code>
callable.</p>
</section>
<section id="the-write-callable">
<h4><a class="toc-backref" href="#the-write-callable" role="doc-backlink">The <code class="docutils literal notranslate"><span class="pre">write()</span></code> Callable</a></h4>
<p>Some existing application framework APIs support unbuffered
output in a different manner than WSGI. Specifically, they
provide a “write” function or method of some kind to write
an unbuffered block of data, or else they provide a buffered
“write” function and a “flush” mechanism to flush the buffer.</p>
<p>Unfortunately, such APIs cannot be implemented in terms of
WSGIs “iterable” application return value, unless threads
or other special mechanisms are used.</p>
<p>Therefore, to allow these frameworks to continue using an
imperative API, WSGI includes a special <code class="docutils literal notranslate"><span class="pre">write()</span></code> callable,
returned by the <code class="docutils literal notranslate"><span class="pre">start_response</span></code> callable.</p>
<p>New WSGI applications and frameworks <strong>should not</strong> use the
<code class="docutils literal notranslate"><span class="pre">write()</span></code> callable if it is possible to avoid doing so. The
<code class="docutils literal notranslate"><span class="pre">write()</span></code> callable is strictly a hack to support imperative
streaming APIs. In general, applications should produce their
output via their returned iterable, as this makes it possible
for web servers to interleave other tasks in the same Python thread,
potentially providing better throughput for the server as a whole.</p>
<p>The <code class="docutils literal notranslate"><span class="pre">write()</span></code> callable is returned by the <code class="docutils literal notranslate"><span class="pre">start_response()</span></code>
callable, and it accepts a single parameter: a string to be
written as part of the HTTP response body, that is treated exactly
as though it had been yielded by the output iterable. In other
words, before <code class="docutils literal notranslate"><span class="pre">write()</span></code> returns, it must guarantee that the
passed-in string was either completely sent to the client, or
that it is buffered for transmission while the application
proceeds onward.</p>
<p>An application <strong>must</strong> return an iterable object, even if it
uses <code class="docutils literal notranslate"><span class="pre">write()</span></code> to produce all or part of its response body.
The returned iterable <strong>may</strong> be empty (i.e. yield no non-empty
strings), but if it <em>does</em> yield non-empty strings, that output
must be treated normally by the server or gateway (i.e., it must be
sent or queued immediately). Applications <strong>must not</strong> invoke
<code class="docutils literal notranslate"><span class="pre">write()</span></code> from within their return iterable, and therefore any
strings yielded by the iterable are transmitted after all strings
passed to <code class="docutils literal notranslate"><span class="pre">write()</span></code> have been sent to the client.</p>
</section>
</section>
<section id="unicode-issues">
<h3><a class="toc-backref" href="#unicode-issues" role="doc-backlink">Unicode Issues</a></h3>
<p>HTTP does not directly support Unicode, and neither does this
interface. All encoding/decoding must be handled by the application;
all strings passed to or from the server must be standard Python byte
strings, not Unicode objects. The result of using a Unicode object
where a string object is required, is undefined.</p>
<p>Note also that strings passed to <code class="docutils literal notranslate"><span class="pre">start_response()</span></code> as a status or
as response headers <strong>must</strong> follow <span class="target" id="index-4"></span><a class="rfc reference external" href="https://datatracker.ietf.org/doc/html/rfc2616.html"><strong>RFC 2616</strong></a> with respect to encoding.
That is, they must either be ISO-8859-1 characters, or use <span class="target" id="index-5"></span><a class="rfc reference external" href="https://datatracker.ietf.org/doc/html/rfc2047.html"><strong>RFC 2047</strong></a>
MIME encoding.</p>
<p>On Python platforms where the <code class="docutils literal notranslate"><span class="pre">str</span></code> or <code class="docutils literal notranslate"><span class="pre">StringType</span></code> type is in
fact Unicode-based (e.g. Jython, IronPython, Python 3000, etc.), all
“strings” referred to in this specification must contain only
code points representable in ISO-8859-1 encoding (<code class="docutils literal notranslate"><span class="pre">\u0000</span></code> through
<code class="docutils literal notranslate"><span class="pre">\u00FF</span></code>, inclusive). It is a fatal error for an application to
supply strings containing any other Unicode character or code point.
Similarly, servers and gateways <strong>must not</strong> supply
strings to an application containing any other Unicode characters.</p>
<p>Again, all strings referred to in this specification <strong>must</strong> be
of type <code class="docutils literal notranslate"><span class="pre">str</span></code> or <code class="docutils literal notranslate"><span class="pre">StringType</span></code>, and <strong>must not</strong> be of type
<code class="docutils literal notranslate"><span class="pre">unicode</span></code> or <code class="docutils literal notranslate"><span class="pre">UnicodeType</span></code>. And, even if a given platform allows
for more than 8 bits per character in <code class="docutils literal notranslate"><span class="pre">str</span></code>/<code class="docutils literal notranslate"><span class="pre">StringType</span></code> objects,
only the lower 8 bits may be used, for any value referred to in
this specification as a “string”.</p>
</section>
<section id="error-handling">
<h3><a class="toc-backref" href="#error-handling" role="doc-backlink">Error Handling</a></h3>
<p>In general, applications <strong>should</strong> try to trap their own, internal
errors, and display a helpful message in the browser. (It is up
to the application to decide what “helpful” means in this context.)</p>
<p>However, to display such a message, the application must not have
actually sent any data to the browser yet, or else it risks corrupting
the response. WSGI therefore provides a mechanism to either allow the
application to send its error message, or be automatically aborted:
the <code class="docutils literal notranslate"><span class="pre">exc_info</span></code> argument to <code class="docutils literal notranslate"><span class="pre">start_response</span></code>. Here is an example
of its use:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">try</span><span class="p">:</span>
<span class="c1"># regular application code here</span>
<span class="n">status</span> <span class="o">=</span> <span class="s2">&quot;200 Froody&quot;</span>
<span class="n">response_headers</span> <span class="o">=</span> <span class="p">[(</span><span class="s2">&quot;content-type&quot;</span><span class="p">,</span> <span class="s2">&quot;text/plain&quot;</span><span class="p">)]</span>
<span class="n">start_response</span><span class="p">(</span><span class="n">status</span><span class="p">,</span> <span class="n">response_headers</span><span class="p">)</span>
<span class="k">return</span> <span class="p">[</span><span class="s2">&quot;normal body goes here&quot;</span><span class="p">]</span>
<span class="k">except</span><span class="p">:</span>
<span class="c1"># XXX should trap runtime issues like MemoryError, KeyboardInterrupt</span>
<span class="c1"># in a separate handler before this bare &#39;except:&#39;...</span>
<span class="n">status</span> <span class="o">=</span> <span class="s2">&quot;500 Oops&quot;</span>
<span class="n">response_headers</span> <span class="o">=</span> <span class="p">[(</span><span class="s2">&quot;content-type&quot;</span><span class="p">,</span> <span class="s2">&quot;text/plain&quot;</span><span class="p">)]</span>
<span class="n">start_response</span><span class="p">(</span><span class="n">status</span><span class="p">,</span> <span class="n">response_headers</span><span class="p">,</span> <span class="n">sys</span><span class="o">.</span><span class="n">exc_info</span><span class="p">())</span>
<span class="k">return</span> <span class="p">[</span><span class="s2">&quot;error body goes here&quot;</span><span class="p">]</span>
</pre></div>
</div>
<p>If no output has been written when an exception occurs, the call to
<code class="docutils literal notranslate"><span class="pre">start_response</span></code> will return normally, and the application will
return an error body to be sent to the browser. However, if any output
has already been sent to the browser, <code class="docutils literal notranslate"><span class="pre">start_response</span></code> will reraise
the provided exception. This exception <strong>should not</strong> be trapped by
the application, and so the application will abort. The server or
gateway can then trap this (fatal) exception and abort the response.</p>
<p>Servers <strong>should</strong> trap and log any exception that aborts an
application or the iteration of its return value. If a partial
response has already been written to the browser when an application
error occurs, the server or gateway <strong>may</strong> attempt to add an error
message to the output, if the already-sent headers indicate a
<code class="docutils literal notranslate"><span class="pre">text/*</span></code> content type that the server knows how to modify cleanly.</p>
<p>Some middleware may wish to provide additional exception handling
services, or intercept and replace application error messages. In
such cases, middleware may choose to <strong>not</strong> re-raise the <code class="docutils literal notranslate"><span class="pre">exc_info</span></code>
supplied to <code class="docutils literal notranslate"><span class="pre">start_response</span></code>, but instead raise a middleware-specific
exception, or simply return without an exception after storing the
supplied arguments. This will then cause the application to return
its error body iterable (or invoke <code class="docutils literal notranslate"><span class="pre">write()</span></code>), allowing the middleware
to capture and modify the error output. These techniques will work as
long as application authors:</p>
<ol class="arabic simple">
<li>Always provide <code class="docutils literal notranslate"><span class="pre">exc_info</span></code> when beginning an error response</li>
<li>Never trap errors raised by <code class="docutils literal notranslate"><span class="pre">start_response</span></code> when <code class="docutils literal notranslate"><span class="pre">exc_info</span></code> is
being provided</li>
</ol>
</section>
<section id="http-1-1-expect-continue">
<h3><a class="toc-backref" href="#http-1-1-expect-continue" role="doc-backlink">HTTP 1.1 Expect/Continue</a></h3>
<p>Servers and gateways that implement HTTP 1.1 <strong>must</strong> provide
transparent support for HTTP 1.1s “expect/continue” mechanism. This
may be done in any of several ways:</p>
<ol class="arabic simple">
<li>Respond to requests containing an <code class="docutils literal notranslate"><span class="pre">Expect:</span> <span class="pre">100-continue</span></code> request
with an immediate “100 Continue” response, and proceed normally.</li>
<li>Proceed with the request normally, but provide the application
with a <code class="docutils literal notranslate"><span class="pre">wsgi.input</span></code> stream that will send the “100 Continue”
response if/when the application first attempts to read from the
input stream. The read request must then remain blocked until the
client responds.</li>
<li>Wait until the client decides that the server does not support
expect/continue, and sends the request body on its own. (This
is suboptimal, and is not recommended.)</li>
</ol>
<p>Note that these behavior restrictions do not apply for HTTP 1.0
requests, or for requests that are not directed to an application
object. For more information on HTTP 1.1 Expect/Continue, see
<span class="target" id="index-6"></span><a class="rfc reference external" href="https://datatracker.ietf.org/doc/html/rfc2616.html"><strong>RFC 2616</strong></a>, sections 8.2.3 and 10.1.1.</p>
</section>
<section id="other-http-features">
<h3><a class="toc-backref" href="#other-http-features" role="doc-backlink">Other HTTP Features</a></h3>
<p>In general, servers and gateways should “play dumb” and allow the
application complete control over its output. They should only make
changes that do not alter the effective semantics of the applications
response. It is always possible for the application developer to add
middleware components to supply additional features, so server/gateway
developers should be conservative in their implementation. In a sense,
a server should consider itself to be like an HTTP “gateway server”,
with the application being an HTTP “origin server”. (See <span class="target" id="index-7"></span><a class="rfc reference external" href="https://datatracker.ietf.org/doc/html/rfc2616.html"><strong>RFC 2616</strong></a>,
section 1.3, for the definition of these terms.)</p>
<p>However, because WSGI servers and applications do not communicate via
HTTP, what <span class="target" id="index-8"></span><a class="rfc reference external" href="https://datatracker.ietf.org/doc/html/rfc2616.html"><strong>RFC 2616</strong></a> calls “hop-by-hop” headers do not apply to WSGI
internal communications. WSGI applications <strong>must not</strong> generate any
<span class="target" id="index-9"></span><a class="rfc reference external" href="https://datatracker.ietf.org/doc/html/rfc2616.html#section-13.5.1"><strong>“hop-by-hop” headers</strong></a>,
attempt to use HTTP features that would
require them to generate such headers, or rely on the content of
any incoming “hop-by-hop” headers in the <code class="docutils literal notranslate"><span class="pre">environ</span></code> dictionary.
WSGI servers <strong>must</strong> handle any supported inbound “hop-by-hop” headers
on their own, such as by decoding any inbound <code class="docutils literal notranslate"><span class="pre">Transfer-Encoding</span></code>,
including chunked encoding if applicable.</p>
<p>Applying these principles to a variety of HTTP features, it should be
clear that a server <strong>may</strong> handle cache validation via the
<code class="docutils literal notranslate"><span class="pre">If-None-Match</span></code> and <code class="docutils literal notranslate"><span class="pre">If-Modified-Since</span></code> request headers and the
<code class="docutils literal notranslate"><span class="pre">Last-Modified</span></code> and <code class="docutils literal notranslate"><span class="pre">ETag</span></code> response headers. However, it is
not required to do this, and the application <strong>should</strong> perform its
own cache validation if it wants to support that feature, since
the server/gateway is not required to do such validation.</p>
<p>Similarly, a server <strong>may</strong> re-encode or transport-encode an
applications response, but the application <strong>should</strong> use a
suitable content encoding on its own, and <strong>must not</strong> apply a
transport encoding. A server <strong>may</strong> transmit byte ranges of the
applications response if requested by the client, and the
application doesnt natively support byte ranges. Again, however,
the application <strong>should</strong> perform this function on its own if desired.</p>
<p>Note that these restrictions on applications do not necessarily mean
that every application must reimplement every HTTP feature; many HTTP
features can be partially or fully implemented by middleware
components, thus freeing both server and application authors from
implementing the same features over and over again.</p>
</section>
<section id="thread-support">
<h3><a class="toc-backref" href="#thread-support" role="doc-backlink">Thread Support</a></h3>
<p>Thread support, or lack thereof, is also server-dependent.
Servers that can run multiple requests in parallel, <strong>should</strong> also
provide the option of running an application in a single-threaded
fashion, so that applications or frameworks that are not thread-safe
may still be used with that server.</p>
</section>
</section>
<section id="implementation-application-notes">
<h2><a class="toc-backref" href="#implementation-application-notes" role="doc-backlink">Implementation/Application Notes</a></h2>
<section id="server-extension-apis">
<h3><a class="toc-backref" href="#server-extension-apis" role="doc-backlink">Server Extension APIs</a></h3>
<p>Some server authors may wish to expose more advanced APIs, that
application or framework authors can use for specialized purposes.
For example, a gateway based on <code class="docutils literal notranslate"><span class="pre">mod_python</span></code> might wish to expose
part of the Apache API as a WSGI extension.</p>
<p>In the simplest case, this requires nothing more than defining an
<code class="docutils literal notranslate"><span class="pre">environ</span></code> variable, such as <code class="docutils literal notranslate"><span class="pre">mod_python.some_api</span></code>. But, in many
cases, the possible presence of middleware can make this difficult.
For example, an API that offers access to the same HTTP headers that
are found in <code class="docutils literal notranslate"><span class="pre">environ</span></code> variables, might return different data if
<code class="docutils literal notranslate"><span class="pre">environ</span></code> has been modified by middleware.</p>
<p>In general, any extension API that duplicates, supplants, or bypasses
some portion of WSGI functionality runs the risk of being incompatible
with middleware components. Server/gateway developers should <em>not</em>
assume that nobody will use middleware, because some framework
developers specifically intend to organize or reorganize their
frameworks to function almost entirely as middleware of various kinds.</p>
<p>So, to provide maximum compatibility, servers and gateways that
provide extension APIs that replace some WSGI functionality, <strong>must</strong>
design those APIs so that they are invoked using the portion of the
API that they replace. For example, an extension API to access HTTP
request headers must require the application to pass in its current
<code class="docutils literal notranslate"><span class="pre">environ</span></code>, so that the server/gateway may verify that HTTP headers
accessible via the API have not been altered by middleware. If the
extension API cannot guarantee that it will always agree with
<code class="docutils literal notranslate"><span class="pre">environ</span></code> about the contents of HTTP headers, it must refuse service
to the application, e.g. by raising an error, returning <code class="docutils literal notranslate"><span class="pre">None</span></code>
instead of a header collection, or whatever is appropriate to the API.</p>
<p>Similarly, if an extension API provides an alternate means of writing
response data or headers, it should require the <code class="docutils literal notranslate"><span class="pre">start_response</span></code>
callable to be passed in, before the application can obtain the
extended service. If the object passed in is not the same one that
the server/gateway originally supplied to the application, it cannot
guarantee correct operation and must refuse to provide the extended
service to the application.</p>
<p>These guidelines also apply to middleware that adds information such
as parsed cookies, form variables, sessions, and the like to
<code class="docutils literal notranslate"><span class="pre">environ</span></code>. Specifically, such middleware should provide these
features as functions which operate on <code class="docutils literal notranslate"><span class="pre">environ</span></code>, rather than simply
stuffing values into <code class="docutils literal notranslate"><span class="pre">environ</span></code>. This helps ensure that information
is calculated from <code class="docutils literal notranslate"><span class="pre">environ</span></code> <em>after</em> any middleware has done any URL
rewrites or other <code class="docutils literal notranslate"><span class="pre">environ</span></code> modifications.</p>
<p>It is very important that these “safe extension” rules be followed by
both server/gateway and middleware developers, in order to avoid a
future in which middleware developers are forced to delete any and all
extension APIs from <code class="docutils literal notranslate"><span class="pre">environ</span></code> to ensure that their mediation isnt
being bypassed by applications using those extensions!</p>
</section>
<section id="application-configuration">
<h3><a class="toc-backref" href="#application-configuration" role="doc-backlink">Application Configuration</a></h3>
<p>This specification does not define how a server selects or obtains an
application to invoke. These and other configuration options are
highly server-specific matters. It is expected that server/gateway
authors will document how to configure the server to execute a
particular application object, and with what options (such as
threading options).</p>
<p>Framework authors, on the other hand, should document how to create an
application object that wraps their frameworks functionality. The
user, who has chosen both the server and the application framework,
must connect the two together. However, since both the framework and
the server now have a common interface, this should be merely a
mechanical matter, rather than a significant engineering effort for
each new server/framework pair.</p>
<p>Finally, some applications, frameworks, and middleware may wish to
use the <code class="docutils literal notranslate"><span class="pre">environ</span></code> dictionary to receive simple string configuration
options. Servers and gateways <strong>should</strong> support this by allowing
an applications deployer to specify name-value pairs to be placed in
<code class="docutils literal notranslate"><span class="pre">environ</span></code>. In the simplest case, this support can consist merely of
copying all operating system-supplied environment variables from
<code class="docutils literal notranslate"><span class="pre">os.environ</span></code> into the <code class="docutils literal notranslate"><span class="pre">environ</span></code> dictionary, since the deployer in
principle can configure these externally to the server, or in the
CGI case they may be able to be set via the servers configuration
files.</p>
<p>Applications <strong>should</strong> try to keep such required variables to a
minimum, since not all servers will support easy configuration of
them. Of course, even in the worst case, persons deploying an
application can create a script to supply the necessary configuration
values:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">the_app</span> <span class="kn">import</span> <span class="n">application</span>
<span class="k">def</span> <span class="nf">new_app</span><span class="p">(</span><span class="n">environ</span><span class="p">,</span> <span class="n">start_response</span><span class="p">):</span>
<span class="n">environ</span><span class="p">[</span><span class="s1">&#39;the_app.configval1&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="s1">&#39;something&#39;</span>
<span class="k">return</span> <span class="n">application</span><span class="p">(</span><span class="n">environ</span><span class="p">,</span> <span class="n">start_response</span><span class="p">)</span>
</pre></div>
</div>
<p>But, most existing applications and frameworks will probably only need
a single configuration value from <code class="docutils literal notranslate"><span class="pre">environ</span></code>, to indicate the location
of their application or framework-specific configuration file(s). (Of
course, applications should cache such configuration, to avoid having
to re-read it upon each invocation.)</p>
</section>
<section id="url-reconstruction">
<h3><a class="toc-backref" href="#url-reconstruction" role="doc-backlink">URL Reconstruction</a></h3>
<p>If an application wishes to reconstruct a requests complete URL, it
may do so using the following algorithm, contributed by Ian Bicking:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">urllib</span> <span class="kn">import</span> <span class="n">quote</span>
<span class="n">url</span> <span class="o">=</span> <span class="n">environ</span><span class="p">[</span><span class="s1">&#39;wsgi.url_scheme&#39;</span><span class="p">]</span><span class="o">+</span><span class="s1">&#39;://&#39;</span>
<span class="k">if</span> <span class="n">environ</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">&#39;HTTP_HOST&#39;</span><span class="p">):</span>
<span class="n">url</span> <span class="o">+=</span> <span class="n">environ</span><span class="p">[</span><span class="s1">&#39;HTTP_HOST&#39;</span><span class="p">]</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">url</span> <span class="o">+=</span> <span class="n">environ</span><span class="p">[</span><span class="s1">&#39;SERVER_NAME&#39;</span><span class="p">]</span>
<span class="k">if</span> <span class="n">environ</span><span class="p">[</span><span class="s1">&#39;wsgi.url_scheme&#39;</span><span class="p">]</span> <span class="o">==</span> <span class="s1">&#39;https&#39;</span><span class="p">:</span>
<span class="k">if</span> <span class="n">environ</span><span class="p">[</span><span class="s1">&#39;SERVER_PORT&#39;</span><span class="p">]</span> <span class="o">!=</span> <span class="s1">&#39;443&#39;</span><span class="p">:</span>
<span class="n">url</span> <span class="o">+=</span> <span class="s1">&#39;:&#39;</span> <span class="o">+</span> <span class="n">environ</span><span class="p">[</span><span class="s1">&#39;SERVER_PORT&#39;</span><span class="p">]</span>
<span class="k">else</span><span class="p">:</span>
<span class="k">if</span> <span class="n">environ</span><span class="p">[</span><span class="s1">&#39;SERVER_PORT&#39;</span><span class="p">]</span> <span class="o">!=</span> <span class="s1">&#39;80&#39;</span><span class="p">:</span>
<span class="n">url</span> <span class="o">+=</span> <span class="s1">&#39;:&#39;</span> <span class="o">+</span> <span class="n">environ</span><span class="p">[</span><span class="s1">&#39;SERVER_PORT&#39;</span><span class="p">]</span>
<span class="n">url</span> <span class="o">+=</span> <span class="n">quote</span><span class="p">(</span><span class="n">environ</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">&#39;SCRIPT_NAME&#39;</span><span class="p">,</span> <span class="s1">&#39;&#39;</span><span class="p">))</span>
<span class="n">url</span> <span class="o">+=</span> <span class="n">quote</span><span class="p">(</span><span class="n">environ</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">&#39;PATH_INFO&#39;</span><span class="p">,</span> <span class="s1">&#39;&#39;</span><span class="p">))</span>
<span class="k">if</span> <span class="n">environ</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">&#39;QUERY_STRING&#39;</span><span class="p">):</span>
<span class="n">url</span> <span class="o">+=</span> <span class="s1">&#39;?&#39;</span> <span class="o">+</span> <span class="n">environ</span><span class="p">[</span><span class="s1">&#39;QUERY_STRING&#39;</span><span class="p">]</span>
</pre></div>
</div>
<p>Note that such a reconstructed URL may not be precisely the same URI
as requested by the client. Server rewrite rules, for example, may
have modified the clients originally requested URL to place it in a
canonical form.</p>
</section>
<section id="supporting-older-2-2-versions-of-python">
<h3><a class="toc-backref" href="#supporting-older-2-2-versions-of-python" role="doc-backlink">Supporting Older (&lt;2.2) Versions of Python</a></h3>
<p>Some servers, gateways, or applications may wish to support older
(&lt;2.2) versions of Python. This is especially important if Jython
is a target platform, since as of this writing a production-ready
version of Jython 2.2 is not yet available.</p>
<p>For servers and gateways, this is relatively straightforward:
servers and gateways targeting pre-2.2 versions of Python must
simply restrict themselves to using only a standard “for” loop to
iterate over any iterable returned by an application. This is the
only way to ensure source-level compatibility with both the pre-2.2
iterator protocol (discussed further below) and “todays” iterator
protocol (see <a class="pep reference internal" href="../pep-0234/" title="PEP 234 Iterators">PEP 234</a>).</p>
<p>(Note that this technique necessarily applies only to servers,
gateways, or middleware that are written in Python. Discussion of
how to use iterator protocol(s) correctly from other languages is
outside the scope of this PEP.)</p>
<p>For applications, supporting pre-2.2 versions of Python is slightly
more complex:</p>
<ul class="simple">
<li>You may not return a file object and expect it to work as an iterable,
since before Python 2.2, files were not iterable. (In general, you
shouldnt do this anyway, because it will perform quite poorly most
of the time!) Use <code class="docutils literal notranslate"><span class="pre">wsgi.file_wrapper</span></code> or an application-specific
file wrapper class. (See <a class="reference internal" href="#optional-platform-specific-file-handling">Optional Platform-Specific File Handling</a>
for more on <code class="docutils literal notranslate"><span class="pre">wsgi.file_wrapper</span></code>, and an example class you can use
to wrap a file as an iterable.)</li>
<li>If you return a custom iterable, it <strong>must</strong> implement the pre-2.2
iterator protocol. That is, provide a <code class="docutils literal notranslate"><span class="pre">__getitem__</span></code> method that
accepts an integer key, and raises <code class="docutils literal notranslate"><span class="pre">IndexError</span></code> when exhausted.
(Note that built-in sequence types are also acceptable, since they
also implement this protocol.)</li>
</ul>
<p>Finally, middleware that wishes to support pre-2.2 versions of Python,
and iterates over application return values or itself returns an
iterable (or both), must follow the appropriate recommendations above.</p>
<p>(Note: It should go without saying that to support pre-2.2 versions
of Python, any server, gateway, application, or middleware must also
use only language features available in the target version, use
1 and 0 instead of <code class="docutils literal notranslate"><span class="pre">True</span></code> and <code class="docutils literal notranslate"><span class="pre">False</span></code>, etc.)</p>
</section>
<section id="optional-platform-specific-file-handling">
<h3><a class="toc-backref" href="#optional-platform-specific-file-handling" role="doc-backlink">Optional Platform-Specific File Handling</a></h3>
<p>Some operating environments provide special high-performance
file-transmission facilities, such as the Unix <code class="docutils literal notranslate"><span class="pre">sendfile()</span></code> call.
Servers and gateways <strong>may</strong> expose this functionality via an optional
<code class="docutils literal notranslate"><span class="pre">wsgi.file_wrapper</span></code> key in the <code class="docutils literal notranslate"><span class="pre">environ</span></code>. An application
<strong>may</strong> use this “file wrapper” to convert a file or file-like object
into an iterable that it then returns, e.g.:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">if</span> <span class="s1">&#39;wsgi.file_wrapper&#39;</span> <span class="ow">in</span> <span class="n">environ</span><span class="p">:</span>
<span class="k">return</span> <span class="n">environ</span><span class="p">[</span><span class="s1">&#39;wsgi.file_wrapper&#39;</span><span class="p">](</span><span class="n">filelike</span><span class="p">,</span> <span class="n">block_size</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="k">return</span> <span class="nb">iter</span><span class="p">(</span><span class="k">lambda</span><span class="p">:</span> <span class="n">filelike</span><span class="o">.</span><span class="n">read</span><span class="p">(</span><span class="n">block_size</span><span class="p">),</span> <span class="s1">&#39;&#39;</span><span class="p">)</span>
</pre></div>
</div>
<p>If the server or gateway supplies <code class="docutils literal notranslate"><span class="pre">wsgi.file_wrapper</span></code>, it must be
a callable that accepts one required positional parameter, and one
optional positional parameter. The first parameter is the file-like
object to be sent, and the second parameter is an optional block
size “suggestion” (which the server/gateway need not use). The
callable <strong>must</strong> return an iterable object, and <strong>must not</strong> perform
any data transmission until and unless the server/gateway actually
receives the iterable as a return value from the application.
(To do otherwise would prevent middleware from being able to interpret
or override the response data.)</p>
<p>To be considered “file-like”, the object supplied by the application
must have a <code class="docutils literal notranslate"><span class="pre">read()</span></code> method that takes an optional size argument.
It <strong>may</strong> have a <code class="docutils literal notranslate"><span class="pre">close()</span></code> method, and if so, the iterable returned
by <code class="docutils literal notranslate"><span class="pre">wsgi.file_wrapper</span></code> <strong>must</strong> have a <code class="docutils literal notranslate"><span class="pre">close()</span></code> method that
invokes the original file-like objects <code class="docutils literal notranslate"><span class="pre">close()</span></code> method. If the
“file-like” object has any other methods or attributes with names
matching those of Python built-in file objects (e.g. <code class="docutils literal notranslate"><span class="pre">fileno()</span></code>),
the <code class="docutils literal notranslate"><span class="pre">wsgi.file_wrapper</span></code> <strong>may</strong> assume that these methods or
attributes have the same semantics as those of a built-in file object.</p>
<p>The actual implementation of any platform-specific file handling
must occur <strong>after</strong> the application returns, and the server or
gateway checks to see if a wrapper object was returned. (Again,
because of the presence of middleware, error handlers, and the like,
it is not guaranteed that any wrapper created will actually be used.)</p>
<p>Apart from the handling of <code class="docutils literal notranslate"><span class="pre">close()</span></code>, the semantics of returning a
file wrapper from the application should be the same as if the
application had returned <code class="docutils literal notranslate"><span class="pre">iter(filelike.read,</span> <span class="pre">'')</span></code>. In other words,
transmission should begin at the current position within the “file”
at the time that transmission begins, and continue until the end is
reached.</p>
<p>Of course, platform-specific file transmission APIs dont usually
accept arbitrary “file-like” objects. Therefore, a
<code class="docutils literal notranslate"><span class="pre">wsgi.file_wrapper</span></code> has to introspect the supplied object for
things such as a <code class="docutils literal notranslate"><span class="pre">fileno()</span></code> (Unix-like OSes) or a
<code class="docutils literal notranslate"><span class="pre">java.nio.FileChannel</span></code> (under Jython) in order to determine if
the file-like object is suitable for use with the platform-specific
API it supports.</p>
<p>Note that even if the object is <em>not</em> suitable for the platform API,
the <code class="docutils literal notranslate"><span class="pre">wsgi.file_wrapper</span></code> <strong>must</strong> still return an iterable that wraps
<code class="docutils literal notranslate"><span class="pre">read()</span></code> and <code class="docutils literal notranslate"><span class="pre">close()</span></code>, so that applications using file wrappers
are portable across platforms. Heres a simple platform-agnostic
file wrapper class, suitable for old (pre 2.2) and new Pythons alike:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">FileWrapper</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">filelike</span><span class="p">,</span> <span class="n">blksize</span><span class="o">=</span><span class="mi">8192</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">filelike</span> <span class="o">=</span> <span class="n">filelike</span>
<span class="bp">self</span><span class="o">.</span><span class="n">blksize</span> <span class="o">=</span> <span class="n">blksize</span>
<span class="k">if</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">filelike</span><span class="p">,</span> <span class="s1">&#39;close&#39;</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">close</span> <span class="o">=</span> <span class="n">filelike</span><span class="o">.</span><span class="n">close</span>
<span class="k">def</span> <span class="fm">__getitem__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">key</span><span class="p">):</span>
<span class="n">data</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">filelike</span><span class="o">.</span><span class="n">read</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">blksize</span><span class="p">)</span>
<span class="k">if</span> <span class="n">data</span><span class="p">:</span>
<span class="k">return</span> <span class="n">data</span>
<span class="k">raise</span> <span class="ne">IndexError</span>
</pre></div>
</div>
<p>and here is a snippet from a server/gateway that uses it to provide
access to a platform-specific API:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">environ</span><span class="p">[</span><span class="s1">&#39;wsgi.file_wrapper&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="n">FileWrapper</span>
<span class="n">result</span> <span class="o">=</span> <span class="n">application</span><span class="p">(</span><span class="n">environ</span><span class="p">,</span> <span class="n">start_response</span><span class="p">)</span>
<span class="k">try</span><span class="p">:</span>
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">result</span><span class="p">,</span> <span class="n">FileWrapper</span><span class="p">):</span>
<span class="c1"># check if result.filelike is usable w/platform-specific</span>
<span class="c1"># API, and if so, use that API to transmit the result.</span>
<span class="c1"># If not, fall through to normal iterable handling</span>
<span class="c1"># loop below.</span>
<span class="k">for</span> <span class="n">data</span> <span class="ow">in</span> <span class="n">result</span><span class="p">:</span>
<span class="c1"># etc.</span>
<span class="k">finally</span><span class="p">:</span>
<span class="k">if</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">result</span><span class="p">,</span> <span class="s1">&#39;close&#39;</span><span class="p">):</span>
<span class="n">result</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
</pre></div>
</div>
</section>
</section>
<section id="questions-and-answers">
<h2><a class="toc-backref" href="#questions-and-answers" role="doc-backlink">Questions and Answers</a></h2>
<ol class="arabic">
<li>Why must <code class="docutils literal notranslate"><span class="pre">environ</span></code> be a dictionary? Whats wrong with using a
subclass?<p>The rationale for requiring a dictionary is to maximize portability
between servers. The alternative would be to define some subset of
a dictionarys methods as being the standard and portable
interface. In practice, however, most servers will probably find a
dictionary adequate to their needs, and thus framework authors will
come to expect the full set of dictionary features to be available,
since they will be there more often than not. But, if some server
chooses <em>not</em> to use a dictionary, then there will be
interoperability problems despite that servers “conformance” to
spec. Therefore, making a dictionary mandatory simplifies the
specification and guarantees interoperability.</p>
<p>Note that this does not prevent server or framework developers from
offering specialized services as custom variables <em>inside</em> the
<code class="docutils literal notranslate"><span class="pre">environ</span></code> dictionary. This is the recommended approach for
offering any such value-added services.</p>
</li>
<li>Why can you call <code class="docutils literal notranslate"><span class="pre">write()</span></code> <em>and</em> yield strings/return an
iterable? Shouldnt we pick just one way?<p>If we supported only the iteration approach, then current
frameworks that assume the availability of “push” suffer. But, if
we only support pushing via <code class="docutils literal notranslate"><span class="pre">write()</span></code>, then server performance
suffers for transmission of e.g. large files (if a worker thread
cant begin work on a new request until all of the output has been
sent). Thus, this compromise allows an application framework to
support both approaches, as appropriate, but with only a little
more burden to the server implementor than a push-only approach
would require.</p>
</li>
<li>Whats the <code class="docutils literal notranslate"><span class="pre">close()</span></code> for?<p>When writes are done during the execution of an application
object, the application can ensure that resources are released
using a try/finally block. But, if the application returns an
iterable, any resources used will not be released until the
iterable is garbage collected. The <code class="docutils literal notranslate"><span class="pre">close()</span></code> idiom allows an
application to release critical resources at the end of a request,
and its forward-compatible with the support for try/finally in
generators thats proposed by <a class="pep reference internal" href="../pep-0325/" title="PEP 325 Resource-Release Support for Generators">PEP 325</a>.</p>
</li>
<li>Why is this interface so low-level? I want feature X! (e.g.
cookies, sessions, persistence, …)<p>This isnt Yet Another Python Web Framework. Its just a way for
frameworks to talk to web servers, and vice versa. If you want
these features, you need to pick a web framework that provides the
features you want. And if that framework lets you create a WSGI
application, you should be able to run it in most WSGI-supporting
servers. Also, some WSGI servers may offer additional services via
objects provided in their <code class="docutils literal notranslate"><span class="pre">environ</span></code> dictionary; see the
applicable server documentation for details. (Of course,
applications that use such extensions will not be portable to other
WSGI-based servers.)</p>
</li>
<li>Why use CGI variables instead of good old HTTP headers? And why
mix them in with WSGI-defined variables?<p>Many existing web frameworks are built heavily upon the CGI spec,
and existing web servers know how to generate CGI variables. In
contrast, alternative ways of representing inbound HTTP information
are fragmented and lack market share. Thus, using the CGI
“standard” seems like a good way to leverage existing
implementations. As for mixing them with WSGI variables,
separating them would just require two dictionary arguments to be
passed around, while providing no real benefits.</p>
</li>
<li>What about the status string? Cant we just use the number,
passing in <code class="docutils literal notranslate"><span class="pre">200</span></code> instead of <code class="docutils literal notranslate"><span class="pre">&quot;200</span> <span class="pre">OK&quot;</span></code>?<p>Doing this would complicate the server or gateway, by requiring
them to have a table of numeric statuses and corresponding
messages. By contrast, it is easy for an application or framework
author to type the extra text to go with the specific response code
they are using, and existing frameworks often already have a table
containing the needed messages. So, on balance it seems better to
make the application/framework responsible, rather than the server
or gateway.</p>
</li>
<li>Why is <code class="docutils literal notranslate"><span class="pre">wsgi.run_once</span></code> not guaranteed to run the app only once?<p>Because its merely a suggestion to the application that it should
“rig for infrequent running”. This is intended for application
frameworks that have multiple modes of operation for caching,
sessions, and so forth. In a “multiple run” mode, such frameworks
may preload caches, and may not write e.g. logs or session data to
disk after each request. In “single run” mode, such frameworks
avoid preloading and flush all necessary writes after each request.</p>
<p>However, in order to test an application or framework to verify
correct operation in the latter mode, it may be necessary (or at
least expedient) to invoke it more than once. Therefore, an
application should not assume that it will definitely not be run
again, just because it is called with <code class="docutils literal notranslate"><span class="pre">wsgi.run_once</span></code> set to
<code class="docutils literal notranslate"><span class="pre">True</span></code>.</p>
</li>
<li>Feature X (dictionaries, callables, etc.) are ugly for use in
application code; why dont we use objects instead?<p>All of these implementation choices of WSGI are specifically
intended to <em>decouple</em> features from one another; recombining these
features into encapsulated objects makes it somewhat harder to
write servers or gateways, and an order of magnitude harder to
write middleware that replaces or modifies only small portions of
the overall functionality.</p>
<p>In essence, middleware wants to have a “Chain of Responsibility”
pattern, whereby it can act as a “handler” for some functions,
while allowing others to remain unchanged. This is difficult to do
with ordinary Python objects, if the interface is to remain
extensible. For example, one must use <code class="docutils literal notranslate"><span class="pre">__getattr__</span></code> or
<code class="docutils literal notranslate"><span class="pre">__getattribute__</span></code> overrides, to ensure that extensions (such as
attributes defined by future WSGI versions) are passed through.</p>
<p>This type of code is notoriously difficult to get 100% correct, and
few people will want to write it themselves. They will therefore
copy other peoples implementations, but fail to update them when
the person they copied from corrects yet another corner case.</p>
<p>Further, this necessary boilerplate would be pure excise, a
developer tax paid by middleware developers to support a slightly
prettier API for application framework developers. But,
application framework developers will typically only be updating
<em>one</em> framework to support WSGI, and in a very limited part of
their framework as a whole. It will likely be their first (and
maybe their only) WSGI implementation, and thus they will likely
implement with this specification ready to hand. Thus, the effort
of making the API “prettier” with object attributes and suchlike
would likely be wasted for this audience.</p>
<p>We encourage those who want a prettier (or otherwise improved) WSGI
interface for use in direct web application programming (as opposed
to web framework development) to develop APIs or frameworks that
wrap WSGI for convenient use by application developers. In this
way, WSGI can remain conveniently low-level for server and
middleware authors, while not being “ugly” for application
developers.</p>
</li>
</ol>
</section>
<section id="proposed-under-discussion">
<h2><a class="toc-backref" href="#proposed-under-discussion" role="doc-backlink">Proposed/Under Discussion</a></h2>
<p>These items are currently being discussed on the Web-SIG and elsewhere,
or are on the PEP authors “to-do” list:</p>
<ul class="simple">
<li>Should <code class="docutils literal notranslate"><span class="pre">wsgi.input</span></code> be an iterator instead of a file? This would
help for asynchronous applications and chunked-encoding input
streams.</li>
<li>Optional extensions are being discussed for pausing iteration of an
applications output until input is available or until a callback
occurs.</li>
<li>Add a section about synchronous vs. asynchronous apps and servers,
the relevant threading models, and issues/design goals in these
areas.</li>
</ul>
</section>
<section id="acknowledgements">
<h2><a class="toc-backref" href="#acknowledgements" role="doc-backlink">Acknowledgements</a></h2>
<p>Thanks go to the many folks on the Web-SIG mailing list whose
thoughtful feedback made this revised draft possible. Especially:</p>
<ul class="simple">
<li>Gregory “Grisha” Trubetskoy, author of <code class="docutils literal notranslate"><span class="pre">mod_python</span></code>, who beat up
on the first draft as not offering any advantages over “plain old
CGI”, thus encouraging me to look for a better approach.</li>
<li>Ian Bicking, who helped nag me into properly specifying the
multithreading and multiprocess options, as well as badgering me to
provide a mechanism for servers to supply custom extension data to
an application.</li>
<li>Tony Lownds, who came up with the concept of a <code class="docutils literal notranslate"><span class="pre">start_response</span></code>
function that took the status and headers, returning a <code class="docutils literal notranslate"><span class="pre">write</span></code>
function. His input also guided the design of the exception handling
facilities, especially in the area of allowing for middleware that
overrides application error messages.</li>
<li>Alan Kennedy, whose courageous attempts to implement WSGI-on-Jython
(well before the spec was finalized) helped to shape the “supporting
older versions of Python” section, as well as the optional
<code class="docutils literal notranslate"><span class="pre">wsgi.file_wrapper</span></code> facility.</li>
<li>Mark Nottingham, who reviewed the spec extensively for issues with
HTTP RFC compliance, especially with regard to HTTP/1.1 features that
I didnt even know existed until he pointed them out.</li>
</ul>
</section>
<section id="references">
<h2><a class="toc-backref" href="#references" role="doc-backlink">References</a></h2>
<aside class="footnote-list brackets">
<aside class="footnote brackets" id="id4" role="doc-footnote">
<dt class="label" id="id4">[<a href="#id1">1</a>]</dt>
<dd>The Python Wiki “Web Programming” topic
(<a class="reference external" href="http://www.python.org/cgi-bin/moinmoin/WebProgramming">http://www.python.org/cgi-bin/moinmoin/WebProgramming</a>)</aside>
<aside class="footnote brackets" id="id5" role="doc-footnote">
<dt class="label" id="id5">[<a href="#id2">2</a>]</dt>
<dd>The Common Gateway Interface Specification, v 1.1, 3rd Draft
(<a class="reference external" href="https://datatracker.ietf.org/doc/html/draft-coar-cgi-v11-03">https://datatracker.ietf.org/doc/html/draft-coar-cgi-v11-03</a>)</aside>
<aside class="footnote brackets" id="id6" role="doc-footnote">
<dt class="label" id="id6">[<a href="#id3">3</a>]</dt>
<dd>mod_ssl Reference, “Environment Variables”
(<a class="reference external" href="http://www.modssl.org/docs/2.8/ssl_reference.html#ToC25">http://www.modssl.org/docs/2.8/ssl_reference.html#ToC25</a>)</aside>
</aside>
</section>
<section id="copyright">
<h2><a class="toc-backref" href="#copyright" role="doc-backlink">Copyright</a></h2>
<p>This document has been placed in the public domain.</p>
</section>
</section>
<hr class="docutils" />
<p>Source: <a class="reference external" href="https://github.com/python/peps/blob/main/peps/pep-0333.rst">https://github.com/python/peps/blob/main/peps/pep-0333.rst</a></p>
<p>Last modified: <a class="reference external" href="https://github.com/python/peps/commits/main/peps/pep-0333.rst">2023-09-09 17:39:29 GMT</a></p>
</article>
<nav id="pep-sidebar">
<h2>Contents</h2>
<ul>
<li><a class="reference internal" href="#preface">Preface</a></li>
<li><a class="reference internal" href="#abstract">Abstract</a></li>
<li><a class="reference internal" href="#rationale-and-goals">Rationale and Goals</a></li>
<li><a class="reference internal" href="#specification-overview">Specification Overview</a><ul>
<li><a class="reference internal" href="#the-application-framework-side">The Application/Framework Side</a></li>
<li><a class="reference internal" href="#the-server-gateway-side">The Server/Gateway Side</a></li>
<li><a class="reference internal" href="#middleware-components-that-play-both-sides">Middleware: Components that Play Both Sides</a></li>
</ul>
</li>
<li><a class="reference internal" href="#specification-details">Specification Details</a><ul>
<li><a class="reference internal" href="#environ-variables"><code class="docutils literal notranslate"><span class="pre">environ</span></code> Variables</a><ul>
<li><a class="reference internal" href="#input-and-error-streams">Input and Error Streams</a></li>
</ul>
</li>
<li><a class="reference internal" href="#the-start-response-callable">The <code class="docutils literal notranslate"><span class="pre">start_response()</span></code> Callable</a><ul>
<li><a class="reference internal" href="#handling-the-content-length-header">Handling the <code class="docutils literal notranslate"><span class="pre">Content-Length</span></code> Header</a></li>
</ul>
</li>
<li><a class="reference internal" href="#buffering-and-streaming">Buffering and Streaming</a><ul>
<li><a class="reference internal" href="#middleware-handling-of-block-boundaries">Middleware Handling of Block Boundaries</a></li>
<li><a class="reference internal" href="#the-write-callable">The <code class="docutils literal notranslate"><span class="pre">write()</span></code> Callable</a></li>
</ul>
</li>
<li><a class="reference internal" href="#unicode-issues">Unicode Issues</a></li>
<li><a class="reference internal" href="#error-handling">Error Handling</a></li>
<li><a class="reference internal" href="#http-1-1-expect-continue">HTTP 1.1 Expect/Continue</a></li>
<li><a class="reference internal" href="#other-http-features">Other HTTP Features</a></li>
<li><a class="reference internal" href="#thread-support">Thread Support</a></li>
</ul>
</li>
<li><a class="reference internal" href="#implementation-application-notes">Implementation/Application Notes</a><ul>
<li><a class="reference internal" href="#server-extension-apis">Server Extension APIs</a></li>
<li><a class="reference internal" href="#application-configuration">Application Configuration</a></li>
<li><a class="reference internal" href="#url-reconstruction">URL Reconstruction</a></li>
<li><a class="reference internal" href="#supporting-older-2-2-versions-of-python">Supporting Older (&lt;2.2) Versions of Python</a></li>
<li><a class="reference internal" href="#optional-platform-specific-file-handling">Optional Platform-Specific File Handling</a></li>
</ul>
</li>
<li><a class="reference internal" href="#questions-and-answers">Questions and Answers</a></li>
<li><a class="reference internal" href="#proposed-under-discussion">Proposed/Under Discussion</a></li>
<li><a class="reference internal" href="#acknowledgements">Acknowledgements</a></li>
<li><a class="reference internal" href="#references">References</a></li>
<li><a class="reference internal" href="#copyright">Copyright</a></li>
</ul>
<br>
<a id="source" href="https://github.com/python/peps/blob/main/peps/pep-0333.rst">Page Source (GitHub)</a>
</nav>
</section>
<script src="../_static/colour_scheme.js"></script>
<script src="../_static/wrap_tables.js"></script>
<script src="../_static/sticky_banner.js"></script>
</body>
</html>