curlで取得したAPIレスポンスをJSON整形できる python -m json.tool の便利な使い方

# はじめに

APIレスポンスのJSON整形には`jq`がよく使用される印象ですが、`python -m json.tool`を使用することで、`jq`のインストールなしで見やすいレスポンス形式に整形できます。Pythonが入っている環境であれば追加インストール不要で使用できるので、特に新しい環境でのセットアップ時や、一時的な作業環境での使用に便利です。



# 対象の方
- jqコマンドはインストールしていないが、curlでコールしたAPIのレスポンスを整形したい方
- 新しい環境ですぐにJSON整形をしたい方

# 結論

```bash
curl "APIのリンク" | python -m json.tool
```

上記のように `python -m json.tool` オプションをつけることでインデントが整形されたレスポンスを取得できます。

:::note warn

日本語部分がエスケープされる場合は`--no-ensure-asciiオプションを追加することで、日本語を正しく表示できました。
```bash
curl "APIのリンク" | python -m json.tool --no-ensure-ascii
```
:::


# ゴール
モックサーバに対してcurlでAPIコールし、インデントが整形されたJSON形式のレスポンスを取得できることを確認します。

例えば、以下のような一行のJSONレスポンスを

```bash
{"id":1,"name":"テストユーザー","age":30,"department":"開発部"}
```

次のように見やすく整形された形で取得できることをゴールとします。

```json
{
    "id": 1,
    "name": "テストユーザー",
    "age": 30,
    "department": "開発部"
}
```


# python -m json.toolとは

- `-m` オプション：Pythonのモジュールを指定します

 > -m モジュール名 として Python モジュールパスにあるモジュールを指定された場合、そのモジュールをスクリプトとして実行します。
 https://docs.python.org/ja/3/using/cmdline.html#interface-options


 - json.tool：JSON形式に整形出力します

 > json.tool モジュールは JSON オブジェクトの検証と整形出力のための、単純なコマンドラインインターフェイスを提供します
 https://docs.python.org/ja/3/library/json.html#module-json.tool
 

# コールするモックAPIを作成

コールの対象とする簡単なモックサーバをPostmanで作成します。

1. Postman「Mock Servers」 > create mock server をクリック
2. サンプルのエンドポイントを作成
   - パス: `/users`
   - メソッド: GET
   - Response Code:200
```json:response body
{"users":[{"id":1,"name":"ほげほげたろう1","age":24,"department":"開発部"},{"id":2,"name":"ほげほげたろう2","age":25,"department":"営業部"},{"id":3,"name":"ほげほげたろう3","age":29,"department":"人事部"}],"total":3,"page":1}
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1247619/1367987d-fa87-69f8-752d-ff20022f6dd0.png)


## curlでのAPI呼び出しと整形の比較

### 整形なしの場合
```bash
$ curl "モックサーバのエンドポイントリンク/users"
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   255  100   255    0     0    256      0 --:--:-- --:--:-- --:--:--   256{"users":[{"id":1,"name":"ほげほげたろう1","age":24,"department":"開発部"},{"id":2,"name":"ほげほげたろう2","age":25,"department":"営業部"},{"id":3,"name":"ほげほげたろう3","age":29,"department":"人事部"}],"total":3,"page":1}

```

レスポンスが一行で表示されており、横に伸びているため見切れています。
これでは見づらいですね、、


### python -m json.toolを使用した場合
```bash
$ curl "モックサーバのエンドポイントリンク/users" | python -m json.tool --no-ensure-ascii
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   255  100   255    0     0    271      0 --:--:-- --:--:-- --:--:--   271
{
    "users": [
        {
            "id": 1,
            "name": "ほげほげたろう1",
            "age": 24,
            "department": "開発部"
        },
        {
            "id": 2,
            "name": "ほげほげたろう2",
            "age": 25,
            "department": "営業部"
        },
        {
            "id": 3,
            "name": "ほげほげたろう3",
            "age": 29,
            "department": "人事部"
        }
    ],
    "total": 3,
    "page": 1
}

```

インデントが整って見やすくなりました。

:::note info
日本語対応について
APIレスポンスに日本語が含まれる場合、デフォルトでは以下のようにユニコードエスケープされて表示されます。

```bash
$ curl "モックサーバのエンドポイントリンク/users" | python -m json.tool
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   255  100   255    0     0    256      0 --:--:-- --:--:-- --:--:--   256
{
    "users": [
        {
            "id": 1,
            "name": "\u7e3a\uff7b\u7e3a\u5075\u2287\u7e3a\u5075\u25c6\u7e67\u962a\u22671",
            "age": 24,
            "department": "\u9ae2\u72d7\u5331\u9a5b\uff68"
        },
        {
            "id": 2,
            "name": "\u7e3a\uff7b\u7e3a\u5075\u2287\u7e3a\u5075\u25c6\u7e67\u962a\u22672",
            "age": 25,
            "department": "\u875f\uff76\u8b8c\uff6d\u9a5b\uff68"
        },
        {
            "id": 3,
            "name": "\u7e3a\uff7b\u7e3a\u5075\u2287\u7e3a\u5075\u25c6\u7e67\u962a\u22673",
            "age": 29,
            "department": "\u83a0\uff7a\u83a0\u77e9\u039a"
        }
    ],
    "total": 3,
    "page": 1
}

```
この場合、`--no-ensure-ascii` オプションを追加することで、日本語を正しく表示できました。

:::

API開発作業が少し快適になれば幸いです。


# 参考
https://docs.python.org/ja/3/using/cmdline.html#interface-options

https://docs.python.org/ja/3/library/json.html#module-json.tool

https://learning.postman.com/docs/designing-and-developing-your-api/mocking-data/setting-up-mock/