believe


Namebelieve JSON
Version 1.0.14 PyPI version JSON
download
home_pageNone
SummaryA easy to use validator for json content
upload_time2024-04-08 07:29:05
maintainerNone
docs_urlNone
authorNone
requires_python>=3.6
licenseNone
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"
}
        
Elapsed time: 1.04603s