{"id":15711153,"url":"https://github.com/junpuf/serial-j","last_synced_at":"2026-05-19T19:32:19.742Z","repository":{"id":57465805,"uuid":"194308403","full_name":"junpuf/serial-j","owner":"junpuf","description":"Validating and Serializing JSON data into Python object with minimal effort.","archived":false,"fork":false,"pushed_at":"2020-10-31T21:31:18.000Z","size":1341,"stargazers_count":1,"open_issues_count":3,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-09-22T23:23:58.967Z","etag":null,"topics":["json","python","serializer"],"latest_commit_sha":null,"homepage":"https://pypi.org/project/serial-j/","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/junpuf.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-06-28T17:08:30.000Z","updated_at":"2020-10-31T21:32:33.000Z","dependencies_parsed_at":"2022-09-17T18:01:24.973Z","dependency_job_id":null,"html_url":"https://github.com/junpuf/serial-j","commit_stats":null,"previous_names":["junpufan/serial-j"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/junpuf/serial-j","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/junpuf%2Fserial-j","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/junpuf%2Fserial-j/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/junpuf%2Fserial-j/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/junpuf%2Fserial-j/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/junpuf","download_url":"https://codeload.github.com/junpuf/serial-j/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/junpuf%2Fserial-j/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33229365,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-19T15:49:41.270Z","status":"ssl_error","status_checked_at":"2026-05-19T15:49:22.917Z","response_time":58,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["json","python","serializer"],"created_at":"2024-10-03T21:11:57.088Z","updated_at":"2026-05-19T19:32:18.508Z","avatar_url":"https://github.com/junpuf.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![https://github.com/JunpuFan/serial-j](https://github.com/junpuf/serial-j/blob/master/static/logo.png)](https://github.com/JunpuFan/serial-j)\n\n\u003cp align=\"center\"\u003e\n  \u003cimg width=\"620\" height=\"422\" src=\"https://github.com/junpuf/serial-j/blob/master/static/demo1.gif\"\u003e\n\u003c/p\u003e\n\n## Features \n   1. Serialize JSON / Python Dictionary data into Python object based on a compact data `schema`.\n       1. Data `schema` is a python list `[]` of many `{}`.\n       2. Each `{}` in the `schema` defines a property in your `JSON` data. \n       3. The easiest form of a property definition is `{'name':'my_property'}` which means:\n          1. Your `JSON` data **MUST** contain a property called `my_property` .\n          2. Its value **MUST** be a **non-empty** value. \n          3. Non-empty means that the value of  `my_property` can not be `None`, `\"\"`, `()`, `[]`, or `{}`.\n       4. Additional options are available to give you more control over your data definition. Those options are: `nullable`, `optional`, `is_compound`, `compound_serializer`, `compound_schema` and `type`.\n          1. Option `nullable: True` means the value of `my_property` can be `None`.\n          2. Option `optional: True` means `my_property` may or may not exist in your `JSON` data.\n             1. In case `my_property` exist, verify all applicable options.\n             2. In case `my_property` doesn't exist, we ignore `my_property`.\n          3. Option `is_compound: True` means `my_property` is a nested `JSON` object or an Array of `JSON` objects.\n             1. When `is_compound: True`, you must provide either `compound_serializer` or `compound_schema` so we can property serialize this nested data structure.\n                1. `compound_serializer` is a `SerialJ` serializer class.\n                2. `compound_schema` has the same structure as the data `schema`.\n          4. Option `type` gives you the power to validate the value of each property in your `JSON` data. Currently supported type definitions are:\n             1. `'type': (bool,)` a boolean value.\n             2. `'type': (float,)` a floating point number.\n             3. `'type': (int,)` an integer.\n             4. `'type': (int, (1, 64, 343))` an enumeration of integers, this means that the value of a `JSON` property should be in `(1, 64, 343)`.\n             5. `'type': (int, range(1, 10, 3)`, a range of integers, this means that the value of a `JSON` property should be in `range(1, 10, 3)`.\n             6. `'type': (int, lambda x: x % 2 == 0)` a user defined `lambda` expression used to filter desired integer values, the above example `lambda`  specifies the value of the `JSON` property should be a `even` number.\n             7. `'type': (str,)` a string value.\n             8. `'type': (str, ('SUCCESS', 'FAILURE'))` an enumeration of strings, this means that the value of a `JSON` property should be in `('SUCCESS', 'FAILURE')`. Note that `('SUCCESS', 'FAILURE')` is just an example here, you can define anything you like.\n             9. `'type': (str, 'email')` an email address.\n             10. `'type': (str, 'url')` a web url.\n             11. `'type': (str, 'ipv4')` an IPv4 address.\n             12. `'type': (str, 'ipv6')` an IPv6 address.\n             13. `'type': (str, 'uuid')` an UUID string.\n             14. `'type': (str, '[^@]+@[^@]+\\.[^@]+')` a user defined `regex`. \n   2. Automatically validate every JSON properties defined in the `schema` based on varies additional options specified in `schema`.\n   3. You are given convenient built-in methods that you can use to convert your data back to JSON encoded string or JSON / Python Dictionary.\n   4. You have the flexibility of defining additional methods in your serializer class that utilize your data in anyway you want.\n\n\n\n## Example Codes\n\n| Name                                                  | Code                                                         |\n| ----------------------------------------------------- | ------------------------------------------------------------ |\n| Basic Example                                         | [basic_ex.py](https://github.com/JunpuFan/serial-j/blob/master/examples/basic_ex.py) |\n| Serialize Nested Json Data with `compound_schema`     | [nested_ex2.py](https://github.com/JunpuFan/serial-j/blob/master/examples/nested_ex2.py) |\n| Serialize Nested Json Data with `compound_serializer` | [nested_ex1.py](https://github.com/JunpuFan/serial-j/blob/master/examples/nested_ex1.py) |\n| Data Type Validation: all in one example              | [typed_ex.py](https://github.com/JunpuFan/serial-j/blob/master/examples/typed_ex.py) |\n| Data Type Validation: `bool`                          | [bool_data.py](https://github.com/JunpuFan/serial-j/blob/master/examples/type/bool_data.py) |\n| Data Type Validation: `float`                         | [float_data.py](https://github.com/JunpuFan/serial-j/blob/master/examples/type/float_data.py) |\n| Data Type Validation: `int`                           | [int_data.py](https://github.com/JunpuFan/serial-j/blob/master/examples/type/int_data.py) |\n| Data Type Validation: `int enum`                      | [int_enum_data.py](https://github.com/JunpuFan/serial-j/blob/master/examples/type/int_enum_data.py) |\n| Data Type Validation: `int range`                     | [int_ranged_data.py](https://github.com/JunpuFan/serial-j/blob/master/examples/type/int_ranged_data.py) |\n| Data Type Validation: `int lambda`                    | [int_lambda_data.py](https://github.com/JunpuFan/serial-j/blob/master/examples/type/int_lambda_data.py) |\n| Data Type Validation: `str`                           | [str_data.py](https://github.com/JunpuFan/serial-j/blob/master/examples/type/str_data.py) |\n| Data Type Validation: `str enum`                      | [str_enum_data.py](https://github.com/JunpuFan/serial-j/blob/master/examples/type/str_enum_data.py) |\n| Data Type Validation: `str email`                     | [str_email_data.py](https://github.com/JunpuFan/serial-j/blob/master/examples/type/str_email_data.py) |\n| Data Type Validation: `str url`                       | [str_url_data.py](https://github.com/JunpuFan/serial-j/blob/master/examples/type/str_url_data.py) |\n| Data Type Validation: `str uuid`                      | [str_uuid_data.py](https://github.com/JunpuFan/serial-j/blob/master/examples/type/str_uuid_data.py) |\n| Data Type Validation: `str ipv4`                      | [str_ipv4_data.py](https://github.com/JunpuFan/serial-j/blob/master/examples/type/str_ipv4_data.py) |\n| Data Type Validation: `str ipv6`                      | [str_ipv6_data.py](https://github.com/JunpuFan/serial-j/blob/master/examples/type/str_ipv6_data.py) |\n| Data Type Validation: `str regex`                     | [str_regex_data.py](https://github.com/JunpuFan/serial-j/blob/master/examples/type/str_regex_data.py) |\n\n\n\n## Basic Example\nLet's first see a basic example. \n\n```python\nfrom serial_j import SerialJ\n\nclass FruitBucket(SerialJ):\n    # define how our data should look like using `schema`.\n    schema = [\n        {'name': 'apple'},\n        {'name': 'orange'},\n        {'name': 'pineapple'},\n    ]\n\n# test data for FruitBucket \ntest1 = dict(\n    apple=\"good apple\",\n    orange=\"very good orange\",\n    pineapple=\"nice pineapple\",\n)\n\n# serialize `test1` into `FruitBucket` object\nfruits = FruitBucket(test1)\n\n# `fruits` is a proper python object , which means that you can use \n# `fruits.apple` syntax to retrieve the value of `apple`.\nprint(fruits.apple)\n\u003e\u003e\u003e good apple\n\n# ...and other fruits too.\nprint(fruits.orange)\n\u003e\u003e\u003e very good orange\nprint(fruits.pineapple)\n\u003e\u003e\u003e nice pineapple\n\n# you can get the JSON formatted string back too.\nprint(fruits)\n\u003e\u003e\u003e {\"apple\": \"good apple\", \"orange\": \"very good orange\", \"pineapple\": \"nice pineapple\"}\n\n# interested to get the python dictionary back?\nfruits_data = fruits.as_dict()\nprint(fruits_data)\n\u003e\u003e\u003e {'apple': 'good apple', 'orange': 'very good orange', 'pineapple': 'nice pineapple'}\n```\n\n\n\n## Nested JSON Data \n\nLet's see how we can serialize more complex data structure into python object.\n\n\n\n##### Serializing Nested JSON Data with `compound_schema`.\n\nDefine a nested data `schema` called `compound_schema` to serialize nested `JSON` data.\n\n```python\nfrom serial_j import SerialJ\n\nclass SnackBucket(SerialJ):\n    schema = [\n        {'name': 'apple'},\n        {'name': 'orange'},\n        {'name': 'pineapple'},\n        {'name': 'snack', 'is_compound': True,\n            'compound_schema': [\n                 {'name': 'cheese', 'optional': True},\n                 {'name': 'chocolate'},\n                 {'name': 'chips', 'nullable': True},\n            ],\n        },\n    ]\n\ntest3 = dict(\n    apple=\"good apple\",\n    orange=\"very good orange\",\n    pineapple=\"nice pineapple\",\n    snack=[\n        dict(\n            cheese=\"Feta\",\n            chocolate=\"Ferrero Rocher\",\n            chips=[] \n        ),\n        dict(\n            chocolate=\"Swiss milk chocolate\",\n            chips=[\"Cheetos\", \"Lays Classic Potato Chips\", \"Cool Ranch Doritos\"] \n        ),\n    ]\n)\nmysnacks = SnackBucket(test3)\nprint(mysnacks)\n\u003e\u003e\u003e {\"apple\": \"good apple\", \"orange\": \"very good orange\", \"pineapple\": \"nice pineapple\", \n\u003e\u003e\u003e \"snack\": [{\"cheese\": \"Feta\", \"chocolate\": \"Ferrero Rocher\", \"chips\": []}, \n\u003e\u003e\u003e           {\"chocolate\": \"Swiss milk chocolate\", \"chips\": \n\u003e\u003e\u003e                [\"Cheetos\", \"Lays Classic Potato Chips\", \"Cool Ranch Doritos\"]}]}\n```\n\n\n\n##### Serializing Nested JSON Data with `compound_serializer`.\n\nDefine a separete data `SerialJ` serializer called `compound_serializer` to serialize nested `JSON` data.\n\n```python\nfrom serial_j import SerialJ\nclass Snack(SerialJ):\n    schema = [\n        # cheese is nice but is optional.\n        {'name': 'cheese', 'optional': True},\n        # chocolate is a MUST have.\n        {'name': 'chocolate'},\n        # chips is a must but we have to decide which kind later, \n        # so its value can be None, False, \"\", {}, [].\n        {'name': 'chips', 'nullable': True},\n    ]\n    \nclass NestedBucket(SerialJ):\n    schema = [\n        {'name': 'apple'},\n        {'name': 'orange'},\n        {'name': 'pineapple'},\n        {'name': 'snack', 'is_compound': True, 'compound_serializer': Snack}\n    ]\n    \n# test data for NestedBucket\ntest2 = dict(\n    apple=\"good apple\",\n    orange=\"very good orange\",\n    pineapple=\"nice pineapple\",\n    snack=dict(\n        chocolate=\"Ferrero Rocher\",\n        chips=[] # yeah its a list of chips!\n    ),\n)\nmy_snacks = NestedBucket(test2)\nprint(my_snacks)\n\u003e\u003e\u003e {\"apple\": \"good apple\", \"orange\": \"very good orange\", \"pineapple\": \"nice pineapple\", \n\u003e\u003e\u003e  \"snack\": {\"chocolate\": \"Ferrero Rocher\", \"chips\": []}}\n```\n\n\n\n## Data Type Validation \n\na compact example that shows all data types currently suppoted by this package.\n\n```python\nfrom serial_j import SerialJ\n\n\nclass TypedData(SerialJ):\n    schema = [\n        {'name': 'prop1', 'type': (int,)},\n        {'name': 'prop2', 'type': (int, (1, 64, 343))},\n        {'name': 'prop3', 'type': (int, range(1, 10, 3))},\n        {'name': 'prop4', 'type': (int, lambda x: x % 2 == 0)},\n        {'name': 'prop5', 'type': (str,)},\n        {'name': 'prop6', 'type': (str, ('SUCCESS', 'FAILURE'))},\n        {'name': 'prop7', 'type': (str, 'email')},\n        {'name': 'prop8', 'type': (str, 'url')},\n        {'name': 'prop9', 'type': (str, 'ipv4')},\n        {'name': 'prop10', 'type': (str, 'ipv6')},\n        {'name': 'prop11', 'type': (str, 'uuid')},\n        {'name': 'prop12', 'type': (str, '[^@]+@[^@]+\\.[^@]+')},\n        {'name': 'prop13', 'type': (float,)},\n        {'name': 'prop14', 'type': (bool,)},\n    ]\n\n\ntest1 = {\n    'prop1': 1,\n    'prop2': 64,\n    'prop3': 4,\n    'prop4': 2,\n    'prop5': \"str\",\n    'prop6': 'SUCCESS',\n    'prop7': 'anyone@emailservice.com',\n    'prop8': 'https://www.something.com/something-something/something/12345',\n    'prop9': '172.16.255.1',\n    'prop10': '2001:0db8:0a0b:12f0:0000:0000:0000:0001',\n    'prop11': 'c026dd66-86f2-498e-8c2c-858179c0c93d',\n    'prop12': 'junpufan@me.com',\n    'prop13': 0.1,\n    'prop14': True\n}\n\ndata1 = TypedData(test1)\nprint(data1)\n# \u003e\u003e\u003e {\"prop1\": 1, \"prop2\": 64, \"prop3\": 4, \"prop4\": 2, \"prop5\": \"str\",\n# \u003e\u003e\u003e \"prop6\": \"SUCCESS\", \"prop7\": \"anyone@emailservice.com\",\n# \u003e\u003e\u003e \"prop8\": \"https://www.something.com/something-something/something/12345\",\n# \u003e\u003e\u003e \"prop9\": \"172.16.255.1\", \"prop10\": \"2001:0db8:0a0b:12f0:0000:0000:0000:0001\",\n# \u003e\u003e\u003e \"prop11\": \"c026dd66-86f2-498e-8c2c-858179c0c93d\", \"prop12\": \"junpufan@me.com\",\n# \u003e\u003e\u003e \"prop13\": 0.1, \"prop14\": true}\n\n```\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjunpuf%2Fserial-j","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjunpuf%2Fserial-j","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjunpuf%2Fserial-j/lists"}