Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to render a template and send a file simultaneously with flask [duplicate]

Tags:

python

flask

The goal of this flask application is to fill a form, parse the data of the resulting form, launch a build, zip and send this build to the user.

Everything is working fine, but I want that once the form is filled, the user is redirected to a waiting page, if this is possible of course.

This is my code at the moment:

def create_and_download_build(form)
        # Some parsing in the beginning of the function, the build etc...
        os.system('tar -zcvf build.tar.gz dist/')
        headers = {"Content-Disposition": "attachment; filename=build.tar.gz"}
        with open('build.tar.gz', 'r+b') as data_file:
            data = data_file.read()
        response = make_response(render_template('waiting.html'), (data, headers))
        return response

This is where this function is declared, in my _init__.py:

@app.route('/', methods=('GET', 'POST'))
    def index():
        form = MyForm() # MyForm is a class in which there is some 
                        # wtform field (for example TextField)
        if form.validate_on_submit(): # This is called once the form is validated
            return create_and_download_build(request.form)
        return render_template('index.html', form=form)

It doesn't work, I receive this error for the line in which I call make_response: AttributeError: 'tuple' object has no attribute 'decode'

If I change make_response to : response = make_response((data, headers)), it will properly upload the file, but it will not render the waiting.html page.
Same if I change it to : response = make_response(render_template('waiting.html')), it will render the template, but it will not download the file.

Is there a method to do both action?

like image 595
maje Avatar asked Oct 17 '17 11:10

maje


1 Answers

Short answer: No. You cannot return different responses at once, obviously.

The quick and dirty solution would be to return the HTML response with your "waiting.html" template, and from this template add some javascript to launch the download.

NB this has nothing to do with flask BTW, you'd have the very same behaviour with any server-side language/techno. It's just how HTTP works.

like image 111
bruno desthuilliers Avatar answered Oct 22 '22 03:10

bruno desthuilliers