はじめに
YAML(YAML Ain’t Markup
Language)は、人間が読み書きしやすい構造化データ形式で、設定ファイルやデータ交換に広く利用されている。インデントを使ったシンプルな構文で、リストや連想配列などの複雑なデータ構造を表現できる。
YAMLの基本
YAMLの構造
YAMLはインデントで構造を表す。インデントはスペース(ふつうは2か4)で表現する。タブはNG。
parent:
childe1: value1
childe2: value2
grandchilde: value3
この例ではキー-バリューの対応構造を表している。大文字小文字は区別される。
コメント
#でコメントを書ける。
# ユーザー設定
users:
# 管理者ユーザー
admin: true
データ型
YAMLにはいくつかのデータ型がある。型の指定は必要ない。
文字列
引用符なしでテキストを表す。
引用符を使ってもよい。エスケープがいるときは引用符が必要。
multiline: "This is a string\nthat spans\nmultiple lines"
改行したい場合は|か>を使う。
multiline_text: |
This is a
multi-line
string in YAML
folded_text: >
This is a
folded multi-line
string that will be
converted to a single line
|は改行を保持するが、>は1行に変換される。
数値
整数と浮動小数点数をサポート。
int_value: 42
float_value: 3.14
ブール値
trueかfalseで値を表す。
null値
空の値をnull、-、""で表す。
key1: null
key2: -
key3: ""
日付/時刻
date_only: 2023-10-01
datetime_with_timezone: 2023-10-01T12:30:45Z
datetime_local: 2023-10-01T12:30:45
detailed_time: 2023-10-01T12:30:45.123456+09:00
データ構造
マップ
キー-バリューの対応構造をマップ(連想配列)というが、それを次のように表す。
simple_map:
key1: value1
key2: value2
key3: value3
リスト
リスト(配列)は次のように表す。
simple_list:
- item1
- item2
- item3
次のように書いてもよい。
simple_list: [item1, item2, item3]
複合データ構造
マップとリストが混ざってもよい。
users:
- name: John Doe
age: 30
roles:
- admin
- user
- name: Jane Smith
age: 25
roles:
- user
少し細かい項目
ドキュメントマーカー
ドキュメントを複数含めることができ、ドキュメントの開始を---で、終わりを...で表す。
# ドキュメント1
---
name: "Document 1"
content: "This is the first document"
...
# ドキュメント2
---
name: "Document 2"
content: "This is the second document"
...
# ドキュメント3
---
name: "Document 3"
content: "This is the third document"
...
終わりの方は省略可能。単一のドキュメントではほぼ使われないが、バリデーションでは警告が出るので、それがいやな場合は一番上に---と書けばよい。
アンカーとエイリアス
アンカーとエイリアスは、記述が重複するのを避けるための機能である。&でアンカーを設定し、*で表されるエイリアスと呼ばれるものでアンカーを参照する。
# アンカーを定義
defaults: &defaults
adapter: postgres
host: localhost
port: 5432
# エイリアスで参照
development:
<<: *defaults
database: dev_db
test:
<<: *defaults
database: test_db
ここで、<<はマージキーというもので、アンカーで定義されたマップをマージする。上の例のdevelopmentは、以下の内容と同じになる。
development:
adapter: postgres
host: localhost
port: 5432
database: dev_db
実際に展開された結果が見たければ、次のようなPythonスクリプトを使えばよい。
# expand_yaml.py
import yaml
with open('your_file.yaml') as f:
data = yaml.safe_load(f)
print(yaml.dump(data, default_flow_style=False))
上記YAMLに対する実行結果
$ python expand_yaml.py
defaults:
adapter: postgres
host: localhost
port: 5432
development:
adapter: postgres
database: dev_db
host: localhost
port: 5432
test:
adapter: postgres
database: test_db
host: localhost
port: 5432
実践的な使用
YAMLの検証
YAMLの検証を行うには、たとえばyamllintを使う。
インストール
実行
$ yamllint config.yaml
config.yaml
2:1 warning missing document start "---" (document-start)
11:4 error syntax error: expected <block end>, but found '<block mapping start>' (syntax)
ディレクトリにあるすべてのファイルをチェックすることもできる。
書式のチェックだけであれば、Pythonを使って以下のようにしてもよい。
python -c "import yaml; yaml.safe_load(open('config.yaml')); print('OK')"
設定ファイルとしての利用
YAMLは設定ファイルとして利用される。
# config.yaml
# アプリケーション設定
app:
name: "My Application"
version: 1.0.0
debug: true
log_level: "INFO"
# データベース設定
database:
host: "localhost"
port: 5432
name: "mydb"
user: "admin"
password: "secret"
max_connections: 10
# サーバー設定
server:
host: "0.0.0.0"
port: 8000
timeout: 30
allowed_origins:
- "http://localhost:3000"
- "https://example.com"
# 特別な設定
special:
features:
- "feature1"
- "feature2"
thresholds:
cpu: 90
memory: 80
Pythonでの利用例
# read_yaml.py
import yaml
import logging
from typing import Dict, Any
def load_config(config_path: str) -> Dict[str, Any]:
"""YAML設定ファイルを読み込む"""
with open(config_path, 'r') as file:
config = yaml.safe_load(file)
return config
def setup_logging(config: Dict[str, Any]) -> None:
"""ログ設定を適用"""
log_level = config['app']['log_level']
logging.basicConfig(
level=log_level,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
def main():
# 設定ファイルを読み込む
config = load_config('config.yaml')
# ログ設定を適用
setup_logging(config)
# 設定を使用してアプリケーションを構成
app_name = config['app']['name']
db_config = config['database']
server_config = config['server']
logging.info(f"Starting {app_name} version {config['app']['version']}")
# データベース接続(例)
#db = connect_to_database(db_config)
# サーバー起動(例)
#start_server(server_config)
# 特別な設定を使用
if 'feature1' in config['special']['features']:
logging.info("Feature1 is enabled")
if config['special']['thresholds']['cpu'] > 80:
logging.warning("High CPU threshold configured")
if __name__ == "__main__":
main()
JSONへの変換
import yaml
import json
import sys
# YAMLファイルをJSONに変換
def yaml_to_json(yaml_file, json_file=None):
try:
# YAMLファイルを読み込み
with open(yaml_file, 'r', encoding='utf-8') as f:
yaml_data = yaml.safe_load(f)
# JSONに変換
json_data = json.dumps(yaml_data, indent=2, ensure_ascii=False)
if json_file:
# JSONファイルに出力
with open(json_file, 'w', encoding='utf-8') as f:
f.write(json_data)
print(f"✅ {yaml_file} → {json_file} に変換完了")
else:
# 標準出力に表示
print(json_data)
except Exception as e:
print(f"エラー: {e}")
sys.exit(1)
# 使用例
if __name__ == "__main__":
yaml_to_json('config.yaml', 'config.json')
|