📌

[小ネタ]S3にhtmlファイルをboto3でアップロードして失敗していた話

2023/03/20に公開

さきにまとめ

sdkでhtmlファイルをS3バケットにアップロードするときは、ContentType='text/html'を指定しましょう。

やりたかったこと

  • S3で静的ファイルをホストしたい
  • boto3でhtmlファイルをアップロードしたい

失敗の状態

  • ファイルのURLにアクセスして表示しようとすると、htmlファイルをダウンロードしてしまう
    • ダウンロードしたファイルはローカルからは正常に開ける

原因

無指定で、Content-Typebinary/octet-streamになっていた。

text/htmlが正しい。

コード

パターン別に書いています。

前提

  • bucketがある
  • htmlファイルをアップロードしたい
    • コード内でhtmlを作る場合
    • htmlファイルがすでにある場合
import boto3

html_content = """<!DOCTYPE html>
<html>
  <head>
    <title>Hello world!</title>
  </head>
  <body>
    <h1>Hello world!</h1>
  </body>
</html>
"""

bucket = "my−static-bucket"
html = "test-my-file.html"

# html_contentを使うとき その1
client = boto3.client("s3")
client.put_object(Body=html_content, Bucket=bucket, Key=html, ContentType="text/html")

# html_contentを使うとき その2
s3 = boto3.resource("s3")
s3.Object(bucket, html).put(Body=html_content, ContentType="text/html")

# ファイルがすでにあるとき その1
client = boto3.client("s3")
client.upload_file("upload.html", bucket, html, ExtraArgs={"ContentType": "text/html"})

# ファイルがすでにあるとき その2
s3 = boto3.resource("s3")
s3.meta.client.upload_file(
    "upload.html", bucket, html, ExtraArgs={"ContentType": "text/html"}
)

まとめ

  • 何も指定せずにhtmlファイルをboto3でアップロードするとbinary/octet-streamになってしまうので、明示的にContentType="text/html"を指定します
  • 書き方がいろいろあるのは迷いますね

参考にしたもの

https://qiita.com/nittyan/items/bf8498e314d3ae807766

--

ChatGTP(3)に聞いても正しく答えてくれました。

コードはこちら。

import boto3

s3_client = boto3.client('s3')
s3_client.upload_file('path/to/local/file.html', 'my-bucket', 'test.html', ExtraArgs={'ContentType': 'text/html'})

Discussion