2012-09-24 106 views
19

是否有任何可行的方式將上傳動態生成的文件直接上傳到amazon s3而無需先創建本地文件然後上傳到s3服務器?我使用python。謝謝如何將文件上傳到S3而不創建臨時本地文件

+0

的答案解釋兩種方法可以做到這一點。但是如果你遇到一個只能獲取文件的API,你可能想看看'tempfile.TemporaryFile';使用正確的參數,您將獲得類似文件的對象,儘可能接近不成爲真實文件。 (在POSIX上,這意味着它沒有目錄項,並且除非必要,它不會被備份到磁盤;在Windows上,它實際上是一個臨時目錄周圍存在的文件對象的包裝對象,直到您關閉它爲止,這並不總是好的足夠了,所以你可能需要PyWin32'CreateFile'並且做一些更復雜的代碼來獲得你想要的)。 – abarnert

+0

目前boto沒有這方面的功能。 'Key.open_write()'方法尚未實現。一旦它是你將有答案。 ''set_contents_from_stream()'據稱可以從流對象讀取,但它實際上期望一個文件...我不知道它是否可以以某種方式使用... – DejanLekic

回答

2

我假設你使用的是botobotoBucket.set_contents_from_file()將接受一個StringIO對象,並且您寫入的用於將數據寫入文件的任何代碼都應該可以很容易地適用於寫入StringIO對象。或者如果你生成一個字符串,你可以使用set_contents_from_string()

+0

我試過在python file = request.file ['name'] set_contents_from_file (file.readlines()),但它需要一個字符串,所以我迭代並獲得字符串,但它給了我** AttributeError:'str'對象沒有屬性'tell'** – Shashank

+1

這是因爲你傳遞一個字符串,而不是一個'StringIO'對象,因爲我建議... – kindall

+0

哦,是的,你是正確的,但在兩種方式StringIO(文件)或StringIO(file.readlines()),文件上傳到S3,但無法打開只顯示空白符號瀏覽器.... – Shashank

9

boto庫的Key對象有幾個方法,你可能感興趣的:

對於使用的例子set_contents_from_string,看到博託文檔Storing Data部分,粘貼在這裏的完整性:

>>> from boto.s3.key import Key 
>>> k = Key(bucket) 
>>> k.key = 'foobar' 
>>> k.set_contents_from_string('This is a test of S3') 
+0

但是如何在** set_contents_from_file **中可能,並且它接受文件本地存儲在磁盤上 – Shashank

+0

@shihon我不明白你的意思題。 – jterrace

+1

看到我用** file = request.file ['name'] **得到了一個文件,然後我將它保存在本地** os.save(os.path.join(path,file))**,from那裏我設置S3鍵和** set_contents_from_filename(os.path.join(路徑,文件))**,那麼我需要直接在S3上保存文件,而不是先保存在本地,然後在S3上... – Shashank

6

你可以使用BytesIO從Python標準庫。

from io import BytesIO 
bytesIO = BytesIO() 
bytesIO.write('whee') 
bytesIO.seek(0) 
s3_file.set_contents_from_file(bytesIO) 
13

下面是一個例子下載的圖像(使用請求庫),並上傳到S3,而無需編寫本地文件:下面

import boto 
from boto.s3.key import Key 
import requests 

#setup the bucket 
c = boto.connect_s3(your_s3_key, your_s3_key_secret) 
b = c.get_bucket(bucket, validate=False) 

#download the file 
url = "http://en.wikipedia.org/static/images/project-logos/enwiki.png" 
r = requests.get(url) 
if r.status_code == 200: 
    #upload the file 
    k = Key(b) 
    k.key = "image1.png" 
    k.content_type = r.headers['content-type'] 
    k.set_contents_from_string(r.content) 
+0

這就是我一直在尋找的,謝謝 – noahandthewhale

0
def upload_to_s3(url, **kwargs): 
    ''' 
    :param url: url of image which have to upload or resize to upload 
    :return: url of image stored on aws s3 bucket 
    ''' 

    r = requests.get(url) 
    if r.status_code == 200: 
     # credentials stored in settings AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY 
     conn = boto.connect_s3(AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, host=AWS_HOST) 

     # Connect to bucket and create key 
     b = conn.get_bucket(AWS_Bucket_Name) 
     k = b.new_key("{folder_name}/{filename}".format(**kwargs)) 

     k.set_contents_from_string(r.content, replace=True, 
            headers={'Content-Type': 'application/%s' % (FILE_FORMAT)}, 
            policy='authenticated-read', 
            reduced_redundancy=True) 

     # TODO Change AWS_EXPIRY 
     return k.generate_url(expires_in=AWS_EXPIRY, force_http=True) 
相關問題