{ "info": { "author": "Henri Hulski", "author_email": "henri.hulski@gazeta.pl", "bugtrack_url": null, "classifiers": [ "Intended Audience :: Developers", "License :: OSI Approved :: BSD License", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3.4", "Programming Language :: Python :: 3.5", "Programming Language :: Python :: 3.6" ], "description": "more.cerberus: validation and normalization support for Morepath\n================================================================\n\nThis package provides Morepath integration for the Cerberus_ data validation\nlibrary:\n\n.. _Cerberus: http://python-cerberus.org\n\nCerberus can automate user input validation and normalization in a HTTP API.\n\n\nSchema\n------\n\nYou can define a schema simply as a Python dict:\n\n.. code-block:: python\n\n user_schema = {\n 'name': {'type': 'string', 'minlength' : 3, 'required': True},\n 'age': {'type': 'integer', 'min': 0, 'required': True}\n }\n\nAltenatively you can define the schema in yaml and load it\nwith pyyaml:\n\n.. code-block:: yaml\n\n user:\n name:\n type: string\n minlength: 3\n required: true\n age:\n type: integer\n min: 0\n required: true\n\n\n.. code-block:: python\n\n import yaml\n\n with open('schema.yml') as schema:\n schema = yaml.load(schema)\n\n user_schema = schema['user']\n\n\nValidate\n--------\n\nThe ``more.cerberus`` integration helps\nwith validation of the request body as it is POSTed or PUT to a view.\nFirst we must create a loader for our schema:\n\n.. code-block:: python\n\n from more.cerberus import loader\n\n user_schema_load = loader(user_schema)\n\nWe can use this loader to handle a PUT or POST request for instance:\n\n.. code-block:: python\n\n @App.json(model=User, request_method='POST', load=user_schema_load)\n def user_post(self, request, json):\n # json is now a validated and normalized dict of whatever got\n # POST onto this view that you can use to update\n # self\n\n\nUpdate models\n-------------\n\nBy default in PUT or PATCH requests the ``load`` function\nsets the ``update`` flag of the ``validate()`` method to ``True``,\nso required fields won\u2019t be checked. For other requests like\nPOST ``update`` is ``False``.\n\nYou can set this manually by passing the ``update`` argument\nto the ``load`` function:\n\n.. code-block:: python\n\n user_schema_load = loader(user_schema, update=False)\n\n @App.json(model=User, request_method='PUT', load=user_schema_load)\n def user_put(self, request, json):\n\n\nCustomize the Validator\n-----------------------\n\nWith Cerberus you can customize the rules, data types, validators,\ncoercers (for normalization) and default setters by subclassing\nCerberusValidator:\n\n.. code-block:: python\n\n import re\n from more.cerberus import CerberusValidator\n\n class CustomValidator(CerberusValidator):\n def _validator_validate_email(self, field, value):\n match = re.match(\n '^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\\.[a-zA-Z0-9-.]+$',value\n )\n if match == None:\n self._error(field, 'Not valid email')\n\n def _normalize_coerce_normalize_email(self, value):\n parts = value.split('@')\n if len(parts) != 2:\n return value\n else:\n domain = parts[1].lower\n if domain == 'googlemail.com':\n domain = 'gmail.com'\n return parts[0] + '@' + domain\n\nYou have to pass the custom Validator class to the ``load`` function:\n\n.. code-block:: python\n\n user_schema_load = loader(user_schema, validator=CustomValidator)\n\nNow you can use the new email validator and normalizer in your schema:\n\n.. code-block:: python\n\n user_schema = {\n 'name': {'type': 'string', 'minlength' : 3, 'required': True},\n 'email': {'type': 'string', 'validator': 'validate_email',\n 'coerce': 'normalize_email','required': True}\n }\n\nor with YAML:\n\n.. code-block:: yaml\n\n user:\n name:\n type: string\n minlength: 3\n required: true\n email:\n type: string\n validator: validate_email\n coerce: normalize_email\n required: true\n\nFor more information how to customize the Validator take a look at the\n`Cerberus documentation`_.\n\n.. _Cerberus documentation:\n http://docs.python-cerberus.org/en/stable/customize.html\n\n\nUse the request or app instance in your custom validator\n--------------------------------------------------------\n\nIn ``CerberusValidator`` you can access the ``request`` through\n``self.request`` and the ``app`` through ``self.request.app``.\nLike this you can use e.g. Morepath settings and services when\nextending rules.\n\nHere an example from `auth-boilerplate`_ for custom email validation and\nnormalization using a service based on `email_validator`_:\n\n.. _auth-boilerplate: https://github.com/yacoma/auth-boilerplate\n.. _email_validator: https://github.com/JoshData/python-email-validator\n\n.. code-block:: python\n\n from more.cerberus import CerberusValidator\n from email_validator import EmailSyntaxError, EmailUndeliverableError\n\n\n class Validator(CerberusValidator):\n def _validator_verify_email(self, field, value):\n email_validation_service = self.request.app.service(\n name='email_validation'\n )\n try:\n email_validation_service.verify(value)\n\n except EmailSyntaxError:\n self._error(field, 'Not valid email')\n\n except EmailUndeliverableError:\n self._error(field, 'Email could not be delivered')\n\n def _normalize_coerce_normalize_email(self, value):\n email_validation_service = self.request.app.service(\n name='email_validation'\n )\n return email_validation_service.normalize(value)\n\n\nError handling\n--------------\n\nIf validation fails due to a validation error (a required field is\nmissing, or a field is of the wrong datatype, for instance), you want\nto show some kind of error message. The ``load`` function created by\n``more.cerberus`` raises the ``more.cerberus.ValidationError`` exception\nin case of errors.\n\nThis exception object has an ``errors`` attribute with the validation errors.\nYou must define an exception view for it, otherwise validation errors are\nreturned as \"500 internal server error\" to API users.\n\nThis package provides a default exception view implementation. If you subclass\nyour application from ``more.cerberus.CerberusApp`` then you get a default\nerror view for ``ValidationError`` that has a 422 status code with a JSON\nresponse with the Cerberus errors structure:\n\n.. code-block:: python\n\n from more.cerberus import CerberusApp\n\n class App(CerberusApp):\n pass\n\nNow your app has reasonable error handling built-in.\n\nIf you want a different error view you can instead create it\nby yourself, e.g.:\n\n.. code-block:: python\n\n from more.cerberus.error import ValidationError\n\n from .app import App\n\n\n @App.json(model=ValidationError)\n def validation_error(self, request):\n @request.after\n def set_status(response):\n response.status = 422\n\n errors = list(self.errors.values())[0][0]\n\n return {\n 'errors': errors\n }\n\nThis could be used to extract the errors from a schema wrapped into\na dictionary like:\n\n.. code-block:: yaml\n\n article-schema:\n article:\n type: dict\n schema:\n title:\n type: string\n required: true\n body:\n type: string\n required: true\n\n\nCHANGES\n=======\n\n0.2 (2018-02-11)\n----------------\n\n- Add Python 3.6 support.\n- Add example for creating a custom error view to README.\n- Some smaller fixes.\n\n\n0.1 (2017-03-17)\n----------------\n\n- initial public release.\n\n\n", "description_content_type": null, "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/morepath/more.cerberus", "keywords": "morepath validation", "license": "BSD", "maintainer": "", "maintainer_email": "", "name": "more.cerberus", "package_url": "https://pypi.org/project/more.cerberus/", "platform": "", "project_url": "https://pypi.org/project/more.cerberus/", "project_urls": { "Homepage": "https://github.com/morepath/more.cerberus" }, "release_url": "https://pypi.org/project/more.cerberus/0.2/", "requires_dist": [ "morepath (>=0.18)", "cerberus", "pytest-cov; extra == 'coverage'", "flake8; extra == 'pep8'", "pep8-naming; extra == 'pep8'", "pytest (>=2.9.1); extra == 'test'", "pytest-remove-stale-bytecode; extra == 'test'", "webtest; extra == 'test'" ], "requires_python": "", "summary": "Cerberus validation support for Morepath", "version": "0.2" }, "last_serial": 3571902, "releases": { "0.1": [ { "comment_text": "", "digests": { "md5": "16cadc2b9cdc16deb79e3b848c0c081d", "sha256": "a7f4176b6d4f462516ad0e79fbb288ce9147beeb357205dedd43945d67d8b375" }, "downloads": -1, "filename": "more.cerberus-0.1-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "16cadc2b9cdc16deb79e3b848c0c081d", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 10534, "upload_time": "2017-03-17T18:21:06", "url": "https://files.pythonhosted.org/packages/ca/bd/d0c9e2cf7049e0e1c27bf0327301ab16d66ca416c04d903a0675cfab3a23/more.cerberus-0.1-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "3e38ef044d5fd477738d1f3343fa86f4", "sha256": "4777184454424ea3ae6af0281f551ef94ac63561f325d6f314d85785e897cae5" }, "downloads": -1, "filename": "more.cerberus-0.1.tar.gz", "has_sig": false, "md5_digest": "3e38ef044d5fd477738d1f3343fa86f4", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 7431, "upload_time": "2017-03-17T18:21:10", "url": "https://files.pythonhosted.org/packages/d8/5a/f411786086840f903d4da852268761104c740ed3068daf161f2f0437ed68/more.cerberus-0.1.tar.gz" } ], "0.2": [ { "comment_text": "", "digests": { "md5": "3d0cb7fc6e2975f8a5639a9e5b073eb8", "sha256": "070812796f37549d2c19d103b3934349c080d9e71888d63e8269bd9e8b58d16b" }, "downloads": -1, "filename": "more.cerberus-0.2-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "3d0cb7fc6e2975f8a5639a9e5b073eb8", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 11133, "upload_time": "2018-02-11T11:40:45", "url": "https://files.pythonhosted.org/packages/8b/fb/c2b7981665cf0c6e6e6a157bb80841bbd280f845dfb8bce5369c16d7a42e/more.cerberus-0.2-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "00ce2922befd599f13511f7fbec0eaf1", "sha256": "eb893f72162c5f29b6e3e23af24fd79c2c7f0b960492f243422c3779134ee4da" }, "downloads": -1, "filename": "more.cerberus-0.2.tar.gz", "has_sig": false, "md5_digest": "00ce2922befd599f13511f7fbec0eaf1", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 7858, "upload_time": "2018-02-11T11:40:47", "url": "https://files.pythonhosted.org/packages/e4/fe/a23ba56e85347c84a5fdab353fa09cf3d885ec982a5d8620d8917149fb1c/more.cerberus-0.2.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "3d0cb7fc6e2975f8a5639a9e5b073eb8", "sha256": "070812796f37549d2c19d103b3934349c080d9e71888d63e8269bd9e8b58d16b" }, "downloads": -1, "filename": "more.cerberus-0.2-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "3d0cb7fc6e2975f8a5639a9e5b073eb8", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 11133, "upload_time": "2018-02-11T11:40:45", "url": "https://files.pythonhosted.org/packages/8b/fb/c2b7981665cf0c6e6e6a157bb80841bbd280f845dfb8bce5369c16d7a42e/more.cerberus-0.2-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "00ce2922befd599f13511f7fbec0eaf1", "sha256": "eb893f72162c5f29b6e3e23af24fd79c2c7f0b960492f243422c3779134ee4da" }, "downloads": -1, "filename": "more.cerberus-0.2.tar.gz", "has_sig": false, "md5_digest": "00ce2922befd599f13511f7fbec0eaf1", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 7858, "upload_time": "2018-02-11T11:40:47", "url": "https://files.pythonhosted.org/packages/e4/fe/a23ba56e85347c84a5fdab353fa09cf3d885ec982a5d8620d8917149fb1c/more.cerberus-0.2.tar.gz" } ] }