我正在使用Python库boto
连接到Amazon S3并为静态网站创建存储桶和密钥。我的键和值是动态生成的,因此我以编程方式而不是通过Web界面(它使用Web界面工作)进行此操作。我的代码目前看起来像这样:
import boto
from boto.s3.connection import S3Connection
from boto.s3.key import Key
conn = S3Connection(AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY)
bucket = conn.create_bucket(BUCKET_NAME)
bucket.configure_website('index.html', 'error.html')
bucket.set_acl('public-read')
for template in ['index.html', 'contact-us.html', 'cart.html', 'checkout.html']:
k = Key(bucket)
k.key = key
k.set_acl('public-read')
k.set_metadata('Content-Type', 'text/html')
k.set_contents_from_string(get_page_contents(template))
我遇到了这段代码的各种错误和问题。当密钥已经存在并且我使用此代码更新它们时,我会将每个密钥的ACL设置为public-read
,但在浏览器中查看文件时,我仍然会收到403个禁止错误。
我尝试删除所有密钥以从头开始重新创建它们,现在我得到NoSuchKey
异常。显然关键不在那里,因为我正在努力创造它。
我是以错误的方式来做这件事的吗?有没有不同的方法来创建密钥而不是更新密钥?当权限不坚持时,我是否遇到某种竞争条件?
答案 0 :(得分:11)
我仍然不完全确定为什么上面的代码不起作用,但我发现了一种不同的(或更新的?)语法来创建密钥。操作顺序似乎也有一些影响。这就是我提出的有效方法:
conn = S3Connection(AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY)
bucket = conn.create_bucket(store.domain_name)
bucket.set_acl('public-read')
bucket.configure_website('index.html', 'error.html')
for template in ['index.html', 'contact-us.html', 'cart.html', 'checkout.html']:
k = bucket.new_key(template)
k.set_metadata('Content-Type', 'text/html')
k.set_contents_from_string(get_page_contents(template))
k.set_acl('public-read') #doing this last seems to be important for some reason
答案 1 :(得分:4)
这也困扰了我。 boto的set_contents_from_string()
方法显然将密钥的ACL设置为private,覆盖任何现有的ACL。
因此,如果您执行set_acl('public-read')
,后跟set_contents_from_string()
,则会覆盖'public-read'
。
答案 2 :(得分:2)
我可以通过策略关键字arg:
一次性设置ACLk.set_contents_from_stream(buff, policy='public-read')