boto2とboto3でバケット名に「.」(ピリオド)が含まれる場合の挙動が違ったので記録しておきます。
- 確認環境
- やりたかったこと
- boto2,boto3と、バケット名に"."(ピリオド)がある、なしでの成否
- boto2のソースとエラーメッセージ
- (ちなみに)boto3のソース
- この結果になった際に考えたこと
- 参考にしました
確認環境
Python 3.8.5 boto==2.49.0 boto3==1.16.52
やりたかったこと
boto2,boto3経由でS3にあるファイルの中身を表示する
boto2,boto3と、バケット名に"."(ピリオド)がある、なしでの成否
boto2 | boto3 | |
バケット名に"."なし | 〇 | 〇 |
バケット名に"."あり | × | 〇 |
boto2では、バケット名に"."がある場合にエラーが発生しました。
一方で、boto3ではバケット名に"."がある、なしにかかわらず結果が得られました
boto2のソースとエラーメッセージ
import boto from boto.s3.key import Key def main(): conn = boto.connect_s3('****','****') bucket = conn.get_bucket('<バケット名>') k = Key(bucket) k.key = '<バケット名を除くフルパス(頭に'/'を入れない)>' print(k.get_contents_as_string(encoding='utf-8')) if __name__ == '__main__': main()
エラーメッセージ
Traceback (most recent call last): File "boto2_s3.py", line 14, in <module> main() File "boto2_s3.py", line 7, in main bucket = conn.get_bucket('<バケット名>') File "/usr/lib/python3.8/site-packages/boto/s3/connection.py", line 509, in get_bucket return self.head_bucket(bucket_name, headers=headers) ...(中略) return self.sslsocket_class._create( File "/usr/lib/python3.8/ssl.py", line 1040, in _create self.do_handshake() File "/usr/lib/python3.8/ssl.py", line 1309, in do_handshake self._sslobj.do_handshake() ssl.SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: Hostname mismatch, certificate is not valid for '<バケット名>.s3.amazonaws.com'. (_ssl.c:1123)
(ちなみに)boto3のソース
import boto3 def main(): s3 = boto3.client('s3', aws_access_key_id='****', aws_secret_access_key='****') sql = s3.get_object(Bucket='<バケット名>', Key='<バケット名を除くフルパス(頭に'/'を入れない)>')['Body'].read().decode('utf-8') print(sql) if __name__ == '__main__': main()
この結果になった際に考えたこと
boto2で実行した際にエラーとなりました。
エラーメッセージにホスト名が云々というのがあったので、S3にはパスベースと仮想ホストベースの指定があったよな?(2020/9月末にパスベース指定は廃止になっています)と思いググったら、まさしくそれ、と言った情報が得られました。
そこで、バケット名に".”を含まないバケットで実行したところ、エラーなく実行できました。
では、boto3ならどうだろう?と思い、追加でboto3でやってみたところ、"."のあるなしにかかわらず結果が得られました。中で良しなにやっているのでしょうね。
boto3では問題なく動きましたが、バケット名には"."が含まれないほうがよさそうですね。