get_bucket() 为我未通过 Boto 创建的 S3 存储桶提供 'Bad Request'

get_bucket() gives 'Bad Request' for S3 buckets I didn't create via Boto

我正在使用 Boto 尝试在 Amazon S3 中获取一个存储桶,但是当我对某些存储桶使用 get_bucket() 时,它 returns 错误请求。我开始怀疑这是否是 Boto 的错误,因为我可以使用 get_all_buckets().

获取存储桶
>>> from boto.s3.connection import S3Connection
>>> conn = S3Connection(S3_ACCESS_KEY, S3_SECRET_KEY)
>>> buckets = conn.get_all_buckets()
>>> buckets
[<Bucket: mysite-backups>]
>>> buckets[0]
<Bucket: mysite-backups>
>>> conn.get_bucket('mysite-backups')
Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "/path/to/virtualenv/lib/python2.7/site-packages/boto/s3/connection.py", line 502, in get_bucket
    return self.head_bucket(bucket_name, headers=headers)
  File "/path/to/virtualenv/lib/python2.7/site-packages/boto/s3/connection.py", line 549, in head_bucket
    response.status, response.reason, body)
S3ResponseError: S3ResponseError: 400 Bad Request

>>> conn.create_bucket('mysite_mybucket')
<Bucket: mysite_mybucket>
>>> conn.get_bucket('mysite_mybucket')
<Bucket: mysite_mybucket>

这似乎是一个问题,即使我使用与使用访问凭证相同的用户帐户登录并从 AWS 控制台中创建它也是如此。

知道为什么会这样吗?

原来是地区问题(我用的是法兰克福)。两种处理方式:

  1. 放弃法兰克福(@andpei 指出那里有 issues currently reported with it)并在不同的区域重新创建存储桶。

  2. 连接时使用'host'参数指定区域(感谢@Siddarth):

    >>> REGION_HOST = 's3.eu-central-1.amazonaws.com'
    >>> conn = S3Connection(S3_ACCESS_KEY, S3_SECRET_KEY, host=REGION_HOST)
    >>> conn.get_bucket('mysite-backups')
    <Bucket: mysite-backups>
    

    您可以找到相关区域主机here

在处理不同区域的桶时使用连接到区域。

可以在 https://github.com/boto/boto/issues/2916 找到一个通用且简单的解决方案,不涉及更改区域或设置特定主机。经过一些编辑:

The Frankfurt AWS region (Ireland and CN too, apparently) only support the V4 signature algorithm. (…)

Per the boto documentation, you can either add [s3] use-sigv4 = True to your ~/.boto file or set the os.environ list to include S3_USE_SIG_V4: os.environ['S3_USE_SIGV4'] = 'True'.

我不得不结合使用 EOL 和 seddonym 的答案 - 首先我指定我想将 Sigv4 与以下内容一起使用:

os.environ['S3_USE_SIGV4'] = 'True'

然后,在连接到存储桶时,我必须指定主机,这看起来有点傻,但这里是:

s3 = S3Connection('key id', 'access key', host='s3.eu-central-1.amazonaws.com')

请注意,这仅适用于 法兰克​​福

将 s3 存储桶主机添加到 boto 连接

conn = boto.connect_s3(AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, host=AWS_HOST)