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(). 또한 매개 변수 save와 함께 인수를 사용 하거나 다른 IO 또는 파일 개체를 사용하여 다른 IO 또는 파일 개체로 복사 할 수 있습니다.dstStringIOFileStorage.stream

문서 참조 : http://flask.pocoo.org/docs/api/#flask.Request.fileshttp://werkzeug.pocoo.org/docs/datastructures/#werkzeug.datastructures.FileStorage .


1
빠른 예 :file = request.files.get('file') filetype = magic.from_buffer(file.read(1024))
endolith

7
안녕하세요 @ user2480542. 나는 같은 문제에 직면하고 있습니다. 클라이언트가 업로드 한 파일의 내용을 어떻게 읽었는지 설명해 주시겠습니까? file.read ()를 호출하고 있지만 아무것도 얻지 못합니다. 감사!
tmthyjames

1
@tmthyjames f = request.files['file']는 업로드 된 파일 (요청에서)을 var ( "f")에 넣습니다. 그런 f.read()다음 위의 코드를 사용하여 작동합니다. print f.read()터미널에서 올바르게 보이는 쓰레기 가 언제 나오나요? 도움이 되었기를 바랍니다.
Marc

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.