通过boto 3上传AWS静态站点文件设置正确的内容类型

时间:2018-04-28 14:08:37

标签: amazon-web-services amazon-s3 boto3 hugo

在AWS 托管的静态网站的不同类型文件的正确内容类型是什么?如何通过boto3以智能方式设置这些文件?

我使用upload_file method

import boto3
s3 = boto3.resource('s3')
bucket = s3.Bucket('allecijfers.nl')
bucket.upload_file('C:/Hugo/Sites/allecijfers/public/test/index.html', 'test/index.html', ExtraArgs={'ACL': 'public-read', 'ContentType': 'text/html'})

这适用于html文件。我最初省略了ExtraArgs导致文件下载(可能是因为内容类型是二进制?)。我发现this page表示了几种内容类型,但我不确定如何应用它。

E.g。可能CSS文件应该使用' ContentType':' text / css'上传。 但是js文件,index.xml等呢?以及如何以聪明的方式做到这一点?仅供参考我这是我目前从Windows上传到AWS的脚本,这需要string.replace(" \"," /")这可能不是最聪明的?

for root, dirs, files in os.walk(local_root + local_dir):
    for filename in files:
        # construct the full local path
        local_path = os.path.join(root, filename).replace("\\","/")
        # construct the full S3 path
        relative_path = os.path.relpath(local_path, local_root)
        s3_path = os.path.join(relative_path).replace("\\","/")
        bucket.upload_file(local_path, s3_path, ExtraArgs={'ACL': 'public-read', 'ContentType': 'text/html'})

我使用AWS CLI将完整的Hugo站点从相同的源上传到相同的S3存储桶,这在没有指定内容类型的情况下工作得很完美,这是否也可以通过boto 3进行?

非常感谢您的帮助!

1 个答案:

答案 0 :(得分:2)

有一个python内置库可以猜测mimetypes。

所以你可以先查找每个文件名。它的工作原理如下:

import mimetypes
print(mimetypes.guess_type('filename.html'))

结果:

('text/html', None)

在你的代码中。我还略微改进了代码相对于Windows路径的可移植性。现在它将做同样的事情,但通过查找将在任何路径中使用的平台特定分隔符(os.path.sep),可以移植到Unix平台。

import boto3
import mimetypes

s3 = boto3.resource('s3')
bucket = s3.Bucket('allecijfers.nl')

for root, dirs, files in os.walk(local_root + local_dir):
    for filename in files:
        # construct the full local path (Not sure why you were converting to a
        # unix path when you'd want this correctly as a windows path
        local_path = os.path.join(root, filename)

        # construct the full S3 path
        relative_path = os.path.relpath(local_path, local_root)
        s3_path = relative_path.replace(os.path.sep,"/")
        # Get content type guess
        content_type = mimetypes.guess_type(filename)[0]
        bucket.upload_file(
            local_path,
            s3_path,
            ExtraArgs={'ACL': 'public-read', 'ContentType': content_type}
        )