{ "info": { "author": "Derrick Gilland", "author_email": "dgilland@gmail.com", "bugtrack_url": null, "classifiers": [ "Development Status :: 3 - Alpha", "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Operating System :: OS Independent", "Programming Language :: Python", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.4", "Programming Language :: Python :: 3.5", "Programming Language :: Python :: 3.6", "Topic :: Software Development :: Libraries", "Topic :: Software Development :: Libraries :: Python Modules" ], "description": "schemable\n*********\n\n|version| |travis| |coveralls| |license|\n\n\nSchemable is a schema parsing and validation library that let's you define schemas simply using dictionaries, lists, types, and callables.\n\n\nLinks\n=====\n\n- Project: https://github.com/dgilland/schemable\n- Documentation: https://schemable.readthedocs.io\n- PyPI: https://pypi.python.org/pypi/schemable/\n- TravisCI: https://travis-ci.org/dgilland/schemable\n\n\nFeatures\n========\n\n- Simple schema definitions using ``dict``, ``list``, and ``type`` objects\n- Complex schema definitions using ``Any``, ``All``, ``As``, and predicates\n- Detailed validation error messages\n- Partial data loading on validation failure\n- Strict and non-strict parsing modes\n- Python 3.4+\n\n\nQuickstart\n==========\n\nInstall using pip:\n\n\n::\n\n pip install schemable\n\n\nDefine a schema using ``dict`` and ``list`` objects:\n\n.. code-block:: python\n\n from schemable import Schema, All, Any, As, Optional, SchemaError\n\n user_schema = Schema({\n 'name': str,\n 'email': All(str, lambda email: len(email) > 3 and '@' in email),\n 'active': bool,\n 'settings': {\n Optional('theme'): str,\n Optional('language', default='en'): str,\n Optional('volume'): int,\n str: str\n },\n 'aliases': [str],\n 'phone': All(str,\n As(lambda phone: ''.join(filter(str.isdigit, phone))),\n lambda phone: 10 <= len(phone) <= 15),\n 'addresses': [{\n 'street_addr1': str,\n Optional('street_addr2', default=None): Any(str, None),\n 'city': str,\n 'state': str,\n 'country': str,\n 'zip_code': str\n }]\n })\n\n\nThen validate and load by passing data to ``user_schema()``:\n\n\n.. code-block:: python\n\n # Fail!\n result = user_schema({\n 'name': 'Bob Smith',\n 'email': 'bob.example.com',\n 'active': 1,\n 'settings': {\n 'theme': False,\n 'extra_setting1': 'val1',\n 'extra_setting2': True\n },\n 'phone': 1234567890,\n 'addresses': [\n {'street_addr1': '123 Lane',\n 'city': 'City',\n 'state': 'ST',\n 'country': 'US',\n 'zip_code': 11000}\n ]\n })\n\n print(result)\n # SchemaResult(\n # data={'name': 'Bob Smith',\n # 'settings': {'extra_setting1': 'val1',\n # 'language': 'en'}\n # 'addresses': [{'street_addr1': '123 Lane',\n # 'city': 'City',\n # 'state': 'ST',\n # 'country': 'US',\n # 'street_addr2': None}]},\n # errors={'email': \"bad value: ('bob.example.com') should evaluate to True\",\n # 'active': 'bad value: type error, expected bool but found int',\n # 'settings': {'theme': 'bad value: type error, expected str but found bool',\n # 'extra_setting2': 'bad value: type error, expected str but found bool'},\n # 'phone': 'bad value: type error, expected str but found int',\n # 'addresses': {0: {'zip_code': 'bad value: type error, expected str but found int'}},\n # 'aliases': 'missing required key'})\n\n # Fail!\n result = user_schema({\n 'name': 'Bob Smith',\n 'email': 'bob@example.com',\n 'active': True,\n 'settings': {\n 'theme': False,\n 'extra_setting1': 'val1',\n 'extra_setting2': 'val2'\n },\n 'phone': '123-456-789',\n 'addresses': [\n {'street_addr1': '123 Lane',\n 'city': 'City',\n 'state': 'ST',\n 'country': 'US',\n 'zip_code': '11000'}\n ]\n })\n\n print(result)\n # SchemaResult(\n # data={'name': 'Bob Smith',\n # 'email': 'bob@example.com',\n # 'active': True,\n # 'settings': {'extra_setting1': 'val1',\n # 'extra_setting2': 'val2',\n # 'language': 'en'},\n # 'addresses': [{'street_addr1': '123 Lane',\n # 'city': 'City',\n # 'state': 'ST',\n # 'country': 'US',\n # 'zip_code': '11000',\n # 'street_addr2': None}]},\n # errors={'settings': {'theme': 'bad value: type error, expected str but found bool'},\n # 'phone': \"bad value: ('123456789') should evaluate to True\",\n # 'aliases': 'missing required key'})\n\n\nOr can raise an exception on validation failure instead of returning results:\n\n\n.. code-block:: python\n\n # Fail strictly!\n try:\n user_schema({\n 'name': 'Bob Smith',\n 'email': 'bob@example.com',\n 'active': True,\n 'settings': {\n 'theme': False,\n 'extra_setting1': 'val1',\n 'extra_setting2': 'val2'\n },\n 'phone': '123-456-789',\n 'addresses': [\n {'street_addr1': '123 Lane',\n 'city': 'City',\n 'state': 'ST',\n 'country': 'US',\n 'zip_code': '11000'}\n ]\n }, strict=True)\n except SchemaError as exc:\n print(exc)\n # Schema validation failed: \\ \n # {'settings': {'theme': 'bad value: type error, expected str but found bool'}, \\ \n # 'phone': \"bad value: ('123456789') should evaluate to True\", \\\n # 'aliases': 'missing required key'}\n\n\nAccess the parsed data after successful validation:\n\n.. code-block:: python\n\n # Pass!\n result = user_schema({\n 'name': 'Bob Smith',\n 'email': 'bob@example.com',\n 'active': True,\n 'settings': {\n 'theme': 'dark',\n 'extra_setting1': 'val1',\n 'extra_setting2': 'val2'\n },\n 'phone': '123-456-7890',\n 'aliases': [],\n 'addresses': [\n {'street_addr1': '123 Lane',\n 'city': 'City',\n 'state': 'ST',\n 'country': 'US',\n 'zip_code': '11000'}\n ]\n })\n\n print(result)\n # SchemaResult(\n # data={'name': 'Bob Smith',\n # 'email': 'bob@example.com',\n # 'active': True,\n # 'settings': {'theme': 'dark',\n # 'extra_setting1': 'val1',\n # 'extra_setting2': 'val2',\n # 'language': 'en'},\n # 'phone': '1234567890',\n # 'aliases': [],\n # 'addresses': [{'street_addr1': '123 Lane',\n # 'city': 'City',\n # 'state': 'ST',\n # 'country': 'US',\n # 'zip_code': '11000',\n # 'street_addr2': None}]},\n # errors={})\n\n\nFor more details, please see the full documentation at https://schemable.readthedocs.io.\n\n\n.. |version| image:: https://img.shields.io/pypi/v/schemable.svg?style=flat-square\n :target: https://pypi.python.org/pypi/schemable/\n\n.. |travis| image:: https://img.shields.io/travis/dgilland/schemable/master.svg?style=flat-square\n :target: https://travis-ci.org/dgilland/schemable\n\n.. |coveralls| image:: https://img.shields.io/coveralls/dgilland/schemable/master.svg?style=flat-square\n :target: https://coveralls.io/r/dgilland/schemable\n\n.. |license| image:: https://img.shields.io/pypi/l/schemable.svg?style=flat-square\n :target: https://pypi.python.org/pypi/schemable/\n\nChangelog\n=========\n\n\nv0.5.0 (2018-08-17)\n-------------------\n\n- Don't load partial data from a nested schema if it was created with ``strict=True`` (e.g. ``Schema({'key': Schema({...}, strict=True)})``).\n\n\nv0.4.1 (2018-08-14)\n-------------------\n\n- Fix previous fix for case where schema results could have ``data`` or ``errors`` with schema classes as keys.\n- Ensure that ``Select('key', )`` doesn't call ```` if ``'key'`` was not found in the source data.\n\n\nv0.4.0 (2018-08-14)\n-------------------\n\n- Fix case where schema object with an ``Optional(key)`` would result in ``SchemaResult.errors[Optional(key)]``. Ensure that ``SchemaResult.errors[key]`` is set instead.\n- Ignore ``KeyError`` when using ``Schema({'key': Select('other_key')})`` when ``'other_key'`` isn't present in the source object. Return a missing key error instead.\n\n\nv0.3.1 (2018-07-31)\n-------------------\n\n- If a validate callable raises an exception, use its string representation as the schema error message. Previously, a custom error message stating that the callable should evaluate to true was used when validator returned falsey and when it raised an exception. That message is now only returned when the validator doesn't raise but returns falsey.\n\n\nv0.3.0 (2018-07-27)\n-------------------\n\n- Add schema helpers:\n\n - ``Select``\n - ``Use``\n\n- Include execption class name in error message returned by ``As``.\n- Always return a ``dict`` when parsing from dictionary schemas instead of trying to use the source data's type as an initializer. (**breaking change**)\n\n\nv0.2.0 (2018-07-25)\n-------------------\n\n- Rename ``Collection`` to ``List``. (**breaking change**)\n- Rename ``Object`` to ``Dict``. (**breaking change**)\n- Allow ``collections.abc.Mapping`` objects to be valid ``Dict`` objects.\n- Modify ``Type`` validation so that objects are only compared with ``isinstance``.\n- Improve docs.\n\n\nv0.1.0 (2018-07-24)\n-------------------\n\n- First release.\n\nLicense\n=======\n\nThe MIT License (MIT)\n\nCopyright (c) 2018, Derrick Gilland\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n\n\n", "description_content_type": "", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/dgilland/schemable", "keywords": "schemable", "license": "MIT License", "maintainer": "", "maintainer_email": "", "name": "schemable", "package_url": "https://pypi.org/project/schemable/", "platform": "", "project_url": "https://pypi.org/project/schemable/", "project_urls": { "Homepage": "https://github.com/dgilland/schemable" }, "release_url": "https://pypi.org/project/schemable/0.5.0/", "requires_dist": [ "coverage; extra == 'dev'", "flake8; extra == 'dev'", "pylint; extra == 'dev'", "pytest; extra == 'dev'", "pytest-cov; extra == 'dev'", "Sphinx; extra == 'dev'", "sphinx-rtd-theme; extra == 'dev'", "tox; extra == 'dev'", "twine; extra == 'dev'", "wheel; extra == 'dev'" ], "requires_python": "", "summary": "A schema loading and validation library", "version": "0.5.0" }, "last_serial": 4182028, "releases": { "0.1.0": [ { "comment_text": "", "digests": { "md5": "f3b94d749712657b1f6955efc958af1e", "sha256": "2526ab836fc93b7679692cc3f767b3edef12484ea16d9da65f65c3580dde9921" }, "downloads": -1, "filename": "schemable-0.1.0-py3-none-any.whl", "has_sig": false, "md5_digest": "f3b94d749712657b1f6955efc958af1e", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 12220, "upload_time": "2018-07-24T19:26:05", "url": "https://files.pythonhosted.org/packages/41/a0/a32ddd7dc580732c71801cc24879cc65cde0ffa667082198e59ad458f64e/schemable-0.1.0-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "bc93a27688c8f2a8e642dc37339f8956", "sha256": "afc7ce7ec61c2d8fc95242c35f22e3f020747eb3b4750a3863cc9e8efc798d62" }, "downloads": -1, "filename": "schemable-0.1.0.tar.gz", "has_sig": false, "md5_digest": "bc93a27688c8f2a8e642dc37339f8956", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 29293, "upload_time": "2018-07-24T19:26:07", "url": "https://files.pythonhosted.org/packages/97/7d/ec551a8248ae9fd283295d8d4a0b692704400bf365ae8810c0caf29144ef/schemable-0.1.0.tar.gz" } ], "0.2.0": [ { "comment_text": "", "digests": { "md5": "e139d16219120f95d80cd56eb8493c9b", "sha256": "7d2969974f453094af0eca95037bab8eec061402a7917eb5bf999b6260b88d54" }, "downloads": -1, "filename": "schemable-0.2.0-py3-none-any.whl", "has_sig": false, "md5_digest": "e139d16219120f95d80cd56eb8493c9b", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 10624, "upload_time": "2018-07-25T05:34:55", "url": "https://files.pythonhosted.org/packages/89/80/ec99df4a18c217ec13ab584b5c8094406b6ccb2becd1838e1dfdcbe6adc3/schemable-0.2.0-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "4fcf8c82063ed50c362d1c51b50effad", "sha256": "642ad700d33112f58f509c0bc6a296712c3c072d0e5514cec27b613f210377d7" }, "downloads": -1, "filename": "schemable-0.2.0.tar.gz", "has_sig": false, "md5_digest": "4fcf8c82063ed50c362d1c51b50effad", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 24815, "upload_time": "2018-07-25T05:34:56", "url": "https://files.pythonhosted.org/packages/2d/2e/964225d8ce1f82f95ae3ed1f2718cc7f4300c9b1bc544801ff93df0fb3d1/schemable-0.2.0.tar.gz" } ], "0.3.0": [ { "comment_text": "", "digests": { "md5": "fb45a68fc8a57bbb0dd1860a610858fe", "sha256": "ae5902410488b9d69f03e47f0690bd9f8d98c5ffae8f520f60edfa184699a767" }, "downloads": -1, "filename": "schemable-0.3.0-py3-none-any.whl", "has_sig": false, "md5_digest": "fb45a68fc8a57bbb0dd1860a610858fe", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 15219, "upload_time": "2018-07-27T21:42:07", "url": "https://files.pythonhosted.org/packages/2a/03/555a983b97e9aecb61b015206626fe824cc96163b23ba2ca1e7660914446/schemable-0.3.0-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "304542aa848a41b6cef4bdbe76392164", "sha256": "709295f263b201ca37f74d5ea1d1f36d261abd23e1d7aca6c810e02ddb6080ea" }, "downloads": -1, "filename": "schemable-0.3.0.tar.gz", "has_sig": false, "md5_digest": "304542aa848a41b6cef4bdbe76392164", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 27207, "upload_time": "2018-07-27T21:42:08", "url": "https://files.pythonhosted.org/packages/22/a4/591ca43e4c346e6beaa19ccec628809ecc45a673415406fecbb4068b1a9b/schemable-0.3.0.tar.gz" } ], "0.3.1": [ { "comment_text": "", "digests": { "md5": "ba50e6d513919653ce204db77d5ba0a0", "sha256": "1f80f1ff23d129cce4ca7692db31f3c951b6210c9fb3a63e7b202fe5e431cd40" }, "downloads": -1, "filename": "schemable-0.3.1-py3-none-any.whl", "has_sig": false, "md5_digest": "ba50e6d513919653ce204db77d5ba0a0", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 11691, "upload_time": "2018-07-31T14:21:07", "url": "https://files.pythonhosted.org/packages/ac/1c/34c88544a7342b2dfe75c502864b11f0e1d8f59cf9ef01b0294cb26a9e0b/schemable-0.3.1-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "50f38949852a9c6b82b8f88bde7cab2c", "sha256": "b5185f8a8959a1b400a8b656acd366bfbdf8906be2b3715aa54cbdde2b38c9f2" }, "downloads": -1, "filename": "schemable-0.3.1.tar.gz", "has_sig": false, "md5_digest": "50f38949852a9c6b82b8f88bde7cab2c", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 27081, "upload_time": "2018-07-31T14:21:08", "url": "https://files.pythonhosted.org/packages/b1/ae/9ccc7eb4c12fe8a0987514f7ba70b84418d6377cfd48d7ea6ae033115344/schemable-0.3.1.tar.gz" } ], "0.4.0": [ { "comment_text": "", "digests": { "md5": "4c704073e9a527ddab7ec1a0a4631891", "sha256": "316eba574a5e248da3d794b58f3420059eee73f0492fb11ff48721e7f08f8f0a" }, "downloads": -1, "filename": "schemable-0.4.0-py3-none-any.whl", "has_sig": false, "md5_digest": "4c704073e9a527ddab7ec1a0a4631891", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 11906, "upload_time": "2018-08-14T20:35:58", "url": "https://files.pythonhosted.org/packages/a3/36/6a7b18277bc6d5a79d46e4ce516a2d76ffbd2cb40dd002b53f4b9ea51773/schemable-0.4.0-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "5317df4e16bc817f17fba0a959b68d14", "sha256": "3e399c966621682984837f5d643af30a4c1acaeacc486b8f5c606cbf20d227eb" }, "downloads": -1, "filename": "schemable-0.4.0.tar.gz", "has_sig": false, "md5_digest": "5317df4e16bc817f17fba0a959b68d14", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 27634, "upload_time": "2018-08-14T20:35:59", "url": "https://files.pythonhosted.org/packages/59/ae/39f2277dc5487249d1b6c18ca11d3a415f4194d816f7b2125f8bbc850e05/schemable-0.4.0.tar.gz" } ], "0.4.1": [ { "comment_text": "", "digests": { "md5": "f00350d00de30b1c16bfa91a657fc921", "sha256": "06f0e5044d45c6e09865c8f8ce48cc8e31b1f214b63c94c00e29100006a34813" }, "downloads": -1, "filename": "schemable-0.4.1-py3-none-any.whl", "has_sig": false, "md5_digest": "f00350d00de30b1c16bfa91a657fc921", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 12069, "upload_time": "2018-08-14T21:42:58", "url": "https://files.pythonhosted.org/packages/cf/1f/64548c9adf573bedb35d656fe946a63a7c42dc6c29ddf7d87b1b5498ba58/schemable-0.4.1-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "305a65abfac0d9ee0e86b1b157ac7e99", "sha256": "d2aedcd4d0bad94a9d0b05f10c8f3d5f79e38828ffd5795fc4b930663a714f25" }, "downloads": -1, "filename": "schemable-0.4.1.tar.gz", "has_sig": false, "md5_digest": "305a65abfac0d9ee0e86b1b157ac7e99", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 27938, "upload_time": "2018-08-14T21:42:59", "url": "https://files.pythonhosted.org/packages/61/4c/4b470b0c45145cea9ff59db549cceb6016a547f05dba610f2428ea40a44b/schemable-0.4.1.tar.gz" } ], "0.5.0": [ { "comment_text": "", "digests": { "md5": "77c246376b232af8f1346422ac8da115", "sha256": "26b163404378d73660834c97b3ee2b597afbd8a840c0f3398148b8d5755f1839" }, "downloads": -1, "filename": "schemable-0.5.0-py3-none-any.whl", "has_sig": false, "md5_digest": "77c246376b232af8f1346422ac8da115", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 12193, "upload_time": "2018-08-17T23:05:11", "url": "https://files.pythonhosted.org/packages/c1/7e/2d2d616e1c535a38a18c2b940853f565f5496068ee504e8e8d76d8ea5940/schemable-0.5.0-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "58f2d4b3850011ec6e399e499d19f54c", "sha256": "cb230761370395a97e030751cec74654f9ef0a92cc91eb8c7f7f5f8037540ae1" }, "downloads": -1, "filename": "schemable-0.5.0.tar.gz", "has_sig": false, "md5_digest": "58f2d4b3850011ec6e399e499d19f54c", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 28170, "upload_time": "2018-08-17T23:05:12", "url": "https://files.pythonhosted.org/packages/b6/90/57cc7af97668d1f7456f00eb69d5ce26022d2703c56ef16a84db68429c50/schemable-0.5.0.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "77c246376b232af8f1346422ac8da115", "sha256": "26b163404378d73660834c97b3ee2b597afbd8a840c0f3398148b8d5755f1839" }, "downloads": -1, "filename": "schemable-0.5.0-py3-none-any.whl", "has_sig": false, "md5_digest": "77c246376b232af8f1346422ac8da115", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 12193, "upload_time": "2018-08-17T23:05:11", "url": "https://files.pythonhosted.org/packages/c1/7e/2d2d616e1c535a38a18c2b940853f565f5496068ee504e8e8d76d8ea5940/schemable-0.5.0-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "58f2d4b3850011ec6e399e499d19f54c", "sha256": "cb230761370395a97e030751cec74654f9ef0a92cc91eb8c7f7f5f8037540ae1" }, "downloads": -1, "filename": "schemable-0.5.0.tar.gz", "has_sig": false, "md5_digest": "58f2d4b3850011ec6e399e499d19f54c", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 28170, "upload_time": "2018-08-17T23:05:12", "url": "https://files.pythonhosted.org/packages/b6/90/57cc7af97668d1f7456f00eb69d5ce26022d2703c56ef16a84db68429c50/schemable-0.5.0.tar.gz" } ] }