【问题标题】:How to download a zip file from the raw binary returned by a requests POST endpoint?如何从请求 POST 端点返回的原始二进制文件中下载 zip 文件?
【发布时间】:2017-01-13 14:27:31
【问题描述】:

我需要点击一个 POST 端点并将作为二进制数据的响应保存为 zip 文件并将其下载到我的本地目录。我已成功访问 POST 端点并检索二进制数据,但我正在努力转换或将其保存为 zip 文件。

函数 download_contract 是我用来命中端点的 POST,其中 contract 是我正在解析的 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()

print(context.response) 时返回的内容如下:

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

WebResponse 为 (status_code, result),其中 status_code 对应 HTTP 状态码 200,result 为端点返回的原始数据。

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)

错误回退:

Traceback(最近一次调用最后一次):文件 "/Users/ss/anaconda/envs/autoimport-server/lib/python3.4/site-packages/behave/model.py", 第 1456 行,运行中 match.run(runner.context)文件“/Users/ss/anaconda/envs/autoimport-server/lib/python3.4/site-packages/behave/model.py”, 第 1903 行,运行中 self.func(context, *args, **kwargs) 文件“features/steps/miu_connector_steps.py”,第 255 行,在 step_impl 与 context.services.autoimport.download_contract(DownloadContract(context.program_id, complete_filename(context.filename))) 作为响应,open(file_name, 'wb') as out_file: AttributeError: exit

【问题讨论】:

标签: python python-3.x post zip python-requests


【解决方案1】:

您的回复看起来像 'WebResponse(200,m_-Jins ...',这就是您正在写入文件 shutil.copyfileobj(response, out_file) 的内容。

我假设您想将response.result 写入文件。 顺便提一句。 out_file 的内容是什么?

【讨论】:

  • 是的,我想将response.result 写入文件中。没什么,它在到达那条线之前就失败了
  • 错误是什么(编辑您的帖子并使用完整的回溯)?
  • 当我尝试您建议的解决方案时,我得到了以下信息。 shutil.copyfileobj(context.response.result, f) File "/Users/ss/anaconda/envs/autoimport-server/lib/python3.4/shutil.py", line 67, in copyfileobj buf = fsrc.read(length) AttributeError: 'str' object has no attribute 'read'
  • 我已将完整的回溯添加到上面的帖子中。
【解决方案2】:

下面的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)

【讨论】:

    猜你喜欢
    • 2019-04-07
    • 1970-01-01
    • 1970-01-01
    • 2012-03-14
    • 2022-01-16
    • 2019-04-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多