【问题标题】:AWS static site file upload via boto 3 set the right content-types通过 boto 3 上传 AWS 静态站点文件设置正确的内容类型
【发布时间】:2018-10-09 04:26:39
【问题描述】:

对于托管在 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 声明了几种内容类型,但我不确定如何应用它。

例如可能 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 实现?

非常感谢您的帮助!

【问题讨论】:

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


    【解决方案1】:

    有一个 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}
            )
    

    【讨论】:

    • 谢谢,这对我很有效!现在我可以通过 Python 脚本部署我的静态站点了! “猜测”的 mime 类型等于 AWS CLI 上传和/或手动 AWS 控制台上传自动设置的内容类型。我通过查看 AWS 管理控制台中元数据下显示的文件属性进行了检查。例如。 index.html = text/html, index.xml = text/xml, favicon.ico = image/x-icon,... 不过,令我惊讶的是,我必须在通过 boto 3 上传时将其指定为参数,而这在通过 AWS CLI 或控制台上传时不需要。
    • 我猜他们愿意在控制台上传上做额外的处理(只是猜测 mime 类型,但它仍然有效),因为这没有大规模使用。通过 API 对所有 S3 上传的对象执行此操作会很浪费,因为通常不需要这样做。但这只是猜测。
    • 我收到一个错误:upload_file() missing 1 required positional argument: 'Key'
    猜你喜欢
    • 2018-10-07
    • 2019-11-07
    • 2013-04-22
    • 1970-01-01
    • 2015-01-24
    • 1970-01-01
    • 2014-04-16
    • 1970-01-01
    • 2015-05-22
    相关资源
    最近更新 更多