{"id":13501601,"url":"https://github.com/HackSoftware/simple_schema_validator","last_synced_at":"2025-03-29T09:30:54.827Z","repository":{"id":57467665,"uuid":"169376057","full_name":"HackSoftware/simple_schema_validator","owner":"HackSoftware","description":"A dead-simple utility that validates if object has a certain structure. Used in some of our projects.","archived":false,"fork":false,"pushed_at":"2020-07-07T20:10:26.000Z","size":82,"stargazers_count":26,"open_issues_count":0,"forks_count":1,"subscribers_count":8,"default_branch":"master","last_synced_at":"2025-03-22T14:08:13.741Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","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/HackSoftware.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-02-06T08:38:28.000Z","updated_at":"2025-03-12T07:48:45.000Z","dependencies_parsed_at":"2022-09-19T09:01:22.628Z","dependency_job_id":null,"html_url":"https://github.com/HackSoftware/simple_schema_validator","commit_stats":null,"previous_names":[],"tags_count":9,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/HackSoftware%2Fsimple_schema_validator","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/HackSoftware%2Fsimple_schema_validator/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/HackSoftware%2Fsimple_schema_validator/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/HackSoftware%2Fsimple_schema_validator/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/HackSoftware","download_url":"https://codeload.github.com/HackSoftware/simple_schema_validator/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246167036,"owners_count":20734377,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":[],"created_at":"2024-07-31T22:01:43.182Z","updated_at":"2025-03-29T09:30:54.545Z","avatar_url":"https://github.com/HackSoftware.png","language":"Python","funding_links":[],"categories":["Python"],"sub_categories":[],"readme":"# Simple schema validator\n\n![coverage](https://img.shields.io/badge/coverage-99%25-brightgreen)\n\n- [Simple schema validator](#simple-schema-validator)\n    - [Basic usage](#basic-usage)\n    - [Type checking](#type-checking)\n        - [Optional types](#optional-types)\n\n\nA dead-simple utility that validates if object has a certain structure. Used in some of our projects.\n\n## Basic usage\n\n```\npip install simple_schema_validator\n```\n\nAn example:\n\nLets say we have an API that returns the following data:\n\n```json\n{\n  \"user\": 1,\n  \"profile\": {\n    \"email\": \"some@user.com\",\n    \"name\": \"Some User\",\n    \"age\": 20\n  },\n  \"tokens\": {\n    \"jwt\": \"...\",\n    \"refresh\": \"...\",\n    \"firebase\": \"...\",\n  }\n}\n```\n\nAnd we are writing a simple integration test, that wants to assure the response has a certain structure.\n\nThen we can use the schema validator like so:\n\n```python\nfrom simple_schema_validator import schema_validator\n\ndata = get_data_from_api()\n\nschema = {\n  'user': Any,\n  'profile': {\n    'email': Any,\n    'name': Any,\n    'age': Any\n  },\n  'tokens': {\n    'jwt': Any,\n    'refresh': Any,\n    'firebase': Any\n  }\n}\n\nvalidation = schema_validator(schema, data)\n\nif not validation:\n    print(f'Keys in data, but not in schema: {validation.additional_keys}')\n    print(f'Keys in schema, but not in data: {validation.missing_keys}')\n    print(f'Keys with different type from schema {validation.type_errors}')\n```\n\n* `missing_keys` are those keys that are required in the `schema`, but not found in `data`.\n* `additional_keys` are those keys present in `data`, but not required by the `schema`.\n* `validation_errors` are those keys, that are having a different type in `data`, from the defined in `schema`.\n\n**Nested keys are represented with \"dot\" notation - `profile.email`, `tokens.jwt`, etc.**\n\n## Type checking\n\nThe util supports simple schema type checking.\n\nCurrently, the supported types in the schema are:\n\n* `int`\n* `float`\n* `str`\n* `bool`\n* `typing.Any` (from Python `typing` library)\n* `simple_schema_validator.types.Optional` (custom type, define in the package)\n\nIf the type is `Any`, no type checking is done.\n\nIf there's a type mismatch, the errors are placed in the `type_errors` attribute of the result, which is a list of type errors.\n\nThe general format of a single type error is:\n\n```python\n{\n  'path': 'the.path.to.the.value.in.data',\n  'expected': the_expected_type_as_defined_in_the_schema,\n  'actual': the_actual_type_of_the_value\n}\n```\n\nHere's an example:\n\n\n```python\nfrom simple_schema_validator import schema_validator, types\n\n\nschema = {\n  'user': str,\n  'profile': {\n    'email': str,\n    'name': str,\n    'age': int\n  },\n  'tokens': {\n    'jwt': str,\n    'refresh': str,\n    'firebase': str\n  }\n}\n\ndata = {\n  'user': 'Some User',\n  'profile': {\n    'email': 'someuser@hacksoft.io',\n    'name': 'Some User',\n    'age': \"29\"\n  },\n  'tokens': {\n    'jwt': 'some token value',\n    'refresh': 'some token value',\n    'firebase': 'some token value'\n  }\n\n}\n\nresult = schema_validator(schema, data)\n\n\nassert bool(result) is False\nassert result.type_errors == [{'path': 'profile.age', 'expected': int, 'actual': str}]\n```\n\n### Optional types\n\nThe schema validator support optional types.\n\nYou can do the following:\n\n```python\nfrom simple_schema_validator import schema_validator, types\n\nschema = {\n  'a': types.Optional[int]\n}\n\ndata_1 = {\n  'a': None\n}\n\ndata_2 = {\n  'a': 1\n}\n\ndata_3 = {\n  'a': 'some_string'\n}\n\nassert bool(schema_validator(schema, data_1)) is True\nassert bool(schema_validator(schema, data_2)) is True\nassert bool(schema_validator(schema, data_3)) is False\n```\n\nAdditionally, you can define optional branches in the schema:\n\n```python\nfrom simple_schema_validator import schema_validator, types\n\nschema = {\n  'a': types.Optional[{\n    'b': int\n  }]\n}\n\ndata_1 = {\n  'a': None\n}\n\ndata_2 = {\n  'a': 1\n}\n\ndata_3 = {\n  'a': {\n    'b': 1\n  }\n}\n\ndata_4 = {\n  'a': {\n    'b': 'some_string'\n  }\n}\n\nassert bool(schema_validator(schema, data_1)) is True\nassert bool(schema_validator(schema, data_2)) is False\nassert bool(schema_validator(schema, data_3)) is True\nassert bool(schema_validator(schema, data_4)) is False\n```\n\nYou can use it with optional lists aswell:\n\n```python\nfrom simple_schema_validator import schema_validator, types\n\nschema = {\n  'a': types.Optional[[int]]\n}\n\ndata_1 = {\n  'a': None\n}\n\ndata_2 = {\n  'a': 1\n}\n\ndata_3 = {\n  'a': [1, 2, 3]\n}\n\ndata_4 = {\n  'a': ['some_string']\n}\n\nassert bool(schema_validator(schema, data_1)) is True\nassert bool(schema_validator(schema, data_2)) is False\nassert bool(schema_validator(schema, data_3)) is True\nassert bool(schema_validator(schema, data_4)) is False\n```\n\n### List types\n\nThe schema validator support list types.\n\nYou can do the following:\n\n```python\nfrom simple_schema_validator import schema_validator, types\n\nschema = {\n  'a': types.List[int]\n}\n\ndata_1 = {\n  'a': [1, 2, 3]\n}\n\ndata_3 = {\n  'a': ['some_string']\n}\n\nassert bool(schema_validator(schema, data_1)) is True\nassert bool(schema_validator(schema, data_2)) is False\n```\n\n### Recursive schemas\n\nThe schema validator support type checking for schemas in list.\n\nYou can do the following:\n\n```python\nfrom simple_schema_validator import schema_validator, types\n\nschema = {\n  'a': [{'b': int}]\n}\n\ndata_1 = {\n  'a': [{'b': 1}]\n}\n\ndata_2 = {\n  'a': [{'b': 'some_string'}]\n}\n\nassert bool(schema_validator(schema, data_1)) is True\nassert bool(schema_validator(schema, data_2)) is False\n```\n\n```python\nfrom simple_schema_validator import schema_validator, types\n\nschema = {\n  'a': [{'b': [int]}]\n}\n\ndata_1 = {\n  'a': [{'b': [1]}]\n}\n\ndata_2 = {\n  'a': [{'b': [1, 2, 3]}]\n}\n\ndata_3 = {\n  'a': [{'b': ['some_string']}]\n}\n\ndata_4 = {\n  'a': [{'b': [1, 'some_string']}]\n}\n\ndata_5 = {\n  'a': [{'b': ['some_string', 'other_string']}]\n}\n\ndata_6 = {\n  'a': [{'b': ['some_string', 1]}]\n}\n\nassert bool(schema_validator(schema, data_1)) is True\nassert bool(schema_validator(schema, data_2)) is True\nassert bool(schema_validator(schema, data_3)) is False\nassert bool(schema_validator(schema, data_4)) is False\nassert bool(schema_validator(schema, data_5)) is False\nassert bool(schema_validator(schema, data_6)) is False\n```\n\nYou can do the same with optional branches aswell:\n\n```python\nfrom simple_schema_validator import schema_validator, types\n\nschema = {\n  'a': [{'b': types.Optional[int]}]\n}\n\ndata_1 = {\n  'a': [{\n    'b': {\n      'c': 1,\n      'd': 2\n    }\n  }]\n}\n\ndata_2 = {\n  'a': [{'b': 'some_string'}]\n}\n\nassert bool(schema_validator(schema, data_1)) is True\nassert bool(schema_validator(schema, data_2)) is False\n```\n\n## Examples\n\nFor examples, check the [examples](examples/) folder or the [tests](tests/) for the project.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FHackSoftware%2Fsimple_schema_validator","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FHackSoftware%2Fsimple_schema_validator","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FHackSoftware%2Fsimple_schema_validator/lists"}