Flaskに保存せずにファイルデータを読み取る


112

私は最初のフラスコアプリケーションを書いています。私はファイルのアップロードを扱っており、基本的にはアップロードしたファイルのデータ/コンテンツを保存せずに読み取り、結果のページに印刷することを望んでいます。はい、ユーザーは常にテキストファイルをアップロードすると想定しています。

これが私が使用している簡単なアップロード機能です:

@app.route('/upload/', methods=['GET', 'POST'])
def upload():
    if request.method == 'POST':
        file = request.files['file']
        if file:
            filename = secure_filename(file.filename)
            file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
            a = 'file uploaded'

    return render_template('upload.html', data = a)

現在、ファイルを保存していますが、ファイルのコンテンツ/データを格納するための「a」変数が必要です。

回答:


137

FileStoragestreamフィールドを含みます。このオブジェクトはIOまたはファイルオブジェクトを拡張する必要があるため、readおよびその他の同様のメソッドを含む必要があります。フィールドオブジェクトの属性FileStorageも拡張するstreamため、file.read()代わりにを使用できますfile.stream.read()。また、別のIOまたはファイルオブジェクトにコピーするためのsave引数dstとして、StringIOまたは他のIOまたはファイルオブジェクトを引数として使用FileStorage.streamできます。

ドキュメントを参照してください:http : //flask.pocoo.org/docs/api/#flask.Request.filesおよびhttp://werkzeug.pocoo.org/docs/datastructures/#werkzeug.datastructures.FileStorage


1
簡単な例:file = request.files.get('file') filetype = magic.from_buffer(file.read(1024))
endolith 2014

7
@ user2480542様 同じ問題が発生しています。クライアントがアップロードしたファイルの内容をどのように読んだか説明できますか?file.read()を呼び出していますが、何も取得していません。ありがとう!
tmthyjames 2015

1
@tmthyjames f = request.files['file']は、アップロードされたファイル(リクエスト内)を変数( "f")に配置します。次にf.read()、上記のコードを使用して動作します。print f.read()ターミナルで正しく見えるジャンクが表示されるのはいつですか。お役に立てば幸いです。
マルク

6
:あなたは、ファイルをアップロードし、バイナリストリームを持っている場合は、簡単TextIOWrapperでそれをラップすることにより、テキストストリームに変換することができます mystring = TextIOWrapper(binary_stream)
オランダの名作

6
f.read()私にも何ももたらさなかった。最初に電話f.seek(0)をかけたのが私にとってはトリックでした。
w177us

11

標準のFlaskを使用したい場合-アップロードされたファイルのサイズが500kbを超える場合、一時ファイルの保存を回避する方法はありません。500kb未満の場合-ファイルのコンテンツをメモリに保存する "BytesIO"を使用し、500kbを超える場合-TemporaryFile()にコンテンツを保存します(werkzeugのドキュメントに記載されています)。どちらの場合も、アップロードされたファイル全体が受信されるまで、スクリプトはブロックされます。

私が見つけたこれを回避する最も簡単な方法は:

1)着信データのすべての処理を行う独自のファイルのようなIOクラスを作成します

2)スクリプトで、Requestクラスを独自のクラスでオーバーライドします。

class MyRequest( Request ):
  def _get_file_stream( self, total_content_length, content_type, filename=None, content_length=None ):
    return MyAwesomeIO( filename, 'w' )

3)Flaskのrequest_classを独自のものに置き換えます。

app.request_class = MyRequest

4)ビールを飲みに行く:)


0

私はまったく同じことをしようとしていた、テキストファイル(実際にはパンダのCSV)を開きます。それをコピーしたくはなく、単に開きたいだけです。form-WTFには優れたファイルブラウザーがありますが、ファイルを開いて一時ファイルを作成し、それをメモリストリームとして表示します。フードの下で少しの作業で、

form = UploadForm() 
 if form.validate_on_submit(): 
      filename = secure_filename(form.fileContents.data.filename)  
      filestream =  form.fileContents.data 
      filestream.seek(0)
      ef = pd.read_csv( filestream  )
      sr = pd.DataFrame(ef)  
      return render_template('dataframe.html',tables=[sr.to_html(justify='center, classes='table table-bordered table-hover')],titles = [filename], form=form) 

0

私は自分のソリューションを共有します(フラスコ内のgoogleバケットに接続するようにすべてがすでに構成されていると仮定)

from google.cloud import storage

@app.route('/upload/', methods=['POST'])
def upload():
    if request.method == 'POST':
        # FileStorage object wrapper
        file = request.files["file"]                    
        if file:
            os.environ["GOOGLE_APPLICATION_CREDENTIALS"] = app.config['GOOGLE_APPLICATION_CREDENTIALS']
            bucket_name = "bucket_name" 
            storage_client = storage.Client()
            bucket = storage_client.bucket(bucket_name)
            # Upload file to Google Bucket
            blob = bucket.blob(file.filename) 
            blob.upload_from_string(file.read())

私の投稿

フラスコ内のGoogleバケットにダイレクト


-1

メモリ内のファイルをディスクにダンプする場合。このコードは使用できます

  if isinstanceof(obj,SpooledTemporaryFile):
    obj.rollover()

-1

私たちは単にしました:

import io
from pathlib import Path

    def test_my_upload(self, accept_json):
        """Test my uploads endpoint for POST."""
        data = {
            "filePath[]": "/tmp/bin",
            "manifest[]": (io.StringIO(str(Path(__file__).parent /
                                           "path_to_file/npmlist.json")).read(),
                           'npmlist.json'),
        }
        headers = {
            'a': 'A',
            'b': 'B'
        }
        res = self.client.post(api_route_for('/test'),
                               data=data,
                               content_type='multipart/form-data',
                               headers=headers,
                               )
        assert res.status_code == 200

-1

機能中

def handleUpload():
    if 'photo' in request.files:
        photo = request.files['photo']
        if photo.filename != '':      
            image = request.files['photo']  
            image_string = base64.b64encode(image.read())
            image_string = image_string.decode('utf-8')
            #use this to remove b'...' to get raw string
            return render_template('handleUpload.html',filestring = image_string)
    return render_template('upload.html')

htmlファイル

<html>
<head>
    <title>Simple file upload using Python Flask</title>
</head>
<body>
    {% if filestring %}
      <h1>Raw image:</h1>
      <h1>{{filestring}}</h1>
      <img src="data:image/png;base64, {{filestring}}" alt="alternate" />.
    {% else %}
      <h1></h1>
    {% endif %}
</body>

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.