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