Flask で CSV 出力

修正版出来ました。一時ファイル作らないバージョン。
http://d.hatena.ne.jp/blaue_fuchs/20110905

        • -

最近 Flask ばっかり触りすぎて Django の勘を失いつつあるカエルです。こんばんは。
Flask、ホント楽過ぎる。日本語情報少ないけど。


というわけで、Flask で CSV 出力。

return Response(csv_file, mimetype="application/octet-stream")

とかだと上手く出力できなかったので、試行錯誤しました。
以下、その結果のソース。
無理矢理1ファイルでまとめました。


# -*- coding: utf-8 -*-
import codecs
import csv
import datetime
from flask import Flask, Response, make_response
app = Flask(__name__)


@app.route("/")
def root():
     return Response("<a href='/dl/'>DL</a>")


@app.route("/dl/")
def make_csv():
     response = make_response()
     response.data = get_csv_data()
     response.headers['Content-Type'] = 'application/octet-stream'
     response.headers['Content-Disposition'] = u'attachment; filename=データ.csv'
     return response


def get_csv_data():
     result = ""
     data = make_data()
     file_name = make_file(data)
     result = read_file(file_name)
     return result


def read_file(file_name):
     csv_file = codecs.open(file_name, u"r", u"utf-8")
     data = csv_file.read()
     csv_file.close()
     return data


def make_file(data):
     file_name = "temp.csv"
     csv_file = codecs.open(file_name, u"w")
     writer = csv.writer(csv_file, quoting=csv.QUOTE_NONNUMERIC)
     writer.writerows(data)
     csv_file.close()
     return file_name


def make_data():
     result = []
     result.append(("1", "p", "python", 100, "あ"))
     result.append(("2", "y", "python", 200, "い"))
     result.append(("3", "t", "python", 300, "う"))
     result.append(("4", "h", "python", 400, "え"))
     result.append(("5", "o", "python", 500, "お"))
     result.append(("6", "n", "python", 600, "か"))
     return result


if __name__ == '__main__':
     app.run(debug=True)


一時ファイルを作るので、複数同時アクセスがありうる場合は
ファイル名を重複させないよう工夫しないと駄目ですね。


ファイルに書きこんで一旦閉じてから、再度読み込んでたりとか、
なぁんか泥臭いんで若干嫌なのですが、他に良いやり方あるのかな…。
ご参考になれば幸い。



とご指摘いただいたので修正しました。
s/datas/data/g で。
…我ながら酷いミスだ…。orz


と、ファイル open 回避の対案を頂いたので、後ほど試して反映します。多謝!