[Cloudian #9] Python(boto3)で、オブジェクトのメタデータを表示してみる


## はじめに
[Cloudian](https://cloudian.com/jp/)は、AWSのS3完全互換のAPIを持ったオブジェクトストレージです。
[前回](https://qiita.com/yamahiro/items/395437a72df179786b0c)は、Python(boto3)で、バケットのバージョニング設定をしてみました。

今回は、Python(boto3)で、オブジェクトストレージのオブジェクトのメタデータ表示を行っていこうと思います。


## オブジェクトのメタデータ表示 / head_object()
アップロード時にオブジェクトに付与したメタデータを、head_object()で表示します。


## 1. 最新バージョンのオブジェクトのメタデータ
以下の例では、バケット「pythonbucket2」に保存されているキー「10mb.dat」の最新バージョンのオブジェクトに付与されているメタデータを表示させています。

```python:test1.py
import boto3

client = boto3.client(
    's3',
    endpoint_url='https://xxx.yyy.com'
)


# バケット名: pythonbucket2fix の オブジェクトのメタデータ表示
ret = client.head_object(Bucket='pythonbucket2fix', Key='10mb.dat')

print(ret)
```

```bash
{'ResponseMetadata': {'RequestId': '9dad3fc3-0e30-1dbc-a754-06bdfcde1d5e',
  'HostId': '',
  'HTTPStatusCode': 200,
  'HTTPHeaders': {'date': 'Sun, 13 Dec 2020 22:43:10 GMT',
   'x-amz-request-id': '9dad3fc3-0e30-1dbc-a754-06bdfcde1d5e',
   'last-modified': 'Sun, 13 Dec 2020 22:40:57 GMT',
   'etag': '"669fdad9e309b552f1e9cf7b489c1f73-2"',
   'content-type': 'binary/octet-stream',
   'x-amz-server-side-encryption': 'AES256',
   'x-amz-version-id': 'fe14c26b-bba0-6edf-a754-06bdfcde1d5e',
   'accept-ranges': 'bytes',
   'content-length': '10485760',
   'server': 'CloudianS3'},
  'RetryAttempts': 0},
 'AcceptRanges': 'bytes',
 'LastModified': datetime.datetime(2020, 12, 13, 22, 40, 57, tzinfo=tzutc()),
 'ContentLength': 10485760,
 'ETag': '"669fdad9e309b552f1e9cf7b489c1f73-2"',
 'VersionId': 'fe14c26b-bba0-6edf-a754-06bdfcde1d5e',
 'ContentType': 'binary/octet-stream',
 'ServerSideEncryption': 'AES256',
 'Metadata': {}}
```

格納されているバケットのバージョニング機能が有効にされており、かつバージョンID を指定しないで head_object()を実行した場合には、そのバケットに保存されている最新バージョンのオブジェクトに付与されているメタデータを返します。

## 2. 過去バージョンのオブジェクトのメタデータ
以下の例では、バージョニング機能が有効になっているバケット「pythonbucket2fix」に保存されているキー「10mb.dat」の、バージョンID「fe14c26b-bed0-c73f-a754-06bdfcde1d5e」のオブジェクトに付与されているメタデータを表示させています。

```python:test1.py
import boto3

client = boto3.client(
    's3',
    endpoint_url='https://xxx.yyy.com'
)


# バケット名: pythonbucket2fix の オブジェクトのメタデータ表示
ret = client.head_object(Bucket='pythonbucket2fix', Key='10mb.dat', VersionId='fe14c26b-bed0-c73f-a754-06bdfcde1d5e')

print(ret)
```

```bash
{'ResponseMetadata': {'RequestId': '9dad3fdf-0e30-1dbc-a754-06bdfcde1d5e',
  'HostId': '',
  'HTTPStatusCode': 200,
  'HTTPHeaders': {'date': 'Sun, 13 Dec 2020 22:43:41 GMT',
   'x-amz-request-id': '9dad3fdf-0e30-1dbc-a754-06bdfcde1d5e',
   'x-amz-meta-engineer': 'yamahiro',
   'x-amz-meta-company': 'nw',
   'x-amz-meta-purpose': 'boto3 demo 1',
   'last-modified': 'Sun, 13 Dec 2020 22:40:52 GMT',
   'etag': '"669fdad9e309b552f1e9cf7b489c1f73-2"',
   'content-type': 'binary/octet-stream',
   'x-amz-server-side-encryption': 'AES256',
   'x-amz-version-id': 'fe14c26b-bed0-c73f-a754-06bdfcde1d5e',
   'accept-ranges': 'bytes',
   'content-length': '10485760',
   'server': 'CloudianS3'},
  'RetryAttempts': 0},
 'AcceptRanges': 'bytes',
 'LastModified': datetime.datetime(2020, 12, 13, 22, 40, 52, tzinfo=tzutc()),
 'ContentLength': 10485760,
 'ETag': '"669fdad9e309b552f1e9cf7b489c1f73-2"',
 'VersionId': 'fe14c26b-bed0-c73f-a754-06bdfcde1d5e',
 'ContentType': 'binary/octet-stream',
 'ServerSideEncryption': 'AES256',
 'Metadata': {'Engineer': 'yamahiro',
  'Company': 'nw',
  'Purpose': 'boto3 demo 1'}}
```
  

## 補足: メタデータのみ選択して表示 
以下の例は、バージョン ID を指定してオブジェクトのメタデータのみを表示させています。

```python
print("~ メタデータのみ選択して表示 ~")
ret = client.head_object(Bucket='pythonbucket2fix',
                Key='10mb.dat',
                VersionId='fe14c26b-bba0-6edf-a754-06bdfcde1d5e'
            )['Metadata']
print(ret)
ret = client.head_object(Bucket='pythonbucket2fix',
                Key='10mb.dat',
                VersionId='fe14c26b-bd5e-4b7f-a754-06bdfcde1d5e'
            )['Metadata']
print(ret)
ret = client.head_object(Bucket='pythonbucket2fix',
                Key='10mb.dat',
                VersionId='fe14c26b-bed0-c73f-a754-06bdfcde1d5e'
            )['Metadata']
print(ret)
ret = client.head_object(Bucket='pythonbucket2fix',
                Key='10mb.dat',
                VersionId='fe14c26b-c075-286f-a754-06bdfcde1d5e'
            )['Metadata']
print(ret)
```

```bash
~ メタデータのみ選択して表示 ~
{}
{'Engineer': 'miki', 'Company': 'nw', 'Purpose': 'boto3 demo 2'}
{'Engineer': 'yamahiro', 'Company': 'nw', 'Purpose': 'boto3 demo 1'}
{}
```


## 補足: get_object と head_object の違い
以下のように”get_object”メソッドでも同様の情報を取得できますが、”head_object”はオブジェクト自体を戻さずにメタデータのみを読み取ることができます。

```python
ret = client.get_object(Bucket='pythonbucket2fix',
                Key='10mb.dat',
                VersionId='fe14c26b-bed0-c73f-a754-06bdfcde1d5e'
            )

print(ret)
```

```bash
{'ResponseMetadata': {'RequestId': '9dad3fed-0e30-1dbc-a754-06bdfcde1d5e', 'HostId': '', 'HTTPStatusCode': 200, 'HTTPHeaders': {'date': 'Sun, 13 Dec 2020 22:45:43 GMT', 'x-amz-request-id': '9dad3fed-0e30-1dbc-a754-06bdfcde1d5e', 'x-amz-version-id': 'fe14c26b-bed0-c73f-a754-06bdfcde1d5e', 'accept-ranges': 'bytes', 'etag': '"669fdad9e309b552f1e9cf7b489c1f73-2"', 'content-type': 'binary/octet-stream', 'x-amz-meta-engineer': 'yamahiro', 'x-amz-meta-company': 'nw', 'x-amz-meta-purpose': 'boto3 demo 1', 'x-amz-server-side-encryption': 'AES256', 'last-modified': 'Sun, 13 Dec 2020 22:40:52 GMT', 'content-length': '10485760', 'server': 'CloudianS3'}, 'RetryAttempts': 0}, 'AcceptRanges': 'bytes', 'LastModified': datetime.datetime(2020, 12, 13, 22, 40, 52, tzinfo=tzutc()), 'ContentLength': 10485760, 'ETag': '"669fdad9e309b552f1e9cf7b489c1f73-2"', 'VersionId': 'fe14c26b-bed0-c73f-a754-06bdfcde1d5e', 'ContentType': 'binary/octet-stream', 'ServerSideEncryption': 'AES256', 'Metadata': {'Engineer': 'yamahiro', 'Company': 'nw', 'Purpose': 'boto3 demo 1'}, 'Body': <botocore.response.StreamingBody object at 0x11b134588>}
```

メタデータのみ読み取りたい場合は、”head_object”を使用するほうがお薦めです。

```python
ret = client.get_object(Bucket='pythonbucket2fix',
                Key='10mb.dat',
                VersionId='fe14c26b-bed0-c73f-a754-06bdfcde1d5e'
            )['Metadata']

print(ret)
```

```bash
{'Engineer': 'yamahiro', 'Company': 'nw', 'Purpose': 'boto3 demo 1'}
```


## まとめ
Python(boto3)で、バケットのバージョニング設定をしてみました。

[次回](https://qiita.com/yamahiro/items/804dd2c89316ef7b8d57)も、Pythonでオブジェクトストレージ/Cloudianをいろいろ操作していきたいと思います。