我正在尝试使用简单的python程序将一个小文件上传到gcloud
client = storage.Client(project=GCLOUD_PROJECT)
bucket = client.get_bucket(GCLOUD_BUCKET)
blob = bucket.blob(GCLOUD_FILE_ON_CLOUD)
blob.upload_from_filename(GCLOUD_FILE_LOCAL)
它一直工作到最近,有些事情发生了变化。现在,每当我上传大于 5MB 的文件时,我都会收到以下错误。小于或等于5MB的文件通过。大小不够大,无法实现断点续传,是吗?
Traceback (most recent call last):
File "/Users/mmumshad/PycharmProjects/quiz-python-flask-angular/gcloud_upload.py", line 40, in <module>
blob.upload_from_filename(GCLOUD_FILE_LOCAL)
File "/Users/mmumshad/PycharmProjects/quiz-python-flask-angular/venv36/lib/python3.6/site-packages/gcloud/storage/blob.py", line 597, in upload_from_filename
encryption_key=encryption_key, client=client)
File "/Users/mmumshad/PycharmProjects/quiz-python-flask-angular/venv36/lib/python3.6/site-packages/gcloud/storage/blob.py", line 543, in upload_from_file
http_response = upload.stream_file(use_chunks=True)
File "/Users/mmumshad/PycharmProjects/quiz-python-flask-angular/venv36/lib/python3.6/site-packages/gcloud/streaming/transfer.py", line 1086, in stream_file
response = send_func(self.stream.tell())
File "/Users/mmumshad/PycharmProjects/quiz-python-flask-angular/venv36/lib/python3.6/site-packages/gcloud/streaming/transfer.py", line 1215, in _send_chunk
return self._send_media_request(request, end)
File "/Users/mmumshad/PycharmProjects/quiz-python-flask-angular/venv36/lib/python3.6/site-packages/gcloud/streaming/transfer.py", line 1125, in _send_media_request
self.bytes_http, request, retries=self.num_retries)
File "/Users/mmumshad/PycharmProjects/quiz-python-flask-angular/venv36/lib/python3.6/site-packages/gcloud/streaming/http_wrapper.py", line 423, in make_api_request
check_response_func=check_response_func)
File "/Users/mmumshad/PycharmProjects/quiz-python-flask-angular/venv36/lib/python3.6/site-packages/gcloud/streaming/http_wrapper.py", line 371, in _make_api_request_no_retry
redirections=redirections, connection_type=connection_type)
File "/Users/mmumshad/PycharmProjects/quiz-python-flask-angular/venv36/lib/python3.6/site-packages/oauth2client/transport.py", line 175, in new_request
redirections, connection_type)
File "/Users/mmumshad/PycharmProjects/quiz-python-flask-angular/venv36/lib/python3.6/site-packages/oauth2client/transport.py", line 282, in request
connection_type=connection_type)
File "/Users/mmumshad/PycharmProjects/quiz-python-flask-angular/venv36/lib/python3.6/site-packages/httplib2/__init__.py", line 1986, in request
cachekey,
File "/Users/mmumshad/PycharmProjects/quiz-python-flask-angular/venv36/lib/python3.6/site-packages/httplib2/__init__.py", line 1685, in _request
content,
httplib2.RedirectMissingLocation: Redirected but the response is missing a Location: header.
当我调试时,我看到以下内容。
{
'content-type': 'text/plain; charset=utf-8',
'range': 'bytes=0-1048575',
'content-length': '0',
'date': 'Sun, 19 Jan 2020 23:52:13 GMT',
'server': 'UploadServer',
'alt-svc': 'quic=":443"; ma=2592000; v="46,43",h3-Q050=":443"; ma=2592000,h3-Q049=":443"; ma=2592000,h3-Q048=":443"; ma=2592000,h3-Q046=":443"; ma=2592000,h3-Q043=":443"; ma=2592000',
'status': '308'}
我的点数列表供参考。操作系统是MAC OSx。我也在Linux上测试过。同样的问题。
adal 1.2.2
bson 0.5.8
cachetools 3.1.1
certifi 2019.9.11
cffi 1.13.1
chardet 3.0.4
cryptography 2.8
dnspython 1.16.0
gcloud 0.18.3
gitdb2 2.0.6
GitPython 3.0.5
google-auth 1.6.3
googleapis-common-protos 1.51.0
httplib2 0.16.0
idna 2.7
itsdangerous 1.1.0
MarkupSafe 1.1.1
oauth2client 4.1.3
oauthlib 3.1.0
pip 19.0.3
protobuf 3.11.2
pyasn1 0.4.7
pyasn1-modules 0.2.7
pycparser 2.19
PyJWT 1.7.1
python-dateutil 2.8.0
requests 2.19.1
requests-oauthlib 1.2.0
rsa 4.0
setuptools 40.8.0
six 1.12.0
smmap2 2.0.5
urllib3 1.23
websocket-client 0.56.0
Werkzeug 0.16.0
这是上周的工作。最近有什么变化吗?
我用以下方法解决了这个问题:
pip install httplib2==0.15.0
pip install google-api-python-client==1.6
编辑: 加载速度更快的是: pip install httplib2==0.15.0 pip install google-api-python-client==1.7.11
解决方案
gcloud
包已弃用两次,并且与httplib2>=0.16
不兼容。正确的解决方案是使用google-cloud-*
包系列。
google-api-python-client>=1.7.12
正在使用redirect_codes API,请升级,它就可以工作了。
httplib2 v0.17.0 刚刚发布,能够修改被视为重定向的响应代码集。如果可以修改创建对象的代码Http
则这是最佳选择:
http = httplib2.Http()
http.redirect_codes = http.redirect_codes - {308}
如果这是不可能的,请编辑您的要求.txt以确定httplib2<0.16.0
长话短说
谷歌云存储服务器使用HTTP 308进行特殊的可恢复上传功能,这有点类似于"将相同的方法重试到同一位置",但不完全是。
以上是 PyPI 包 google-resumable-media 的基本原理,它被 gcloud 相关包的最新化身使用,并以类似的方式处理 200 和 308,不像通用的 HTTP 客户端应该。
历史背景:
- 2016 软件包 gcloud 被弃用,取而代之的是软件包
google-cloud
- 2017 Google-Cloud-Python 将 HTTP 传输从 httplib2 切换到请求
- 2018 软件包 Google-Cloud 再次被弃用,取而代之的是 Google-Cloud-* 软件包
- 2020 httplib2 v0.16 获得了对每RFC7538 308 次重定向的支持
对不起,坏消息。作为HTTP爱好者,我偏向于308支持。如果您有更好的想法,请与我们联系,以更优雅地处理这种情况。
将httplib2
版本降级为0.15.0
。在python google-cloud-sdk上为我工作。
我在数据流上遇到了这个错误(也伪装成Broken Pipe(。将google-api-python-client
降级到版本>=1.7.8,<1.7.12
修复它,因为 1.7.12 引入了对 httplib2 0.17.0 的依赖,这在某种程度上是不兼容的。
我简直不敢相信。 这个问题在 3 年前就已经列出,现在仍然是一个问题。我一直在以下 python 包之间玩 whack-a-version 来解决这个问题,因为他们在包端还没有弄清楚。
这是我的情况 - 我有一个将某些稍大的文件(从 gmail/chat/等创建的存档文件(上传到 google 云端硬盘位置的过程。
错误(httplib2.重定向缺少位置:已重定向,但响应缺少位置:标头。当我的进程尝试上传更大的文件时,我发生了。
我无法升级以下任何软件包:
google-auth-httplib2
google-api-python-client
httplib2
google-auth
这是我从程序员那里继承下来的过程,他们现在已经转向更绿色的牧场,所以我想我必须重写这个过程来尝试使用所有 google-cloud-* 包(如@temoto建议的那样(。
从现在到上周(当这个过程起作用时(,看起来有一个新版本的 google-auth-httplib2 可用(v. 0.1.1(,我的进程使用了它,并且出现了该错误。我降级了它,现在看起来它正在工作。
目前,这是对我有用的软件包版本:
google-auth-httplib2==0.1.0
google-api-python-client==1.7.8
httplib2==0.15.0
google-auth==1.12.0