Response and sending content to the browser

2 views
Skip to first unread message

jose

unread,
Aug 9, 2006, 2:50:27 PM8/9/06
to pylons-discuss
I've got what I hope is a simple question,

a WSGI response should be in iterable object, but Response doesn't
behave that way. What I would like to be able to do, especially for
long processes is send info the the browser incrementally, which you
would be able to do with the yield statement. I know I can write my
own WSI app as it shows in the 0.9 wscgi docs, however if you do that
then it looks like you lose the ability to set actions and stuff like
that in the controller.

so the question is how do I use yield in a normal pylons controller?
Jose

Ben Bangert

unread,
Aug 9, 2006, 6:33:29 PM8/9/06
to pylons-...@googlegroups.com

Your controller is expected to yield a normal WSGI response when its
called. So if you want to handle the WSGI part yourself, you can do so
by overriding the __call__ on your WSGI Controller. The code for the
current one is:
http://pylonshq.com/docs/0.9/pylons/controllers.py.html?f=112&l=146#112

You'll probably want to retain most of it, except instead of expecting
the action to return a Response object, you can proceed to handle that
yourself.

Alternatively, you can do yield without touching the controller at all,
by defining the content as the iterable. Here's a short one for an
action:

def view(self):
def numbers():
x = 0
while 1:
yield x
x += 1
if x > 40: break
resp = Response()
resp.content = numbers()
return resp

Something to note, somewhere in the middleware right now, that iterable
is having list() called on it. I'm looking through to remove this, or
at least make it optional so you can directly return iter's of large
things that you definitely don't want flooding into your ram. The above
code should keep putting out numbers forever without affecting ram, but
in fact right now will eat ram until you kill the thread and never
return anything.

HTH,
Ben

Ben Bangert

unread,
Aug 9, 2006, 7:44:48 PM8/9/06
to pylons-...@googlegroups.com
On Aug 9, 2006, at 3:33 PM, Ben Bangert wrote:

> Something to note, somewhere in the middleware right now, that iterable
> is having list() called on it. I'm looking through to remove this, or
> at least make it optional so you can directly return iter's of large
> things that you definitely don't want flooding into your ram. The above
> code should keep putting out numbers forever without affecting ram, but
> in fact right now will eat ram until you kill the thread and never
> return anything.

This has been fixed in the latest Pylons trunk, it will now stream the
data from an iterable without list()'ing it anywhere. A new release of
Pylons with the minor fixes from the past 2 weeks will be out by
Friday, 0.9.1.

Cheers,
Ben

Jose Galvez

unread,
Aug 9, 2006, 7:53:07 PM8/9/06
to pylons-...@googlegroups.com
Thanks for looking into this.  I'll take a look at the new code after fri, for what I want to do it might be better to __call__ function and not use the response object at all.  I'll have to see.  thanks
Jose

Ian Bicking

unread,
Aug 15, 2006, 11:47:09 PM8/15/06
to pylons-...@googlegroups.com
jose wrote:
> I've got what I hope is a simple question,
>
> a WSGI response should be in iterable object, but Response doesn't
> behave that way. What I would like to be able to do, especially for
> long processes is send info the the browser incrementally, which you
> would be able to do with the yield statement. I know I can write my
> own WSI app as it shows in the 0.9 wscgi docs, however if you do that
> then it looks like you lose the ability to set actions and stuff like
> that in the controller.

Is there an easy way to forward the request to a WSGI application? If
there is, something like paste.fileapp.FileApp might do what you want
(with some added features), but you still get first shot at the request
and actions and all that.


--
Ian Bicking | ia...@colorstudy.com | http://blog.ianbicking.org

Philip Jenvey

unread,
Aug 16, 2006, 2:31:05 PM8/16/06
to pylons-...@googlegroups.com

From within your controller action, do:

return FileApp(path)(request.environ, self.start_response)

--
Philip Jenvey

Reply all
Reply to author
Forward
0 new messages