2016-02-29 48 views
1

我正在使用Flask應用程序接收帶有上傳文件(在此示例中爲視頻)的多部分/表單數據請求。燒瓶 - 處理表單文件並上傳到AWS S3而不保存到文件

我不想將文件保存在本地目錄中,因爲此應用程序將在服務器上運行,並且保存它會減慢速度。

我想使用由Flask request.files ['']方法創建的文件對象,但它似乎並沒有工作。

下面是它的一部分代碼:上線

TypeError: must be encoded string without NULL bytes, not str 

@bp.route('/video_upload', methods=['POST']) 
def VideoUploadHandler(): 
    form = request.form 
    video_file = request.files['video_data'] 
    if video_file: 
     s3 = boto3.client('s3') 
     s3.upload_file(video_file.read(), S3_BUCKET, 'video.mp4') 
     return json.dumps('DynamoDB failure') 

這將返回一個錯誤

s3.upload_file(video_file.read(), S3_BUCKET, 'video.mp4') 

我沒有得到這個由第一工作保存文件然後訪問保存的文件,因此捕獲請求文件不是問題。這工作:

video_file.save(form['video_id']+".mp4") 
s3.upload_file(form['video_id']+".mp4", S3_BUCKET, form['video_id']+".mp4") 

什麼是在內存中處理文件數據,並將其傳遞給s3.upload_file()方法的最佳方法是什麼?我正在使用boto3方法here,我只找到第一個參數中使用的文件名的例子,所以我不知道如何使用內存中的文件正確處理這個。謝謝!

+0

你管理這個問題? – cuongnv23

回答

1

首先您需要能夠訪問發送給Flask的原始數據。這並不像看起來那麼容易,因爲你正在閱讀一份表格。爲了能夠讀取原始數據流,您可以使用flask.request.stream,其行爲與StringIO類似。這裏的技巧是,你的不能調用request.formrequest.file,因爲訪問這些屬性會將整個流加載到內存或文件中。

你需要一些額外的工作來提取流的正確部分(不幸的是我不能幫你,因爲它取決於你的表單是如何製作的,但我會讓你試驗這個)。

最後,您可以使用boto的set_contents_from_file函數,因爲upload_file似乎沒有處理文件類對象(StringIO等)。

示例代碼:

from boto.s3.key import Key 

@bp.route('/video_upload', methods=['POST']) 
def VideoUploadHandler(): 
    # form = request.form <- Don't do that 
    # video_file = request.files['video_data'] <- Don't do that either 
    video_file_and_metadata = request.stream # This is a file-like object which does not only contain your video file 
    # This is what you need to implement 
    video_title, video_stream = extract_title_stream(video_file_and_metadata) 
    # Then, upload to the bucket 
    s3 = boto3.client('s3') 
    bucket = s3.create_bucket(bucket_name, location=boto.s3.connection.Location.DEFAULT) 
    k = Key(bucket) 
    k.key = video_title 
    k.set_contents_from_filename(video_stream) 
+0

感謝您的幫助!你能否詳細說明'extract_title_stream(video_file_and_metadata)'?我對此很陌生,所以我不知道從哪裏開始提取與我已經做的不同的流。 – Feedslant

+0

就像我說的那樣,這是針對你的表單的,所以你應該親自看看它......看看https://docs.python.org/2/library/stringio.html。 'request.stream'可能有'get_value'方法,但我不確定。國際海事組織最好的辦法就是用你用來處理你的文件的方式處理你的文件:它更安全,我不確定你需要額外的性能。 –

+0

這可能是因爲我是stringIO庫和流媒體的新手,但我不知道如何將一個LimitedStream('request.stream')轉換爲stringIO。我在網上也找不到很多信息。 – Feedslant