Python module - jsonschema Part 1
Posted on Mar 20, 2018 in Python 模組/套件推薦 by Amo Chen ‐ 3 min read
本文為 Python module - jsonchema 一系列教學文:
JSON 目前資料交換格式的主流之一,然而如果要在程式中驗證 JSON 資料的格式是否正確,就需要花費一些心力撰寫驗證的程式碼。所幸現在有 JSON Schema 可以讓驗證 JSON 格式簡單化,如果是以 JSON 作為資料交換格式的 API ,可以考慮使用 JSON Schema 進行驗證。
JSON Schema is a vocabulary that allows you to annotate and validate JSON documents.
本文為 Python 的 jsonschema 套件與驗證 JSON 格式的相關教學。
目前 JSON Schema 仍在草稿階段(draft-07),詳情請參閱 Specification 。而必須注意的是本文所使用的 python jsonschema 模組只支援 draft-03
與 draft-4
2 種版本,因此有些較新的語法是不支援的。
本文環境
- Python 3.5
- jsonschema 2.6.0
安裝 jsonschema
$ pip install jsonschema
Hello, jsonschema!
Python 的 jsonschema 模組驗證的是由 Python 資料型別組成的資料,並非 JSON 字串,如果想對 JSON 字串進行驗證,就必須先用 json.loads()
轉換成 Python 的資料型別。
先以範例了解 JSON Schema 的概觀,假設有一個登入的 API 以 JSON 作為交換格式,該 JSON 格式中必須包含 username
與 password
作為登入之用,如果轉換成 Python 的 dictionary 就會長得像這樣: {'username': 'foobar', 'password': '123456'}
,那麼我們可以針對這格式定義一個 schema 進行格式驗證。
以下是含有 username
及 password
2 個屬性的 schema ,接著以 validate()
對一個 Python dictionary 進行格式驗證的範例。
from jsonschema import validate
schema = {
'type': 'object',
'properties': {
'username': {
'type': 'string',
'minLength': 6,
},
'password': {
'type': 'string',
'minLength': 8,
},
}
}
validate({'username': 'foobar', 'password': '123456'}, schema)
執行結果:
ValidationError: '123456' is too short
Failed validating 'minLength' in schema['properties']['password']:
{'minLength': 8, 'type': 'string'}
On instance['password']:
'123456'
從執行結果可以知道 {'username': 'foobar', 'password': '123456'}
驗證沒通過(原因在於 password
長度限制至少為 8 碼)。
透過上述範例,已經能夠使我們了解 jsonchema 如何驗證資料格式,後續將會更詳細地介紹如何定義 JSON Schema 。
Primitive Types
第 1 個範例中的 schema 的 type
關鍵字指的是資料是何種型別,定義一個 JSON Shema 就是在組合這些型別。
The type keyword is fundamental to JSON Schema. It specifies the data type for a schema.
而 JSON Schema 目前定義 6 種資料型別,每 1 種都可以對應回 Python 的資料型別,如下表所示:
| JSON Schema | Python |
|-----------------------------------|
| object | dict |
| array | list, tuple |
| string | str |
| number | int, float, decimal |
| boolean | bool |
| null | None |
null
null
是最簡單的 type ,它對應到的只有 None
。
驗證格式時,除了 None
之外的任何 type 都會驗證失敗,以下是範例:
from jsonschema import validate
schema = {'type': 'null'}
# would raise exception
validate(123, schema)
執行結果:
ValidationError: 123 is not of type 'null'
Failed validating 'type' in schema:
{'type': 'null'}
On instance:
123
上述範例只要把 123
換成 None
就會通過驗證了。
boolean
boolean
對應到 Python 的 True
False
,只要是這 2 個值之外的都會驗證失敗。
schema = {'type': 'boolean'}
# would raise exception
validate(None, schema)
執行結果:
ValidationError: None is not of type 'boolean'
Failed validating 'type' in schema:
{'type': 'boolean'}
On instance:
None
同樣地,只要將上述範例中的 None
換為 True
或是 False
即可通過驗證。
number
number
對應的是 Python 的 int
float
decimal
,如果把字串丟進去驗證就會驗證失敗。
範例:
schema = {'type': 'number'}
# would raise exception
validate('123', schema)
執行結果:
ValidationError: '123' is not of type 'number'
Failed validating 'type' in schema:
{'type': 'number'}
On instance:
'123'
這時候只要把 '123'
換成 123
就會正確了。
string
string
對應的是 Python 的 str
,連空字串 ''
也屬於合法的字串。
範例:
schema = {'type': 'string'}
# would pass
validate('', schema)
上述範例會通過驗證,如果放進非字串的值,則會驗證失敗。
array
array
對應的是 Python 的 list
tuple
,連空的 list
tuple
也屬合法。
schema = {'type': 'array'}
# would pass
validate([1, 2], schema)
上述範例同樣會通過驗證,如果 [1, 2]
改為非 list
或 tuple
的值,則會驗證失敗。
object
object
相當於 Python 的 dict (也就是字典),空的 dict 也屬合法。
schema = {'type': 'object'}
# would pass
validate({'foo': 'bar'}, schema)
上述範例代入了 dict {'foo': 'bar'}
,所以通過 JSON Schema 的驗證,可以試著代入非 dict 型別的值,看看會發生何事。
小結
認識 6 種 JSON Schema 的資料型別之後,至此對 JSON Schema 應已有基礎的認識。
下一篇將會介紹如何利用此 6 種型態組合 JSON Schema 進行複雜的 JSON 格式驗證。
References
http://json-schema.org/
https://spacetelescope.github.io/understanding-json-schema/index.html