Dan*_*ski 7 python gzip http python-requests
(这个问题不是关于来自Web服务器的gzip
-encoded 响应的透明解压缩;我知道这requests
会自动处理.)
我正在尝试将文件POST到RESTful Web服务.显然,requests
这很容易做到:
files = dict(data=(fn, file))
response = session.post(endpoint_url, files=files)
Run Code Online (Sandbox Code Playgroud)
在这种情况下,我的文件是一个非常高度可压缩的格式(是的,XML),所以我想确保请求体是压缩的.
服务器声称接受gzip编码(Accept-Encoding: gzip
在响应头中),所以我应该能够gzip整个身体请求体,对吧?
这是我尝试完成这项工作:我首先构建请求并准备它,然后我进入PreparedRequest
对象,猛拉出来body
,运行它gzip
,并把它放回去.(哦,不要忘记更新Content-Length
和Content-Encoding
标题.)
files = dict(data=(fn, file))
request = request.Request('POST',endpoint_url, files=files)
prepped = session.prepare_request(request)
with NamedTemporaryFile(delete=True) as gzfile:
gzip.GzipFile(fileobj=gzfile, mode="wb").write(prepped.body)
prepped.headers['Content-Length'] = gzfile.tell()
prepped.headers['Content-Encoding'] = 'gzip'
gzfile.seek(0,0)
prepped.body = gzfile.read()
response = session.send(prepped)
Run Code Online (Sandbox Code Playgroud)
不幸的是,服务器没有合作并返回500 Internal Server Error
.也许它并没有真正接受gzip
-encoded请求?
或者我的方法可能有错误?这似乎相当复杂.是否有更简单的方法来执行请求身体压缩python-requests
?
编辑:固定(3)和(5)来自@ sigmavirus24的答案(这些基本上只是我在简化代码时忽略的工件,在此处发布).
或者我的方法可能有错误?
坦白说,我不确定你是如何达到你的方法的,但肯定有一种更简单的方法.
首先,一些事情:
files
参数构造一个multipart/form-data
主体.所以你正在压缩服务器可能没有任何线索的东西.Content-Encoding
并且Transfer-Encoding
是两个非常不同的东西.你想要的Transfer-Encoding
.NamedTemporaryFile
.multipart/form-data
请求,我将假设您实际上并不想这样做.session.Request
(我认为应该是requests.Request
)的调用缺少一个方法,即它应该是:requests.Request('POST', endpoint_url, ...)
有了这些,这就是我将如何做到这一点:
# Assuming `file` is a file-like obj
with NamedTemporaryFile(delete=True) as gzfile:
gzip.GzipFile(fileobj=gzfile, mode="wb").write(file.read())
headers = {'Content-Length': gzfile.tell(),
'Transfer-Encoding': 'gzip'}
gzfile.seek(0, 0)
response = session.post(endpoint_url, data=gzfile,
headers=headers)
Run Code Online (Sandbox Code Playgroud)
假设其中file
包含xml
内容并且您的意思是压缩它,这应该适合您.你可能想设置一个Content-Type
标题,例如,你就是这样做的
headers = {'Content-Length': gzfile.tell(),
'Content-Type': 'application/xml', # or 'text/xml'
'Transfer-Encoding': 'gzip'}
Run Code Online (Sandbox Code Playgroud)
该Transfer-Encoding
通知的请求仅在运输过程中被压缩的服务器,它应该解压.该Content-Type
告诉服务器如何,一旦处理内容Transfer-Encoding
已经被处理.