Membaca data file tanpa menyimpannya di Flask


112

Saya sedang menulis aplikasi termos pertama saya. Saya berurusan dengan unggahan file, dan pada dasarnya yang saya inginkan adalah membaca data / konten file yang diunggah tanpa menyimpannya dan kemudian mencetaknya pada halaman yang dihasilkan. Ya, saya berasumsi bahwa pengguna selalu mengupload file teks.

Berikut adalah fungsi unggah sederhana yang saya gunakan:

@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)

Saat ini, saya sedang menyimpan file, tetapi yang saya butuhkan adalah variabel 'a' untuk memuat konten / data file .. ada ide?

Jawaban:


137

FileStorageberisi streambidang. Objek ini harus memperluas IO atau objek file, sehingga harus berisi readdan metode serupa lainnya. FileStoragejuga memperluas streamatribut objek bidang, jadi Anda bisa menggunakan file.read()saja file.stream.read(). Anda juga dapat menggunakan saveargumen dengan dstparameter as StringIOatau IO lain atau objek file untuk disalin FileStorage.streamke IO atau objek file lain.

Lihat dokumentasi: http://flask.pocoo.org/docs/api/#flask.Request.files dan http://werkzeug.pocoo.org/docs/datastructures/#werkzeug.datastructures.FileStorage .


1
contoh cepat:file = request.files.get('file') filetype = magic.from_buffer(file.read(1024))
endolith

7
hai @ user2480542. Saya mengalami masalah yang sama. Dapatkah Anda menjelaskan bagaimana Anda membaca konten file yang diupload klien? Saya menelepon file.read () tetapi tidak mendapatkan apa-apa. Terima kasih!
tmthyjames

1
@tyyames f = request.files['file']meletakkan file yang diunggah (dalam permintaan) ke var ("f"). Kemudian f.read()bekerja menggunakan kode di atas. kapan print f.read()saya mendapatkan benar mencari sampah di terminal. Semoga membantu.
Marc

6
Jika Anda mengunggah file dan memiliki streaming biner, Anda dapat dengan mudah mengubahnya menjadi aliran teks dengan membungkusnya di TextIOWrApper: mystring = TextIOWrapper(binary_stream)
Dutch Masters

7
f.read()tidak menghasilkan apa-apa untukku juga. Menelepon lebih dulu f.seek(0)berhasil bagi saya.
w177us

12

Jika Anda ingin menggunakan perangkat Flask standar - tidak ada cara untuk menghindari penyimpanan file sementara jika ukuran file yang diunggah> 500kb. Jika lebih kecil dari 500kb - ia akan menggunakan "BytesIO", yang menyimpan konten file dalam memori, dan jika lebih dari 500kb - ia menyimpan konten dalam TemporaryFile () (seperti yang dinyatakan dalam dokumentasi werkzeug ). Dalam kedua kasus tersebut, skrip Anda akan diblokir hingga keseluruhan file yang diunggah diterima.

Cara termudah untuk mengatasi ini yang saya temukan adalah:

1) Buat kelas IO seperti file Anda sendiri tempat Anda melakukan semua pemrosesan data yang masuk

2) Dalam skrip Anda, ganti kelas Request dengan milik Anda:

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

3) Gantikan request_class Flask dengan milik Anda:

app.request_class = MyRequest

4) Pergi minum bir :)


0

Saya mencoba melakukan hal yang persis sama, membuka file teks (sebenarnya CSV untuk Pandas). Tidak ingin membuat salinannya, hanya ingin membukanya. Bentuk-WTF memiliki browser file yang bagus, tetapi kemudian membuka file dan membuat file sementara, yang ditampilkan sebagai aliran memori. Dengan sedikit pekerjaan di bawah tenda,

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

Saya membagikan solusi saya (dengan asumsi semuanya sudah dikonfigurasi untuk terhubung ke google bucket in flask)

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())

Posting saya

Langsung ke Google Bucket in flask


-1

Kami hanya melakukan:

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

dalam fungsi

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')

dalam file 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>


-2

Jika kita ingin membuang file memori ke disk. Kode ini dapat digunakan

  if isinstanceof(obj,SpooledTemporaryFile):
    obj.rollover()
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.