yamlを考える with python

## yamlってなんぞ？
### まえがき
kubernetesなどのクラウドネイティブな環境を設定するときに、yaml形式のファイルを読み込ませることが多い。
yamlのことがよくわかっていないまま使うのもどうかと思い、今回は実際に手を動かしながら勉強してみた。

### yamlの由来
[yamlの公式サイト](https://yaml.org/spec/1.2/spec.html)より
「“YAML Ain’t Markup Language” 」

「yamlはマークアップ言語ではない」という意味の再起的な頭文字で表されるデータ構造の書き方である。

### デザインゴール
YAMLのデザインゴールは以下の７つ。
1. YAMLは人にとって簡単に読みやすいものである
2. YAMLのデータはプログラム言語間で持ち運び可能である
3. YAMLはアジャイル言語のネイティブデータ構造と一致する
4. YAMLには、汎用ツールをサポートするための一貫したモデルがある
5. YAMLはワンパス処理をサポートする
6. YAMLは表現力豊かで拡張可能
7. YAMLの実装と使用は簡単

### loadとdump
yamlのデータを扱う場合には、loadとdumpがある。
loadはyamlデータをプログラムが理解していく流れに対し、dumpはプログラムがyamlデータに変換していく流れになる。すなわち、アプリから見たとき、yamlの入力が"load"、yamlの出力が"dump"と理解すれば大丈夫。
![公式サイト「３.１ Processing Overview」より](https://yaml.org/spec/1.2/overview2.png " 公式サイト「３.１ Processing Overview」より")
公式サイト「３.１ Processing Overview」より　　


## pythonで実装してみる
実際に手を動かして考える。今回はプログラム言語として、python3を使って実際にyamlを扱ってみる。

### pyyamlのインストール
pythonでyamlを使うのに[pyyaml](https://pyyaml.org/wiki/PyYAMLDocumentation)というパッケージがある。
pipを使ってインストールする。  
`pip install pyyaml`


### 実際にコードを書いてみる
yamlを読み込むloadおよびyamlを出力するdumpについてそれぞれコードを書いて確認する。
なお試した環境は以下。
- macOS 
- python:3.7.3
- pyYAML:5.3.1

#### 1. yamlのデータをpythonで読み込む（load）
##### test用のyaml ファイルを準備する
以下のようにyamlファイル（test.yaml）を作成する。

```yaml:test.yaml
env:
  python:3.7.3
  pyYAML:5.3.1
```
yamlに書かれたバージョン情報をpythonで取得する。

##### pythonでコードを書く
test.yamlと同一フォルダにyamlを読み込むためのpythonコード(data-reader.py)を作成する。

```python:data-reader.py
#!/usr/bin/env python3
from yaml import load, dump
try:
    from yaml import CLoader as Loader, CDumper as Dumper
except ImportError:
    from yaml import Loader, Dumper

with open('test.yaml', 'r') as yml:
    config = load(yml, Loader=Loader)

print("#### data_chcek ####")
print(config)
print("####################")

print("ソフトウェア/パッケージ名: 取得したバージョン")
print("python: {}".format(config['env']['python']))
print("pyYAML: {}".format(config['env']['pyYAML']))
```
##### 実行結果
terminalを開いて、以下のようにpythonコードを実行した。
yamlから取得したデータが多層構造の辞書型に変換され、目的のバージョン情報を取り出せることが確認できた。 

```
$ python3 data-reader.py 
#### data_chcek ####
{'env': {'python': '3.7.3', 'pyYAML': '5.3.1'}}
####################
ソフトウェア/パッケージ名: 取得したバージョン
python: 3.7.3
pyYAML: 5.3.1
```

#### 2. pythonで作成したデータをyamlファイルに出力する（dump）
##### pythonでコードを書く
辞書型のデータをサンプルで作成し、作成したデータをyaml形式に変換し出力する。
以下のようにpythonコード(data-writer.py)を作成した。

```python:data-writer.py
#!/usr/bin/env python3
from yaml import load, dump
try:
    from yaml import CLoader as Loader, CDumper as Dumper
except ImportError:
    from yaml import Loader, Dumper

# making data for yaml
item_list = ['apple', 'banana', 'orange']
amounts = [2, 3, 4]
sample_data = {item:value for item, value in zip(item_list, amounts)}

# data output to yaml
output = dump(sample_data, Dumper=Dumper)

with open("output_file.yaml", 'w') as yml:
    yml.write(output)
```
##### 実行結果
terminalを開いて、以下のようにpythonコードを実行する。
実行した結果、サンプルで作成した辞書型データがyaml形式に変換されていることが確認できた。

```
$ python3 data-writer.py
#### data_check ####
apple: 2
banana: 3
orange: 4

####################
output to output_file.yaml
```

出力したファイルの中身は以下で確認できる。

``` 
$ cat output_file.yaml                        
apple: 2
banana: 3
orange: 4
```
## まとめ
yamlについて、ドキュメントを読み、実際にコードを書きながら挙動を確認した。
今後loadおよびdump両面を意識ながら、yamlに関して知見を深めていきたい。