10

I'm trying to make work a code that I found at this URL: http://code.runnable.com/UiIdhKohv5JQAAB6/how-to-download-a-file-generated-on-the-fly-in-flask-for-python

My goal is to be able to download a file on a web browser when the user access to a web service on my Flask-base Python server.

So I wrote the following code:

@app.route("/api/downloadlogfile/<path>")
def DownloadLogFile (path = None):
    if path is None:
        self.Error(400)

    try:
        with open(path, 'r') as f:
            response  = make_response(f.read())
        response.headers["Content-Disposition"] = "attachment; filename=%s" % path.split("/")[2]

        return response
    except Exception as e:
        self.log.exception(e)
        self.Error(400)

But this code doesn't seem to work. Indeed I get an error that I didn't manage to fix:

Traceback (most recent call last):
File "C:\Python27\lib\site-packages\gevent\pywsgi.py", line 508, in handle_one_response
self.run_application()
File "C:\Python27\lib\site-packages\geventwebsocket\handler.py", line 88, in run_application
return super(WebSocketHandler, self).run_application()
File "C:\Python27\lib\site-packages\gevent\pywsgi.py", line 495, in run_application
self.process_result()
File "C:\Python27\lib\site-packages\gevent\pywsgi.py", line 484, in process_result
for data in self.result:
File "C:\Python27\lib\site-packages\werkzeug\wsgi.py", line 703, in __next__
return self._next()
File "C:\Python27\lib\site-packages\werkzeug\wrappers.py", line 81, in _iter_encoded
for item in iterable:
TypeError: 'Response' object is not iterable

I update my Flask and Werkzeug package to the last version but without success.

If anybody have an idea it would be great.

Thanks in advance

4
  • Where are these files on the file system? Commented Jun 21, 2016 at 7:00
  • If you are not dynamically generating the file then why not use flask.send_file()? Commented Jun 21, 2016 at 7:04
  • Even if you were dynamically generating the best practice is to save the file to the disk and then serve it through Apache or nginx since web servers are much much more efficient at serving files than flask. Commented Jun 21, 2016 at 7:06
  • @donkopotamus These file are in a "log" repository at the root of the Python web server. So they are not dynamically generated. @KDawG I already tried to use flask.send_file but with the same result: "'Response' object is not iterable". Commented Jun 21, 2016 at 7:09

1 Answer 1

22

The best way to solve this issue is to use the already predefined helper function send_file() in flask:

from flask import send_file

@app.route("/api/downloadlogfile/<path>")
def DownloadLogFile (path = None):
    if path is None:
        self.Error(400)
    try:
        return send_file(path, as_attachment=True)
    except Exception as e:
        self.log.exception(e)
        self.Error(400)
Sign up to request clarification or add additional context in comments.

3 Comments

what is self?? ?
send_file can be used by importing it with from flask import send_file
self in python is basically equivalent to 'this' in javascript. Is used when a class is defined -- there is only a function here, and this isn't passed to the function, so its understandable that the reference to this doesn't make any sense here.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.