awscli s3apiでの日本語を含むオブジェクト操作
日本語などnon-ascii文字列を含むオブジェクト操作のメモ
"nonあascii" (unicode: \u3042) というオブジェクト名を想定します。
aws s3 rm
ふつうに日本語で実行できる。 (おそらく実行環境に依る)
# Key does not exist aws s3 rm "s3://bucket/non\u3042ascii" # delete successful aws s3 rm "s3://bucket/nonあascii"
s3api delete-object
こちらも同様。 ただ、s3コマンドと違ってファイルの存在を確認しないため、バージョニングが有効だと存在しないファイルにデリートマーカをつくる。
# successful aws s3api delete-object --bucket "bucket" --key "nonあascii" # fail (create delete marker to non\\u3042ascii) aws s3api delete-object --bucket "bucket" --key "non\u3042ascii"
s3api delete-objects
複数指定したい場合は、delete-objects。
以下は失敗パターン。
defaultencoding=asciiの環境だと 'ascii' codec can't encode character u'\u3042' in position 24: ordinal not in range(128)
のエラーが出る。
aws s3api delete-objects --bucket "bucket" \ --delete '{"Objects":[{"Key":"non\u3042ascii"}],"Quiet":false}' aws s3api delete-objects --bucket "bucket" \ --delete '{"Objects":[{"Key":"nonあascii"}],"Quiet":false}'
sitecustomize.pyでデフォルトエンコーディングをUTF-8に変更するとどちらもXML不正エラーが出る。
A client error (MalformedXML) occurred when calling the DeleteObjects operation: The XML you provided was not well-formed or did not validate against our published schema
何が起きているかというと、XMLがおかしい。
0x0000: 4500 0074 8db1 4000 4006 10a5 ac1f 18d5 E..t..@.@....... 0x0010: 36e7 a052 bab8 0050 ddd0 5f96 019d f618 6..R...P.._..... 0x0020: 5018 0073 9c94 0000 3c44 656c 6574 653e P..s....<Delete> 0x0030: 3c4f 626a 6563 743e 3c4b 6579 3e6e 6f6e <Object><Key>non 0x0040: e381 8261 7363 6969 3c2f 4b65 793e 3c2f ...ascii</Key></ 0x0050: 4f62 6a65 6374 3e3c 5175 6965 743e 6661 Object><Quiet>fa 0x0060: 6c73 653c 2f51 7569 6574 3e3c 2f44 656c lse</Quiet></Del 0x0070: 6574 653e ete>
ということで、XML実体参照で送る。
aws s3api delete-objects --bucket "bucket" \ --delete '{"Objects":[{"Key":"nonあascii"}],"Quiet":false}'
まとめ
- s3apiの引数でJSONを指定する場合、non-asciiな文字列はXML実体参照で入れる
JSONとXMLの変換の闇でした。