tpositive
tpositive

Reputation: 11

Flask send_file() giving error TypeError: send_file() missing 1 required positional argument: 'environ'

So I am new to flask and have been working on developing a little web app locally on my computer. I haven't run into too many issues, but I have not been able to get my webpage to return a csv file when clicking on a link. I get an error stating that the environ variable is missing, to my understanding I can set this to be a server that then serves up the document, however, I am hoping to just do this all locally on my machine.

@app.route('/sessions/csv_file')
def get_csv_file():
   return send_file('./sessions.csv',mimetype='csv',as_attachment=True, 
   download_name='sessions.csv')

edit:This code gives me the following error: TypeError: send_file() missing 1 required positional argument: 'environ'

I was given advice to try using my app as the environ variable:

app = Flask(__name__)    
@app.route('/sessions/csv_file')
    def get_csv_file():
       return send_file('./sessions.csv',mimetype='csv',as_attachment=True, 
       download_name='sessions.csv', environ=app)

But this give me the following error: TypeError: get() takes 2 positional arguments but 3 were given

I have also tried this with send_directory() and run into the same environ error. If anyone is able to point me in the right direction that would be greatly appreciated!

edit: send_file() is an import

from werkzeug.utils import send_file

Upvotes: 1

Views: 2319

Answers (1)

Bijan
Bijan

Reputation: 136

As mentioned in your post's comments there is two version of send_file in flask.

one from werkzeug.utils which you can import like:

from werkzeug.utils import send_file

another from flask package as

from flask import send_file

send_file from flask package actually calls send_file of werkzeug.utils with request.environ. Here is the flask's send_file implementation:

return werkzeug.utils.send_file(
    **_prepare_send_file_kwargs(
        path_or_file=path_or_file,
        environ=request.environ,
        mimetype=mimetype,
        as_attachment=as_attachment,
        download_name=download_name,
        attachment_filename=attachment_filename,
        conditional=conditional,
        etag=etag,
        add_etags=add_etags,
        last_modified=last_modified,
        max_age=max_age,
        cache_timeout=cache_timeout,
    )

So to fix this error replace send_file from werkzeug with flask version

from flask import send_file

Or assign your send_file's last parameter(environ) with request.environ as below:

return send_file('./sessions.csv',mimetype='csv',as_attachment=True, 
   download_name='sessions.csv', environ=request.environ)

However there is still a little difference: relative paths of flask's send_file are based on root path(if you are using flask blueprints it will be the current python package). But werkzeug paths refers to execution root(parent of the current python package usually).

Upvotes: 2

Related Questions