On Wed, Nov 25, 2009 at 2:03 PM, Tres Seaver <span dir="ltr">&lt;<a href="mailto:tseaver@palladion.com">tseaver@palladion.com</a>&gt;</span> wrote:<br><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">

<div class="im">Aaron Watters wrote:<br>
&gt;<br>
&gt; --- On Wed, 11/25/09, Chris Dent &lt;<a href="mailto:chris.dent@gmail.com">chris.dent@gmail.com</a>&gt; wrote:<br>
&gt;<br>
&gt;&gt; From: Chris Dent &lt;<a href="mailto:chris.dent@gmail.com">chris.dent@gmail.com</a>&gt;<br>
&gt;&gt; I can (barely) relate to some of the complaints that<br>
&gt;&gt; start_response is a pain in the ass, but environ, to me, is<br>
&gt;&gt; not broken.<br>
&gt;<br>
&gt; I agree.  It maps nicely onto the underlying protocol<br>
&gt; and WSGI is supposed to be low level right?<br>
&gt;<br>
&gt; The biggest problem with start_response is that after<br>
&gt; you evaluate<br>
&gt;<br>
&gt;     iterable = application(env, start_response)<br>
&gt;<br>
&gt; Sometimes the start_response has been called and sometimes<br>
&gt; it hasn&#39;t, and this can break middlewares when they haven&#39;t<br>
&gt; been tested both ways (repose.who for example seems to<br>
&gt; assume it has been called).<br>
<br>
</div>Since version 1.0.13 (2009-04-24), repoze.who&#39;s middleware is very<br>
careful to dance around the fact that an application is not required to<br>
have called &#39;start_response&#39; on return, but *must* call it before<br>
returning the first chunk from its iterator.  That bit of flexibility in<br>
 PEP 333 is likely there to support *some* use case, but it makes<br>
&#39;start_response&#39; a *big* pain to work with in middleware which needs to<br>
to &quot;egress&quot; processing of headers.<br></blockquote></div><div><br></div><div>Just in terms of history, I think I&#39;m to blame on this one, as I argued quite vigorously for start_response.  The reason being that at the time frameworks that had a concept of &quot;streaming&quot; usually did it by writing to the response.  While the names were different depending on the framework, this was the common way to do streaming:</div>

<div><br></div><div>def file_app(req):</div><div>    filename = ...</div><div>    req.response.setHeader(&#39;Content-Type&#39;, mimetypes.guess_type(os.path.splitext(filename)[1])[0])</div><div>    # I believe most did not stream by default...</div>

<div>    req.response.stream()</div><div>    fp = open(filename, &#39;rb&#39;)</div><div>    while 1:</div><div>        chunk = fp.read(4096)</div><div>        if not chunk: break</div><div>        req.response.write(chunk)</div>

<div><br></div><div>To support that style of streaming start_response was added.  I think PJE also had some notion of Comet-style interactions, and maybe something related to async, leading to the specific restrictions on how written content should be handled.  I still don&#39;t entirely understand the use case underlying that.  But anyway, that&#39;s some of the motivation.  start_response is still useful for retrofitting support for frameworks from time to time, but all the modern frameworks work differently these days making start_response seem less necessary.</div>

<br>-- <br>Ian Bicking  |  <a href="http://blog.ianbicking.org">http://blog.ianbicking.org</a>  |  <a href="http://topplabs.org/civichacker">http://topplabs.org/civichacker</a><br>