Pythonでコンフィグファイルを簡単に読み込むライブラリを作った

## はじめに

Pythonでアプリケーションを作成する際に、設定やパラメータを`ini`や`json`, `yaml`形式のコンフィグファイルで持つことが多いと思います。
そのコンフィグファイルを簡単に読み込めるライブラリ`confile`を作成しました!

## インストール

インストールはpipで行います。

```python
pip install confile
```

## 使用方法

### 使用例

下記はデータベースの接続情報が記述されたiniファイルです。

```ini:database.ini
[mysql]
host=localhost
port=3306
user=user
password=password
db=db
```

使い方は`read_config`でファイルを読み込み、`get_property`, `to_dict`で値を取得します。

```python
>>> import confile
# MySQL接続用
>>> import pymysql

>>> db_config = confile.read_config('database.ini')

>>> db_config.get_property('mysql', 'host')
'localhost' 

>>> db_config.get_property('mysql', 'port')
3306 # int型で返却

>>> db_config.get_property('mysql')
{'host': 'localhost', 'port': 3306, 'user': 'user', 'password': 'password', 'db': 'db'}

>>> db_config.to_dict()
{'mysql': {'host': 'localhost', 'port': 3306, 'user': 'user', 'password': 'password', 'db': 'db'}}

# MySQLに接続
>>> conn = pymysql.connect(**db_config.get_property('mysql'))
```

### ネストの深いコンフィグファイル

ネストの深いコンフィグファイルから値を取り出す例です。

```json:nest.json
{
  "nest1": {
    "nest2": {
      "nest3": "OK"
    }
  }
}
```


```python
>>> nested_config = confile.read_config('nest.json')

>>> nested_config.get_property('nest1')
{'nest2': {'nest3': 'OK'}}

>>> nested_config.get_property('nest1', 'nest2')
{'nest3': 'OK'}

>>> nested_config.get_property('nest1', 'nest2', 'nest3')
'OK'

>>> nested_config.to_dict()
{'nest1': {'nest2': {'nest3': 'OK'}}}
```

### 特殊な拡張子

内部でファイル種別の判別に拡張子を利用しています。
そのため`cnf`・`conf`・`cfg`のような拡張子の場合、明示的にファイルの種別を指定します。

```bash
>>> config = confile.read_config('db.conf', file_type='ini')
```
`file_type`には`ini`, `json`, `yml`, `yaml`の指定可能です。

## 「既存ライブラリとの違い」と「本ライブラリの特徴」

ビルドインやサードパーティのライブラリを用いることでもコンフィグファイルの読み込みは可能であり、本ライブラリも内部で使用しています。

| 種別       | ライブラリ   | 
|-----------|------------ |
| ini       | configparser|
| json      | column      |
| yaml      | PyYAML      |

その中でも具体的な本ライブラリの特徴は下記の２つです。

### インターフェースの統一

コンフィグファイルの種別にかかわらず`read_config`でコンフィグファイルを読み込み、
`get_property`, `to_dict`で値の取得が可能です。

### 型の自動判別

[configparser](https://docs.python.org/ja/3/library/configparser.html)のページより

>Config parser は値のデータ型について何も推論せず、常に文字列のまま内部に保存します。他のデータ型が必要な場合は自分で変換する必要があります

特にiniファイルのおいては、どのデータ型で扱いたいか意識しておく必要があります。
下記はconfigparserを利用して、上記の`db.ini`を読み込んだ例です。

```python
>>> import configparser
>>> config = configparser.ConfigParser()
>>> config.read('db.ini')
# portを出力
>>> config.get('mysql', 'port')
'3306' # str型で返却
>>> config.getint('mysql', 'port')
3306 # int型で返却
```

本ライブラリではデータ型については`ast`を使用して推論を行っています。

## コンフィグファイル

本ライブラリから読み込むと、下記の３ファイルは同じ結果を返却します。

```ini:sample.ini
[test]
string = string
int = 0
float = 0.0
date = 2001-01-23
boolean_true = True
boolean_false = False
list = ['a' ,'b', 'c']
dict = {'a': 1, 'b': 2, 'c': 3}
```

```json:sample.json
{
  "test": {
    "string": "string",
    "int": 0,
    "float": 0.0,
    "date": "2001-01-23",
    "boolean_true": true,
    "boolean_false": false,
    "list": [
      "a",
      "b",
      "c"
    ],
    "dict": {
      "a": 1,
      "b": 2,
      "c": 3
    }
  }
}
```

```yaml:sample.yml
test:
  string: string
  int: 0
  float: 0.0
  date: 2001-01-23
  boolean_true: True
  boolean_false: False
  list:
    - a
    - b
    - c
  dict:
    a: 1
    b: 2
    c: 3
```

iniファイルは読み込む際に`ast`を利用しているため、Pythonの記法を利用してリスト・辞書を表現できます。

## おわりに

コンフィグファイルを読み込むためのライブラリを作成しました。
初めてのライブラリを作成ので、おかしなところもあると思いますがぜひ利用してみてください！
[GitHub](https://github.com/777nancy/confile)