使用Boto3在S3中设置AWS内容类型

55

我正尝试使用亚马逊的Boto3 SDK上传网页至S3桶。

我无法设置Content-Type。AWS一直在创建一个新的元数据键用于Content-Type,除了我使用以下代码指定的那个键之外。

# Upload a new file
data = open('index.html', 'rb')
x = s3.Bucket('website.com').put_object(Key='index.html', Body=data)
x.put(Metadata={'Content-Type': 'text/html'})

非常感谢任何关于如何设置Content-Typetext/html的指导。

5个回答

85

Content-Type不是自定义元数据,这就是Metadata所用的。它有自己的属性,可以像这样设置:

bucket.put_object(Key='index.html', Body=data, ContentType='text/html')

注意: .put_object()不仅可以设置Content-Type,还可以设置更多。请参阅Boto3文档了解详情。


74

您还可以使用upload_file()方法和ExtraArgs关键字进行操作(同时将权限设置为全局可读):

import boto3
s3 = boto3.resource('s3')
s3.meta.client.upload_file('source_file_name.html', 'my.bucket.com', 'aws_file_name.html', ExtraArgs={'ContentType': "application/json", 'ACL': "public-read"} )

5
答案错误,它将设置'x-amz-meta-contenttype'为'application/json',而不是'Content-Type'。 - doanduyhai
8
这是正确的做法。看起来你正将密钥设置在“ExtraArgs”字典中的“Metadata”键内。 - sisanared
ValueError: Invalid extra_args key 'x-amz-meta-contenttype', must be one of: ACL, CacheControl, ContentDisposition, ContentEncoding, ContentLanguage, ContentType, ExpectedBucketOwner, Expires, GrantFullControl, GrantRead, GrantReadACP, GrantWriteACP, Metadata, RequestPayer, ServerSideEncryption, StorageClass, SSECustomerAlgorithm, SSECustomerKey, SSECustomerKeyMD5, SSEKMSKeyId, SSEKMSEncryptionContext, Tagging, WebsiteRedirectLocation - Scott
如果我不想将它设置为“public-read”呢? - Yuvraj Singh
1
@YuvrajSingh 请查看文档中的请求语法示例。看起来选项有'private'|'public-read'|'public-read-write'|'authenticated-read'|'aws-exec-read'|'bucket-owner-read'|'bucket-owner-full-control',但效果可能因情况而异。 - Jheasly

6
使用Boto3示例(2022年)- 使用"ExtraArgs"参数
s3 = boto3.client('s3', aws_access_key_id = AWS_ACCESS_KEY_ID, aws_secret_access_key = AWS_SECRET_ACCESS_KEY, region_name = "us-east-1")
    
s3.upload_file(file_path, s3_bucket, file_name, ExtraArgs={'ContentType': "application/json"})

0
# bucket: s3 bucket name
# key: s3 file path (eg: test/123/a.jpg)
# file_path: local file path
def upload_img(bucket: str, key: str, file_path: str):
    s3_client.upload_file(Bucket=bucket, Key=key, Filename=file_path, ExtraArgs={'ContentType': "image/jpeg"})
    os.remove(file_path)
    print("upload image {} success".format(file_path))

-6

这里的data是一个已打开的文件,而不是它的内容:

# Upload a new file
data = open('index.html', 'rb')

读取(二进制)文件的方法:

import io

with io.open("index.html", mode="rb") as fd:
    data = fd.read()

那样会更好。


1
感谢您的留言。但是它仍然以“二进制/八位流”的形式上传。 - Rupert

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接