LoginSignup
35

More than 3 years have passed since last update.

pythonでjsonスキーマを使用する

Last updated at Posted at 2019-09-07

はじめに

JSON形式の通信データのやり取りをする際に、プログラムや装置に悪影響を及ぼさないために通信データのチェックをすると思います。
ただ、そのチェックを一から組むのは手間なのでチェックの設定とデータを与えるとチェックを実行してくれる仕組みが作られています。
チェックの設定はJSONスキーマ、チェック用のライブラリはpythonのjsonschemaを使用します。
JSONスキーマに関しては公式のサイトがあります。

環境

  • python:3.6.5
  • jsonschema:3.0.1

JSONスキーマによるチェック方法

JSON形式のデータをチェックするためのJSONスキーマを作成して、pythonに読み込みチェックする方法を記載します。

JSONスキーマの説明の記載

直接的にデータのチェックには使いませんが、作成したJSONスキーマがどのようなものなのかを表す情報を記載します。

key 説明
$schema jsonスキーマのバージョン(例はdraft-7版)
title 名前
description メモ
schema.json
{
    "$schema": "http://json-schema.org/draft-07/schema#",
    "title": "PyJsonValidate",
    "description": "sample json for json validate",
}

JSONスキーマのデータチェックの設定

データのチェックの設定を記載していきます。
色々な設定ができますが、詳細は次に説明することにして、ここでは簡単な例を記載します。

key 説明
type 型(例は連想配列と文字列と整数)
properties json内の子要素(例はnameとageキー)
schema.json
{
    "$schema": "http://json-schema.org/draft-07/schema#",
    "title": "PyJsonValidate",
    "description": "sample json for json validate",
    "type": "object",
    "properties" :{
        "name": {
            "type": "string"
        },
        "age": {
            "type": "integer"
        }
    }
}

pythonでjsonスキーマを読み込む

pythonのjsonschemaライブラリに使用するため、作成したjsonスキーマファイルを読み込みます。読み込んだjsonスキーマファイルはjsonライブラリでdict型にしておきます。

json_schema_main.py
import json

with open('schema.json') as file_obj:
    json_schema = json.load(file_obj)

pythonでデータのチェックをする

読み込んだjsonスキーマファイルのdictとサンプルのdictをjsonschemaライブラリに読み込ませることでサンプルデータ(item)のチェックを行います。

json_schema_main.py
import json
from jsonschema import validate, ValidationError

with open('schema.json') as file_obj:
    json_schema = json.load(file_obj)

item = {
    "kind":"cat",
    "name": "tama",
}

try:
    validate(item, json_schema)
except ValidationError as e:
    print(e.message)

print('END')

結果

# python3 json_schema_main.py
END

itemの中の要素はnameがstringなのでチェック結果がOKになり、正常に終了します。
itemの中のnameを"name": 12,に変えて実施してみます。

結果

# python3 json_schema_main.py
12 is not of type 'string'
END

チェックが正常に動き、nameがstringではないとエラーが出ました。

入力必須なキーを指定する

実際に使用するときは必ずプログラムに必要なデータがあると思います。そのようなデータは必ずデータに入れてほしいため、必須キーとしてJSONスキーマのrequiredに教えてあげることでチェック対象になります。
nameとageを必須キーとして設定しました。

schema.json
{
    "$schema": "http://json-schema.org/draft-07/schema#",
    "title": "PyJsonValidate",
    "description": "sample json for json validate",
    "type": "object",
    "required": [
        "name",
        "age"
    ],
    "properties" :{
        "name": {
            "type": "string"
        },
        "age": {
            "type": "integer"
        }
    }
}

itemにageが含まれていないpythonを実行しました。

結果

# python3 json_schema_main.py
'age' is a required property
END

itemにageが含まれていないため、チェックが働き、ageが必須だという旨のメッセージが表示されました。
もちろんitemにageが含まれているときは何もエラーを出さずに終了します。

指定外キーをチェックする

プログラムによっては、不要なものは入力してほしくないケースがあります。そのような場合は、propertiesに設定したキー以外を許す設定additionalPropertiesをFalseにしてあげることで指定していないキーをチェックすることができます。
具体的には上のpythonのkindがそれにあたります。

schema.json
{
    "$schema": "http://json-schema.org/draft-07/schema#",
    "title": "PyJsonValidate",
    "description": "sample json for json validate",
    "type": "object",
    "additionalProperties": false,
    "required": [
        "name",
        "age"
    ],
    "properties" :{
        "name": {
            "type": "string"
        },
        "age": {
            "type": "integer"
        }
    }
}

上と同じpythonを実行しました。

結果

# python3 json_schema_main.py
Additional properties are not allowed ('kind' was unexpected)
END

kindがjsonスキーマに含まれていないため、チェックが働き、kindが許可されていない旨のメッセージが表示されました。
もちろんitemにkindがいないときは何もエラーを出さずに終了します。

おわりに

pythonでjsonスキーマを使用する方法について記載しました。とは言ってもpython要素はほぼなく、ほとんどjsonスキーマのお話になってしまいました。
jsonスキーマは、python特有のものではなく様々な言語で使用されているので汎用性が高いかなと思っています。
これ以外にも頑張れば色々なことがjsonスキーマでできるので機会があればまとめてみます。
jsonスキーマを色々な機能を使用するにまとめてみました。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
35