2017-01-13 10 views
0

Мне нужно ударить конечную точку POST и сохранить ответ, который является двоичными данными в виде zip-файла, и загрузить его в мой локальный каталог. Мне удалось ударить конечную точку POST и получить двоичные данные, но я изо всех сил пытаюсь ее преобразовать или сохранить в виде zip-файла.Как загрузить zip-файл из необработанного двоичного файла, возвращаемого запросами конечной точки POST?

Функция download_contract является POST я использую, чтобы попасть в конечную точку, где контракт является JSON я разборе:

def post(cls, url, access_token, obj=None): 
    return WebResponse.from_requests(requests.post(url, data=None if obj is None else obj.json(), headers=cls.secure_header(access_token) if obj is None else cls.secure_json_header(access_token))) 

def download_contract(self, contract): 
    return SecureWebRequest.post(self.CONTRACT_EXPORT_URL, obj=contract, access_token=self.access_token) 

Следующий код обо мне ударять конечной точки и извлечения его ответ и пытается спасти это как zip-файл.

@then(u'I will download file from S3') 
def step_impl(context): 
    print(context.response) 
    file_name = 'myzip.zip' 
    with context.services.autoimport.download_contract(DownloadContract(context.program_id, complete_filename(context.filename))) as response, open(file_name, 'wb') as out_file: 
     shutil.copyfileobj(response, out_file) 
     with zipfile.ZipFile(file_name) as zf: 
      zf.extractall() 

Что возвращается, когда я печатаю (context.response) выглядит следующим образом:

WebResponse(200,m_-Jinstrument.xmlmPÍ Â0
žď)B_ ÖQ1CđŕYń8ĘI kGßޡ)Ă\ň}|?FłČeqÁťť×=Lť&sRÁĐxÜăcŇĽHżÁ:Źů9 üż7OĚhtÓé`Ä#CŤ3>ÚŇŞV­hŕşwZÂč8yłś 32Wű\ep

WebResponse является (status_code, результат), где status_code соответствует коду HTTP Status 200 и результатом является исходные данные, возвращаемые конечной точкой.

class WebResponse(): 
    STATUS_OK = 200 
    STATUS_CREATED = 201 
    STATUS_ACCEPTED = 202 
    STATUS_NOCONTENT = 204 
    STATUS_BADREQUEST = 400 
    STATUS_UNAUTHORIZED = 401 
    STATUS_FORBIDDEN = 403 
    STATUS_NOTFOUND = 404 
    STATUS_CONFLICT = 409 
    STATUS_INVALID = 422 
    STATUS_INTERNALSERVER_ERROR = 500 

    def __init__(self, r, result=None): 
     self.status_code = r.status_code 
     self.text = r.text 
     self.headers = r.headers 
     self.result = r.text if result is None else result 

    def __repr__(self): 
     return 'WebResponse(%s, %s)' % (self.status_code, self.result) 

Ошибка Thrownback:

Traceback (most recent call last): File "/Users/ss/anaconda/envs/autoimport-server/lib/python3.4/site-packages/behave/model.py", line 1456, in run match.run(runner.context) File "/Users/ss/anaconda/envs/autoimport-server/lib/python3.4/site-packages/behave/model.py", line 1903, in run self.func(context, *args, **kwargs) File "features/steps/miu_connector_steps.py", line 255, in step_impl with context.services.autoimport.download_contract(DownloadContract(context.program_id, complete_filename(context.filename))) as response, open(file_name, 'wb') as out_file: AttributeError: exit

+0

http://stackoverflow.com/a/9419208/6626530 - может быть, вы должны попробовать urllib2.urlopen – Shijo

+0

@Shijo Для этого требуется ссылка с zip-файлом, хотя у меня есть только конечная точка POST, на которую я могу попасть. т.е. «http://accautoimport.miuinsights.com/v1/contractsExport» – user4659009

+0

как насчет http://stackoverflow.com/questions/13137817/how-to-download-image-using-requests – Shijo

ответ

0

Ваш ответ выглядит как 'WebResponse(200,m_-Jins ...' и это то, что вы пишете в файл shutil.copyfileobj(response, out_file).

Предположим, вы хотите написать response.result в файл. КПП. Что такое контент в out_file?

+0

Да, я хочу написать ' response.result' в файл. Ничего, не удается, пока не дойдет до этой строки – user4659009

+0

Какая ошибка (отредактируйте свой пост с полной трассировкой)? –

+0

Я получаю следующий ответ, когда я попробую ваше предлагаемое решение. 'shutil.copyfileobj (context.response.result, f) Файл« /Users/ss/anaconda/envs/autoimport-server/lib/python3.4/shutil.py », строка 67, в copyfileobj buf = fsrc .read (length) AttributeError: объект 'str' не имеет атрибута 'read'' – user4659009

0

INIT ниже пропускал r.raw, где r относится к requests.

class WebResponse(): 
    STATUS_OK = 200 
    STATUS_CREATED = 201 
    STATUS_ACCEPTED = 202 
    STATUS_NOCONTENT = 204 
    STATUS_BADREQUEST = 400 
    STATUS_UNAUTHORIZED = 401 
    STATUS_FORBIDDEN = 403 
    STATUS_NOTFOUND = 404 
    STATUS_CONFLICT = 409 
    STATUS_INVALID = 422 
    STATUS_INTERNALSERVER_ERROR = 500 

    def __init__(self, r, result=None): 
     self.status_code = r.status_code 
     self.text = r.text 
     self.headers = r.headers 
     self.raw = r.raw 
     self.result = r.text if result is None else result 

Затем я изменил код на следующее, чтобы это заработало:

@then(u'I will download the zip file from the service') 
def step_impl(context): 
    with open(context.filename, 'wb') as fd: 
     for chunk in context.response.iter_content(chunk_size=128): 
      fd.write(chunk)