librelist archives

« back to archive

Big passthrough download without response object?

Big passthrough download without response object?

From:
Marten Lehmann
Date:
2010-11-05 @ 22:58
Hello,

I want to send response content to the user directly, is this possible?

So far everything that is returned from a template engine or individual 
function seems to go through a flask.Flask.Response object before it is 
returned to the user by a HTTP response.

In my case this is fine for the basic web application with flask, but 
part of the application is to return a bigger file to download which 
already exists in the filesystem. Is there any way to circumvent the 
common flask model, so everything that is printed to stdout will be sent 
to be user directly (even the content-type), so that only the routing 
and initial request processing is used from flask in that case?

Kind regards
Marten

Re: [flask] Big passthrough download without response object?

From:
Thadeus Burgess
Date:
2010-11-05 @ 23:56
from flask import send_static_file

--
Thadeus




On Fri, Nov 5, 2010 at 5:58 PM, Marten Lehmann <lehmann@cnm.de> wrote:

> Hello,
>
> I want to send response content to the user directly, is this possible?
>
> So far everything that is returned from a template engine or individual
> function seems to go through a flask.Flask.Response object before it is
> returned to the user by a HTTP response.
>
> In my case this is fine for the basic web application with flask, but
> part of the application is to return a bigger file to download which
> already exists in the filesystem. Is there any way to circumvent the
> common flask model, so everything that is printed to stdout will be sent
> to be user directly (even the content-type), so that only the routing
> and initial request processing is used from flask in that case?
>
> Kind regards
> Marten
>

Re: [flask] Big passthrough download without response object?

From:
Marten Lehmann
Date:
2010-11-06 @ 00:10
Well,

On 06.11.2010 00:56, Thadeus Burgess wrote:
> from flask import send_static_file

but how do I specify special headers like content-type and 
content-disposition here?

Kind regards
Marten

Re: [flask] Big passthrough download without response object?

From:
Simon Sapin
Date:
2010-11-06 @ 03:39
Le 06/11/2010 09:10, Marten Lehmann a écrit :
> On 06.11.2010 00:56, Thadeus Burgess wrote:
>> >  from flask import send_static_file
> but how do I specify special headers like content-type and
> content-disposition here?

See flask.send_file and it’s optional arguments:
http://flask.pocoo.org/docs/api/#flask.send_file

flask.send_from_directory might also be interesting:
http://flask.pocoo.org/docs/api/#flask.send_from_directory

Regards,
-- 
Simon Sapin

Re: [flask] Big passthrough download without response object?

From:
Robert Mela
Date:
2010-11-06 @ 02:11
I think request will accept anything iteratable, so you can pass it an 
open file:

     from flask import Flask,Response

     app=Flask(__name__)

     @app.route('/')
     def sendfile():
             return Response(open('staticfile.py','r'), 
content_type='text/plain' )

     app.run()

On 11/5/10 8:10 PM, Marten Lehmann wrote:
> Well,
>
> On 06.11.2010 00:56, Thadeus Burgess wrote:
>> from flask import send_static_file
> but how do I specify special headers like content-type and
> content-disposition here?
>
> Kind regards
> Marten
>

Re: [flask] Big passthrough download without response object?

From:
Marten Lehmann
Date:
2010-11-11 @ 14:58
Hello,

> I think request will accept anything iteratable, so you can pass it an
> open file:
>
> from flask import Flask,Response
>
> app=Flask(__name__)
>
> @app.route('/')
> def sendfile():
> return Response(open('staticfile.py','r'), content_type='text/plain' )
>
> app.run()

this looks reasonable (and other examples as well). The special 
situation in my case is, that I'm working with temporary files. That 
means, I'm creating them on the fly, then the content shall be sent to 
the client and afterwards the file shall be deleted. If the client makes 
another request, the file will be newly created.

My machine has 8 GB of RAM and the temporary files are at a maximum of 
1GB each, mostly even less then 100 MB. So if it's not possible for the 
function within the flask app to send the content step by step, but only 
all at once, then probably reading everything into memory and returning 
it (return f.read()) seems to be the only option here. Or any other idea?

Kind regards
Marten

Re: [flask] Big passthrough download without response object?

From:
Robert Mela
Date:
2010-11-14 @ 02:10
could not decode message

Re: [flask] Big passthrough download without response object?

From:
Robert Mela
Date:
2010-11-17 @ 15:21
could not decode message

Re: [flask] Big passthrough download without response object?

From:
Simon Sapin
Date:
2010-11-11 @ 23:36
Le 11/11/2010 23:58, Marten Lehmann a écrit :
> this looks reasonable (and other examples as well). The special
> situation in my case is, that I'm working with temporary files. That
> means, I'm creating them on the fly, then the content shall be sent to
> the client and afterwards the file shall be deleted. If the client makes
> another request, the file will be newly created.
>
> My machine has 8 GB of RAM and the temporary files are at a maximum of
> 1GB each, mostly even less then 100 MB. So if it's not possible for the
> function within the flask app to send the content step by step, but only
> all at once, then probably reading everything into memory and returning
> it (return f.read()) seems to be the only option here. Or any other idea?

Hi,

If you temporary file is on the filesystem or a file-like object, see 
flask.send_file:
http://flask.pocoo.org/docs/api/#flask.send_file

Otherwise, you need something like this:

http://flask.pocoo.org/mailinglist/archive/2010/11/3/using-yield/#478b0c1829b5263700da1db7d2d22c79

Regards,
-- 
Simon Sapin

Re: [flask] Big passthrough download without response object?

From:
Zahari Petkov
Date:
2010-11-11 @ 15:12
On Thu, Nov 11, 2010 at 4:58 PM, Marten Lehmann <lehmann@cnm.de> wrote:
> Hello,
>
>> I think request will accept anything iteratable, so you can pass it an
>> open file:
>>
>> from flask import Flask,Response
>>
>> app=Flask(__name__)
>>
>> @app.route('/')
>> def sendfile():
>> return Response(open('staticfile.py','r'), content_type='text/plain' )
>>
>> app.run()
>
> this looks reasonable (and other examples as well). The special
> situation in my case is, that I'm working with temporary files. That
> means, I'm creating them on the fly, then the content shall be sent to
> the client and afterwards the file shall be deleted. If the client makes
> another request, the file will be newly created.
>
> My machine has 8 GB of RAM and the temporary files are at a maximum of
> 1GB each, mostly even less then 100 MB. So if it's not possible for the
> function within the flask app to send the content step by step, but only
> all at once, then probably reading everything into memory and returning
> it (return f.read()) seems to be the only option here. Or any other idea?
>
> Kind regards
> Marten
>

Just a quick idea, not sure whether it will work for you, but
something to keep in mind is that you may delegate such responsibility
to your HTTP server:

http://wiki.nginx.org/XSendfile

Thanks,
Zahari

Re: [flask] Big passthrough download without response object?

From:
Robert Mela
Date:
2010-11-06 @ 02:23
IIRC, you can also pass a named "headers" parameter to the request for 
any arbitrary headers.

      return Request( open("foo.txt", "r", headers={ 
'Content-type':'text/plain' } )

Also check out the doc on werkzeug Headers at 
http://werkzeug.pocoo.org/documentation/dev/datastructures.html#http-related

It uses Content-disposition as one of the example headers.

from flask import Flask,Response
from werkzeug import Headers

     app=Flask(__name__)

     @app.route('/')
     def sendfile():
             h=Headers()
             h.add( 'Content-type', 'text/plain', charset='utf8'  )
             h.add( 'Content-disposition', 'attachment', 
filename='foo.txt' )
             return Response(open('myfile.txt','r'), headers=h )

app.run(debug=True)



And also you can use the headers object, which is kinda neat in how it 
allows adding headers with parameters

      headers=Header
On 11/5/10 10:11 PM, Robert Mela wrote:
> I think request will accept anything iteratable, so you can pass it an 
> open file:
>
>     from flask import Flask,Response
>
>     app=Flask(__name__)
>
>     @app.route('/')
>     def sendfile():
>             return Response(open('staticfile.py','r'), 
> content_type='text/plain' )
>
>     app.run()
>
> On 11/5/10 8:10 PM, Marten Lehmann wrote:
>> Well,
>>
>> On 06.11.2010 00:56, Thadeus Burgess wrote:
>>> from flask import send_static_file
>> but how do I specify special headers like content-type and
>> content-disposition here?
>>
>> Kind regards
>> Marten
>>
>

Re: [flask] Big passthrough download without response object?

From:
alice ni
Date:
2010-11-06 @ 01:18
Would this be of any help:-

mimetype = 'image/png'

return 
current_app.response_class(qu.pic,mimetype=mimetype,direct_passthrough=False)

I dont know what direct_passthrough does by the way..lol, but I guess
possibly changing it to true might solve your problem..If yes please
let me know too



On Sat, Nov 6, 2010 at 5:40 AM, Marten Lehmann <lehmann@cnm.de> wrote:

> Well,
>
> On 06.11.2010 00:56, Thadeus Burgess wrote:
> > from flask import send_static_file
>
> but how do I specify special headers like content-type and
> content-disposition here?
>
> Kind regards
> Marten
>