2013-10-24 43 views
2

SpiderOak我一直在用這個Zipstream模塊瞎掰,它基本上允許你在不寫任何內容的情況下對文件或文件夾進行流和壓縮。它產生大小不規則的數據。用於python請求的多部分表單數據生成器

現在,我試圖上傳一個目錄到一個文件託管網站,要求我發送fileapikey字段內的發佈請求。隨着要求我必須建立一個字典的apikey像這樣:

,並讀取整個zipstream成字符串,並將其傳遞到文件編碼字典:

files = {'file': ('mydir.zip', the_string_that_is_a_zipped_dir)} 

然後發出要求

r = requests.post(url, data=data, files=files). 

這工作正常。不過,我希望將來能夠傳輸更大的內容,並且從內存中讀取整個文件是一個糟糕的主意。 我看到請求的高級部分,你可以發送一個生成器作爲數據字段,但然後我不能發送api鍵,並且必須手動修改標題以設置內容類型和所有這些東西,所以它不起作用。還試圖以形成一個字典出API密鑰和zip文件發生器的像這樣 數據= { '文件':( 'mydir.zip',發電機()), 'apikey': 'myapikey' }

但這失敗(如預期)。

有沒有一種方法可以將請求轉化爲使用一個爲多部分表單數據中的文件生成字符串的生成器?

回答

0

好的,經過一番鬥爭,我設法使這個工作沒有請求,而是使用模塊poster

首先我創建一個FileObject包裝圍繞zipstream像這樣:

from zipstream import ZipStream 

class Zipit: 
    def __init__(self, path): 
    self.it = iter(ZipStream(path,compression=0)) 
    self.next_chunk = "" 
    self.length = -1 
    self.path = path 
    self.__is_zipit__=''  
    @property 
    def size(self): 
    if self.length < 0: 
     self.length = 0 
     zip_object = ZipStream(self.path,compression=0) 
     for data in zip_object: 
     self.length += len(data) 
    return self.length 

    def growChunk(self): 
    self.next_chunk = self.next_chunk + self.it.next() 
    def read(self, n): 
    if self.next_chunk == None: 
     return None 
    try: 
     while len(self.next_chunk)<n: 
     self.growChunk() 
     rv = self.next_chunk[:n] 
     self.next_chunk = self.next_chunk[n:] 
     return rv 
    except StopIteration: 
     rv = self.next_chunk 
     self.next_chunk = None 
     return rv 

爲了有一個簡單的API(代碼從另一示例無恥適於在SO)。

然後按照海報的文檔創建必要的多對象:

z = Zipit('/my/path/to/zip') 

f = MultipartParam('file', fileobj=z, filesize=z.size, filename='test.zip',filetype='application/zip') 
datagen, headers = multipart_encode([ f, ('akey', 'mykey')]) 

最後一個黑客被跳過的情況下,復位的文件對象字段是從ZipIt實例:

def reset(self): 
     if hasattr(self.fileobj, '__is_zipit__'): return 
     if self.fileobj is not None: 
      self.fileobj.seek(0) 
     elif self.value is None: 
      raise ValueError("Don't know how to reset this parameter") 

這爲我工作。希望它能幫助你們五個人中的任何一個讀到這個。

相關問題