Name | believe JSON |
Version |
1.0.14
JSON |
| download |
home_page | None |
Summary | A easy to use validator for json content |
upload_time | 2024-04-08 07:29:05 |
maintainer | None |
docs_url | None |
author | None |
requires_python | >=3.6 |
license | None |
keywords |
json
validate
validator
|
VCS |
|
bugtrack_url |
|
requirements |
No requirements were recorded.
|
Travis-CI |
No Travis.
|
coveralls test coverage |
No coveralls.
|
# Believe
## Motivation
* We often need to compare expected results in our test. It's lousy to check expected result under the following way.
```
import uuid
class TestCases:
def test_user(self):
user = {
"name": "John",
"id": "30e7b1e2-4c80-44c2-8fe5-23bad73ed8f2"
}
assert set("name", "id") == set(user.keys())
assert isinstance(user["name"], str)
assert 0 < len(user["name"]) < 64
assert isinstance(user["id"], str)
uuid.UUID(user["id"])
```
* By using this package, we could compare the value using the following way. It's easier to read and maintain.
```
import believe as B
class TestCases:
def test_user(self):
user = {
"name": "John",
"id": "30e7b1e2-4c80-44c2-8fe5-23bad73ed8f2"
}
assert user == {"name": B.AnyStr(min_len=1, max_len=63),
"id": B.AnyUUID()}
```
* If you are looking for web framework input validation, I suggest use [FastAPI](https://fastapi.tiangolo.com/). It properly integrate with openapi as well.
## Installation
```
pip install believe
```
## Basic usage
```
import believe as B
import time
# Match any string
assert B.AnyStr() == "any_str"
# Match string length >= 1 and <= 10
assert B.AnyStr(min_len=1, max_len=10) == "a"
# Match any string that can be converted to int
assert B.AnyIntStr() == "123"
# Match any UUID format string
assert B.AnyUUID() == "732c0743-2638-47d5-902d-0daa3080348b"
# Match any sha1 string
assert B.AnySHA1() == "b130c4b97d0640eaf3f45f7360a5b4dbbf561f58"
# Match any IPv4 string
assert B.AnyIPV4() == "1.2.3.4"
# Match integer that is >=1 and <= 10
assert B.AnyInt(min_value=1, max_value=10) == 5
# Match any float that is >= 1.0 and <= 10.0
assert B.AnyFloat(min_value=1.0, max_value=10.0) == 5.0 # 1.0 <= X <= 10.0
# Match if values is "one" or "two"
assert B.OneOf("one", "two") == "one"
# Sometimes we don't care about the order, we can use AnyOrder
assert B.AnyOrder([1, 2, 3]) == [2, 1, 3]
# Sometimes we assign value as timestamp but test cases takes more than 1 sec
# We can use almost to accept a range of values
assert B.Almost(time.time(), ts_range=3) == time.time() # Allow 3 sec gap
# If we allow None or any string
assert B.Nullable(B.AnyStr()) == None
assert B.Nullable(B.AnyStr()) == "123"
# Only check type
assert B.Any(bytes) == b'123'
# Reverse check result, anything but "A" or "B"
assert B.Not(B.OneOf("A", "B")) == "C"
# Match list
assert B.ListOf(B.AnyStr()) == ["A", "B", "C"]
assert B.ListOf(B.AnyStr(), n_item=3) == ["A", "B", "C"] # exact 3 items
assert B.ListOf(B.AnyStr(), min_item=1) == ["A", "B", "C"] # >= 1 items
assert B.ListOf(B.AnyStr(), max_item=5) == ["A", "B", "C"] # <= 5 items
```
## Advance Usage
```
# If we don't want to use json.load('{"foo": "bar"}') == {"foo": "bar"}, we can use the following way
assert B.AnyJsonStr({"foo": "bar"}) == '{"foo": "bar"}'
# We can use AnyUrl to compare the normalized url
# 1. We can compare one with default port and one without, they are identical
assert B.AnyUrl("https://foo.com/") == "https://foo.com:443/"
assert B.AnyUrl("http://foo.com/") == "http://foo.com:80/"
# 2. We can ignore the order in query string
assert B.AnyUrl("https://foo.com/bar?p1=1&p2=2") == "https://foo.com/bar?p2=2&p1=1"
# We can use Dict to compare a dict with Optional field
assert B.Dict({"name": B.AnyStr(), "value": B.Optional(B.AnyStr())}) == {"name": "abc"}
assert B.Dict({"name": B.AnyStr(), "value": B.Optional(B.AnyStr())}) == {"name": "abc", "value": "def"}
# If key is a dynamic value, we can use DictOf(<key_matcher>, <value_matcher>)
# i.e. We want to match a dict with random uuid as key
assert B.DictOf(B.AnyUUID(), B.OneOf("ok", "fail")) == {"732c0743-2638-47d5-902d-0daa3080348b": "ok",
"5cfd50ba-c3d3-4fb7-b2fe-e9a6e039ad29": "fail"}
```
## Use Validate Function
```
# validate with error exception
import believe as B
validator = B.Dict({"name": B.AnyInt()})
B.validate(validator, {"name": "ken"}) # believe.error.ValidateError: [e_path=$.name] 'ken' != AnyInt()
```
## A Complex Example
```
import believe as B
import time
result_json = {"name": "john",
"age": 32,
"download_link": "https://download.server.com/?name=john&id=abc",
"role": "admin",
"address": "10.1.2.3",
"updated_at": int(time.time()),
"tags": ["admin", "john"]}
exp_result = B.Dict({"name": B.AnyStr(min_len=1, max_len=64),
"age": B.AnyInt(min_value=0, max_value=200),
"download_link": B.AnyUrl("https://download.server.com/?id=abc&name=john"),
"role": B.OneOf("admin", "user"),
"address": B.AnyIPV4(),
"updated_at": B.Almost(int(time.time())),
"tags": B.ListOf(B.AnyStr()),
"extra": B.Optional(B.Nullable(B.AnyStr()))})
B.validate(exp_result, result_json)
```
Raw data
{
"_id": null,
"home_page": null,
"name": "believe",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.6",
"maintainer_email": null,
"keywords": "json, validate, validator",
"author": null,
"author_email": "Seth Wang <pkyosx@gmail.com>",
"download_url": "https://files.pythonhosted.org/packages/e9/62/91a319ec8effe6568c94104540f32955246cff24dfefb3074103a27c97a0/believe-1.0.14.tar.gz",
"platform": null,
"description": "# Believe\n## Motivation\n* We often need to compare expected results in our test. It's lousy to check expected result under the following way.\n\n```\nimport uuid\n\nclass TestCases:\n def test_user(self):\n user = {\n \"name\": \"John\",\n \"id\": \"30e7b1e2-4c80-44c2-8fe5-23bad73ed8f2\"\n }\n assert set(\"name\", \"id\") == set(user.keys())\n assert isinstance(user[\"name\"], str)\n assert 0 < len(user[\"name\"]) < 64\n assert isinstance(user[\"id\"], str)\n uuid.UUID(user[\"id\"])\n```\n\n* By using this package, we could compare the value using the following way. It's easier to read and maintain.\n\n```\nimport believe as B\n\nclass TestCases:\n def test_user(self):\n user = {\n \"name\": \"John\",\n \"id\": \"30e7b1e2-4c80-44c2-8fe5-23bad73ed8f2\"\n }\n assert user == {\"name\": B.AnyStr(min_len=1, max_len=63),\n \"id\": B.AnyUUID()}\n\n```\n\n* If you are looking for web framework input validation, I suggest use [FastAPI](https://fastapi.tiangolo.com/). It properly integrate with openapi as well.\n\n## Installation\n```\npip install believe\n```\n\n## Basic usage\n```\nimport believe as B\nimport time\n\n# Match any string\nassert B.AnyStr() == \"any_str\"\n\n# Match string length >= 1 and <= 10\nassert B.AnyStr(min_len=1, max_len=10) == \"a\"\n\n# Match any string that can be converted to int\nassert B.AnyIntStr() == \"123\"\n\n# Match any UUID format string\nassert B.AnyUUID() == \"732c0743-2638-47d5-902d-0daa3080348b\"\n\n# Match any sha1 string\nassert B.AnySHA1() == \"b130c4b97d0640eaf3f45f7360a5b4dbbf561f58\"\n\n# Match any IPv4 string\nassert B.AnyIPV4() == \"1.2.3.4\"\n\n# Match integer that is >=1 and <= 10\nassert B.AnyInt(min_value=1, max_value=10) == 5\n\n# Match any float that is >= 1.0 and <= 10.0\nassert B.AnyFloat(min_value=1.0, max_value=10.0) == 5.0 # 1.0 <= X <= 10.0\n\n# Match if values is \"one\" or \"two\"\nassert B.OneOf(\"one\", \"two\") == \"one\"\n\n# Sometimes we don't care about the order, we can use AnyOrder\nassert B.AnyOrder([1, 2, 3]) == [2, 1, 3]\n\n# Sometimes we assign value as timestamp but test cases takes more than 1 sec\n# We can use almost to accept a range of values\nassert B.Almost(time.time(), ts_range=3) == time.time() # Allow 3 sec gap\n\n# If we allow None or any string\nassert B.Nullable(B.AnyStr()) == None\nassert B.Nullable(B.AnyStr()) == \"123\"\n\n# Only check type\nassert B.Any(bytes) == b'123'\n\n# Reverse check result, anything but \"A\" or \"B\"\nassert B.Not(B.OneOf(\"A\", \"B\")) == \"C\"\n\n# Match list\nassert B.ListOf(B.AnyStr()) == [\"A\", \"B\", \"C\"]\nassert B.ListOf(B.AnyStr(), n_item=3) == [\"A\", \"B\", \"C\"] # exact 3 items\nassert B.ListOf(B.AnyStr(), min_item=1) == [\"A\", \"B\", \"C\"] # >= 1 items\nassert B.ListOf(B.AnyStr(), max_item=5) == [\"A\", \"B\", \"C\"] # <= 5 items\n```\n\n## Advance Usage\n```\n# If we don't want to use json.load('{\"foo\": \"bar\"}') == {\"foo\": \"bar\"}, we can use the following way\nassert B.AnyJsonStr({\"foo\": \"bar\"}) == '{\"foo\": \"bar\"}'\n\n# We can use AnyUrl to compare the normalized url\n# 1. We can compare one with default port and one without, they are identical\nassert B.AnyUrl(\"https://foo.com/\") == \"https://foo.com:443/\"\nassert B.AnyUrl(\"http://foo.com/\") == \"http://foo.com:80/\"\n# 2. We can ignore the order in query string\nassert B.AnyUrl(\"https://foo.com/bar?p1=1&p2=2\") == \"https://foo.com/bar?p2=2&p1=1\"\n\n# We can use Dict to compare a dict with Optional field\nassert B.Dict({\"name\": B.AnyStr(), \"value\": B.Optional(B.AnyStr())}) == {\"name\": \"abc\"}\nassert B.Dict({\"name\": B.AnyStr(), \"value\": B.Optional(B.AnyStr())}) == {\"name\": \"abc\", \"value\": \"def\"}\n\n# If key is a dynamic value, we can use DictOf(<key_matcher>, <value_matcher>)\n# i.e. We want to match a dict with random uuid as key\nassert B.DictOf(B.AnyUUID(), B.OneOf(\"ok\", \"fail\")) == {\"732c0743-2638-47d5-902d-0daa3080348b\": \"ok\",\n \"5cfd50ba-c3d3-4fb7-b2fe-e9a6e039ad29\": \"fail\"}\n```\n\n## Use Validate Function\n```\n# validate with error exception\nimport believe as B\nvalidator = B.Dict({\"name\": B.AnyInt()})\n\nB.validate(validator, {\"name\": \"ken\"}) # believe.error.ValidateError: [e_path=$.name] 'ken' != AnyInt()\n```\n\n## A Complex Example\n```\nimport believe as B\nimport time\n\nresult_json = {\"name\": \"john\",\n \"age\": 32,\n \"download_link\": \"https://download.server.com/?name=john&id=abc\",\n \"role\": \"admin\",\n \"address\": \"10.1.2.3\",\n \"updated_at\": int(time.time()),\n \"tags\": [\"admin\", \"john\"]}\n\nexp_result = B.Dict({\"name\": B.AnyStr(min_len=1, max_len=64),\n \"age\": B.AnyInt(min_value=0, max_value=200),\n \"download_link\": B.AnyUrl(\"https://download.server.com/?id=abc&name=john\"),\n \"role\": B.OneOf(\"admin\", \"user\"),\n \"address\": B.AnyIPV4(),\n \"updated_at\": B.Almost(int(time.time())),\n \"tags\": B.ListOf(B.AnyStr()),\n \"extra\": B.Optional(B.Nullable(B.AnyStr()))})\nB.validate(exp_result, result_json)\n```\n",
"bugtrack_url": null,
"license": null,
"summary": "A easy to use validator for json content",
"version": "1.0.14",
"project_urls": {
"Home": "https://github.com/pkyosx/believe"
},
"split_keywords": [
"json",
" validate",
" validator"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "294b00761ac39a991de16505db9f3962174926a44ecb66d479cbd7af8a8541a6",
"md5": "4dcf0db25038a136370dd42ddccf72c3",
"sha256": "60e8a13f3b0303c501d8f1f787fdb976e88db27c116c8ee614f05e526823f061"
},
"downloads": -1,
"filename": "believe-1.0.14-py3-none-any.whl",
"has_sig": false,
"md5_digest": "4dcf0db25038a136370dd42ddccf72c3",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.6",
"size": 9663,
"upload_time": "2024-04-08T07:29:03",
"upload_time_iso_8601": "2024-04-08T07:29:03.562504Z",
"url": "https://files.pythonhosted.org/packages/29/4b/00761ac39a991de16505db9f3962174926a44ecb66d479cbd7af8a8541a6/believe-1.0.14-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "e96291a319ec8effe6568c94104540f32955246cff24dfefb3074103a27c97a0",
"md5": "97a4d10abe7a56620d3369cc711f16cd",
"sha256": "ce3efe52109e330a118f1047e17a13d0a34061538a9c096a725087c5124a5efc"
},
"downloads": -1,
"filename": "believe-1.0.14.tar.gz",
"has_sig": false,
"md5_digest": "97a4d10abe7a56620d3369cc711f16cd",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.6",
"size": 13305,
"upload_time": "2024-04-08T07:29:05",
"upload_time_iso_8601": "2024-04-08T07:29:05.565978Z",
"url": "https://files.pythonhosted.org/packages/e9/62/91a319ec8effe6568c94104540f32955246cff24dfefb3074103a27c97a0/believe-1.0.14.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-04-08 07:29:05",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "pkyosx",
"github_project": "believe",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"lcname": "believe"
}