Flask – how to write csv file & save using prefilled value of the filename (response.headers["Content-Disposition"]="attachment; filename=xxx")
Suretha Weweje
surethaweweje at gmail.com
Fri Aug 6 11:50:02 EDT 2021
I am trying to upload a CSV file with flask, read and process one line at a
time while iterating through all rows of the file and write the results
back to a new CSV file. My python script produces the correct results on
its own, but I am not able to get the same results when using Flask. I am
new to flask.
The CSV file that I want to work on has different row lengths and each row
contains the pair of column names(headers) and cell values for that row.
***Short example of the CSV file content** I am trying to upload with flask*
3012,"COMPANY NAME",3015,"LIVE",3020,916301,3022,"LB45",9999
4000,"92001",4018,"FORM5",4022,"A",4025,2017,4030,"SMITH",4040,"ANN",4060,’C5,9999
4000,"92002",4018,"FORM5",4022,"A",4025,2017,4030,"BROWN",4040,"JOE",4075,89500,9999
***The expected results***
3012 3015 3020 3022 4000 4018
4022 4025 4030 4040 4060
4075
COMP NAME "LIVE" 916301 "LB45"
"92001" "FORM5" "A" 2017 "SMITH" "ANN "
C5
"92002" "FORM5" "A" 2017 "BROWN" "JOE"
89500
*** This is my code so far ***
from flask import Flask*, *make_response*, **request*
import io
import csv
*app *= Flask(__name__)
def transform(*text_file_contents*):
*output *= []
*strip9999 *= []
*the_headers *= []
*headers_new *= []
*num_lines *=
*0 **new *= *text_file_contents*.replace("9999"*, *"")
*csv_reader *= csv.reader(*new*)
for *line *in *csv_reader*:
*dictionary *= str(*line*)
*strip9999*.append(*dictionary*)
for *row *in *strip9999*:
*it *= iter(*row*)
*res_dct *= dict(zip(*it**, **it*))
*output*.append(*res_dct*)
for *key *in *res_dct*:
*f_name *=
*key the_headers*.append(*f_name*)
*the_headers *= list(set(sorted(*the_headers*)))
*headers_new *= sorted(*the_headers*)
*mywriter = csv.DictWriter('results.csv', fieldnames=headers_new)*
*mywriter*.writeheader()
for *data *in *output*:
*mywriter*.writerow(*data*)
*num_lines *+=
*1 *return
*data *@*app*.route('/')
def form():
return """
<html>
<body>
<h1>Select File To Convert</h1>
<form action="/transform" method="post"
enctype="multipart/form-data">
<input type="file" name="data_file" />
<input type="submit" />
</form>
</body>
</html>
"""
@*app*.route('/transform'*, *methods=["POST"])
def transform_file():
*f *= *request*.files['data_file']
if not *f*:
return "No file"
*stream *= io.StringIO(*f*.stream.read().decode("UTF8")*, *newline=None)
csv_input = csv.reader(*stream*)
*stream*.seek(*0*)
*result = transform(stream.read())*
*response *= make_response(*result*)
*response*.headers["Content-Disposition"] = "attachment;
filename=result.csv"
return
*response *if __name__ == "__main__":
*app*.run(debug=True)
***The following TypeError**:* *argument 1 must have a "write" method *is
displayed noting these two problems:
- result = transform(stream.read()) and
- mywriter = csv.DictWriter('results.csv', fieldnames=headers_new)
I am not sure if the problem might be with mywriter because the original
Python script below work fine as
with open('results.csv', 'x', newline='') as new_file:
mywriter = csv.DictWriter(new_file, fieldnames=headers_new)
mywriter.writeheader()
whereas in Flask I am not sure how to link data written using the function
to **response.headers["Content-Disposition"] = "attachment;
filename=result.csv"**
More information about the Python-list
mailing list