Dosya verilerini Flask'a kaydetmeden okuyun


112

İlk şişe başvurumu yazıyorum. Dosya yüklemeleri ile uğraşıyorum ve temel olarak istediğim, yüklenen dosyanın verilerini / içeriğini kaydetmeden okumak ve ardından ortaya çıkan sayfaya yazdırmaktır. Evet, kullanıcının her zaman bir metin dosyası yüklediğini varsayıyorum.

İşte kullandığım basit yükleme işlevi:

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

Şu anda dosyayı kaydediyorum, ancak ihtiyacım olan şey dosyanın içeriğini / verilerini içerecek 'a' değişkeni… herhangi bir fikir?

Yanıtlar:


137

FileStoragestreamalan içerir . Bu nesne, GÇ'yi veya dosya nesnesini genişletmelidir, bu nedenle, readve diğer benzer yöntemleri içermelidir . alan nesnesi niteliklerini FileStoragede genişletir stream, böylece file.read()bunun yerine kullanabilirsiniz file.stream.read(). Ayrıca başka bir GÇ'ye veya dosya nesnesine kopyalamak için as parametresi veya başka bir GÇ veya dosya nesnesi saveile bağımsız değişken kullanabilirsiniz .dstStringIOFileStorage.stream

Belgelere bakın: http://flask.pocoo.org/docs/api/#flask.Request.files ve http://werkzeug.pocoo.org/docs/datastructures/#werkzeug.datastructures.FileStorage .


1
hızlı örnek:file = request.files.get('file') filetype = magic.from_buffer(file.read(1024))
endolith

7
Merhaba @ user2480542. Ben de aynı problemle karşılaşıyorum. İstemci tarafından yüklenen dosyanın içeriğini nasıl okuduğunuzu anlatır mısınız? File.read () 'i çağırıyorum ama hiçbir şey alamıyorum. Teşekkürler!
tmthyjames

1
@tmthyjames f = request.files['file']yüklenen dosyayı (istekte) bir var ("f") öğesine koyar. Daha f.read()sonra yukarıdaki kodu kullanarak çalışır. ne zaman print f.read()terminalde doğru görünümlü hurda alıyorum. Umarım yardımcı olur.
Marc

6
Bir dosya yüklüyorsanız ve ikili bir akışınız varsa, onu TextIOWrapper'a sararak kolayca bir metin akışına dönüştürebilirsiniz: mystring = TextIOWrapper(binary_stream)
Dutch Masters

7
f.read()benim için de hiçbir şey vermedi. Önce aramak f.seek(0)benim için hile yaptı.
w177us

12

Standart Flask malzemelerini kullanmak istiyorsanız - yüklenen dosya boyutu> 500kb ise geçici bir dosyayı kaydetmekten kaçınmanın bir yolu yoktur. 500kb'den küçükse - dosya içeriğini bellekte depolayan "BytesIO" kullanacaktır ve 500kb'den fazlaysa içeriği TemporaryFile () içinde depolar ( werkzeug belgelerinde belirtildiği gibi ). Her iki durumda da komut dosyanız, yüklenen dosyanın tamamı alınana kadar engellenecektir.

Bulduğum bu sorunu çözmenin en kolay yolu şudur:

1) Gelen verilerin tüm işlemlerini yaptığınız kendi dosya benzeri IO sınıfınızı oluşturun

2) Komut dosyanızda, İstek sınıfını kendi sınıfınızla geçersiz kılın:

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

3) Flask'ın request_class'ını kendinizinkiyle değiştirin:

app.request_class = MyRequest

4) Git biraz bira al :)


0

Ben de aynı şeyi yapmaya çalışıyordum, bir metin dosyası açmaya çalışıyordum (aslında Pandalar için bir CSV). Bir kopyasını yapmak istemiyorum, sadece açmak istiyorum. Form-WTF'nin güzel bir dosya tarayıcısı vardır, ancak daha sonra dosyayı açar ve bir bellek akışı olarak sunduğu geçici bir dosya oluşturur. Kaputun altında küçük bir çalışma ile

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

Çözümümü paylaşıyorum (her şeyin flask'ta google kovasına bağlanmak için zaten yapılandırılmış olduğunu varsayarak)

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

Benim yazım

Doğrudan şişede Google Bucket'e


-1

Biz basitçe yaptık:

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

işlevde

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 dosyasında

<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

Bellek içindeki dosyayı diske dökmek istememiz durumunda. Bu kod kullanılabilir

  if isinstanceof(obj,SpooledTemporaryFile):
    obj.rollover()
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.