{ "info": { "author": "konglw", "author_email": "konglwbox@foxmail.com", "bugtrack_url": null, "classifiers": [], "description": "# Protovtor is a Python data conversion and validation library\n\n[![Build Status](https://travis-ci.org/konglwbox/protovtor.svg?branch=master)](https://travis-ci.org/konglwbox/protovtor?branch=master)\n[![Coverage Status](https://coveralls.io/repos/github/konglwbox/protovtor/badge.svg?branch=master)](https://coveralls.io/github/konglwbox/protovtor?branch=master)\n\nProtovtor is a simple and flexible data conversion and validation library for Python. It is designed for converting and\nvalidating data coming into Python such as JSON/YAML(or something else), and convert them to Python data-types.\n\nGoals:\n1. Simple to use.\n2. Support complex data.\n3. Provide useful error messages.\n\n# Installation\nUse pip or easy_install: \n`pip install protovtor`\n\nTested with Python 2.7, 3.3, 3.4, 3.5, 3.6.\n\n# Quick start\n```python\n# coding: utf-8\nfrom protovtor import (Protocol, StringField, IntegerField, FloatField, LengthLimitTextField, BooleanField,\n DateTimeField, PlaceField, FieldList, UniqueFieldList, ProtocolField, validators)\nimport json\n\n# The usage of 'Field' and 'Validator'.\n# It is usually used for converting and validating fundamental type value.\n\nf = StringField(validators=[validators.Length(min=0, max=4), validators.AnyOf([\"9527\", \"8080\"])])\n\nvalue = 9527\nf.process(value)\n\nif f.validate():\n assert f.value == \"9527\"\n\nvalue = 9090\nf.process(value)\n\nif not f.validate():\n print(f.error) # Must be one of ['9527', '8080']\n\n\n# The usage of 'Protocol'.\n# It is usually used for converting and validating composite type value.\n\nclass UserProto(Protocol):\n field_username = StringField(validators=[validators.DataRequired(), validators.Length(max=100)])\n field_age = IntegerField(validators=[validators.DataRequired(), validators.NumberRange(max=28)])\n # The 'discard=True' mean that the 'email' will not in the result data if 'nullable=True'.\n field_email = StringField(validators=[validators.DataRequired()], nullable=True, discard=True)\n field_phone = StringField(validators=[validators.DataRequired()], nullable=True, discard=False)\n # The 'sex' in result data will be used the default value if 'nullable=False'.\n field_sex = StringField(validators=[validators.AnyOf([\"man\", \"woman\"])], nullable=False, default=\"woman\")\n\n\ndata = {\"username\": \"VeVe\", \"age\": 28, \"email\": None, \"phone\": None, \"sex\": None}\n\np = UserProto(data)\nif p.validate():\n print(p.data) # {'phone': None, 'age': 28, 'sex': 'woman', 'username': 'VeVe'}\n\ndata = {\"username\": \"VeVe\", \"age\": 30} # You can omit the none values.\n\np = UserProto(data)\nif not p.validate():\n print(p.error) # {'age': 'Can not greater then 28'}\n\n\n# A complex example.\n# This example has been used most of the features.\n\nclass AppProto(Protocol):\n \"\"\"\n App\n \"\"\"\n field_name = StringField(validators=[validators.Length(max=200), validators.DataRequired()])\n field_version = StringField(validators=[validators.DataRequired()])\n\n\nclass OSProto(AppProto):\n \"\"\"\n OS\n \"\"\"\n field_apps = FieldList(\n ProtocolField(AppProto),\n validators=[validators.DataRequired()]\n )\n\n def post_validate(self, fields):\n \"\"\"\n Overwrite super class's method. This method will be called before the method 'validate' returned.\n\n If you expect to have a custom validation with the fields, you should do it in this method.\n \"\"\"\n # Get the field object by the key.\n field_version = fields[\"version\"]\n # Get the value of the field.\n field_version_value = field_version.value\n\n # To have a custom validation.\n if int(field_version_value.split(\".\")[1]) < 13:\n # Remember to set 'error'.\n field_version.error = \"The version is too old\"\n return False\n\n return True\n\n\nclass CPUProto(Protocol):\n \"\"\"\n CPU\n \"\"\"\n field_processor = StringField(validators=[validators.DataRequired()])\n field_speed = FloatField(validators=[validators.AnyOf([2.3, 3.1])])\n\n\nclass DisplayProto(Protocol):\n \"\"\"\n Display\n \"\"\"\n field_type = StringField(validators=[validators.DataRequired()])\n field_resolutions = UniqueFieldList(\n StringField(validators=[validators.Regular(\"[\\d]+ by [\\d]+\")]),\n validators=[validators.Length(min=3)]\n )\n field_ppi = IntegerField(validators=[validators.DataRequired()])\n\n\nclass ProductProto(Protocol):\n \"\"\"\n Product\n \"\"\"\n field_model = StringField(validators=[validators.Length(max=200), validators.DataRequired()])\n field_touch_bar = BooleanField()\n field_size = IntegerField(validators=[validators.AnyOf([13, 15])])\n field_os = ProtocolField(OSProto)\n field_cpu = ProtocolField(CPUProto)\n field_ssd = IntegerField(validators=[validators.NumberRange(min=128, max=512)])\n field_memory = IntegerField(validators=[validators.DataRequired()])\n field_display = PlaceField(ProtocolField(DisplayProto), handler=json.loads)\n field_buy_date = DateTimeField(format=\"%Y-%m-%d %H:%M:%S\")\n field_doc = LengthLimitTextField(limit=10)\n\n def post_data(self, data):\n \"\"\"\n Overwrite super class's method. This method will be called before the method 'data' returned.\n\n If you expect to convert the data structure or something else, you should do it in this method, because\n the parameter 'data' has been converted and validated successfully.\n \"\"\"\n # Add an unit of 'G'.\n data[\"ssd\"] = str(data[\"ssd\"]) + \"G\"\n # To convert from 'GB' to 'MB'.\n data[\"memory\"] = data[\"memory\"] * 1024\n\n return data\n\n\ndata = {\n \"model\": \"MacBook Pro\", # str, max length: 200, required: True.\n \"touch_bar\": True, # bool.\n \"size\": 15, # int, one of: (13, 15).\n \"os\": { # dict.\n \"name\": \"macOS\", # str, max length: 200, required: True.\n \"version\": \"10.13.4\", # str, required: True; We expect to validate whether the version is old.\n \"apps\": [{ # list, required: True.\n \"name\": \"Numbers\", # str, max length: 200, required: True.\n \"version\": \"5.0.1\" # str, required: True.\n }, {\n \"name\": \"Pages\",\n \"version\": \"7.0.1\"\n }]\n },\n \"cpu\": {\n \"processor\": \"Intel Core i5\", # str, required: True.\n \"speed\": 3.1 # float, one of: (2.3, 3.1).\n },\n \"ssd\": \"256\", # int, min: 128, max: 512; We expect to add an unit of 'G'.\n \"memory\": \"16\", # int, required: True; We expect to convert from 'GB' to 'MB'.\n \"display\": json.dumps({ # str; We expect to convert it from json string to dict.\n \"type\": \"retina\", # str, required: True.\n \"resolutions\": [ # list, max length: 3; We expect to remove repeated value.\n \"1680 by 1050\",\n \"1440 by 900\",\n \"1440 by 900\", # A repeated value.\n \"1024 by 640\"\n ],\n \"ppi\": 227 # int, required: True.\n }),\n \"doc\": \"A very long Directions for use\", # str; We expect to cut more than 10 chars.\n \"buy_date\": \"2018-05-21 16:50:06\" # datetime.\n}\n\np = ProductProto(data)\nif p.validate():\n print(p.data)\n # {\n # \"cpu\": {\n # \"processor\": \"Intel Core i5\",\n # \"speed\": 3.1\n # },\n # \"display\": {\n # \"ppi\": 227,\n # \"resolutions\": [\n # \"1680 by 1050\",\n # \"1024 by 640\",\n # \"1440 by 900\"\n # ],\n # \"type\": \"retina\"\n # },\n # \"doc\": \"A very lon\",\n # \"memory\": 16384,\n # \"model\": \"MacBook Pro\",\n # \"os\": {\n # \"apps\": [\n # {\n # \"name\": \"Numbers\",\n # \"version\": \"5.0.1\"\n # },\n # {\n # \"name\": \"Pages\",\n # \"version\": \"7.0.1\"\n # }\n # ],\n # \"name\": \"macOS\",\n # \"version\": \"10.13.4\"\n # },\n # \"size\": 15,\n # \"ssd\": \"256G\",\n # \"buy_date\": datetime.datetime(2018, 5, 21, 16, 50, 6),\n # \"touch_bar\": True\n # }\n\n\n# Custom 'Field'.\n# This is an example of how to customize a 'UpperStringField'.\n\nclass UpperStringField(StringField):\n def process(self, value):\n super(UpperStringField, self).process(value)\n\n self.value = self.value.upper()\n\n\nf = UpperStringField()\n\nvalue = \"test\"\nf.process(value)\n\nif f.validate():\n assert f.value == \"TEST\"\n\n\n# Custom 'Validator'.\n# This is an example of how to customize a 'UpperRequired'.\n\nclass UpperRequired(validators.Validator):\n def validate(self, value):\n if not value.isupper():\n raise ValueError(\"The value is not upper\")\n\n\nf = StringField(validators=[UpperRequired()])\n\nvalue = \"test\"\nf.process(value)\n\nif not f.validate():\n print(f.error) # The value is not upper\n```", "description_content_type": "text/markdown", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/konglwbox/protovtor", "keywords": "protovtor,json,conversion,validation", "license": "MIT", "maintainer": "", "maintainer_email": "", "name": "protovtor", "package_url": "https://pypi.org/project/protovtor/", "platform": "", "project_url": "https://pypi.org/project/protovtor/", "project_urls": { "Homepage": "https://github.com/konglwbox/protovtor" }, "release_url": "https://pypi.org/project/protovtor/1.0.2/", "requires_dist": null, "requires_python": ">=2.7", "summary": "Simple data conversion and validation library", "version": "1.0.2" }, "last_serial": 4443076, "releases": { "0.0.10": [ { "comment_text": "", "digests": { "md5": "af253bdf0b685b5ce0059c2d91b3ec95", "sha256": "aebc52b800d2ea97dfb851fd96741e4ba70849b843e25d2cc5bd4b03e9e3fb6b" }, "downloads": -1, "filename": "protovtor-0.0.10.tar.gz", "has_sig": false, "md5_digest": "af253bdf0b685b5ce0059c2d91b3ec95", "packagetype": "sdist", "python_version": "source", "requires_python": ">=2.7", "size": 11744, "upload_time": "2018-05-23T03:43:27", "url": "https://files.pythonhosted.org/packages/c5/7a/e18b0f36482699cb36d6538deb0bf93fd5a0f8ed13b21f1cb2cc45b2e7e8/protovtor-0.0.10.tar.gz" } ], "0.0.9": [ { "comment_text": "", "digests": { "md5": "72903fbb9bbd543686d008b7844ffbc8", "sha256": "37c0906f8773f4fd8a3ad6e76645b7b02d723162b26bfb45699c0a2158a6511e" }, "downloads": -1, "filename": "protovtor-0.0.9.tar.gz", "has_sig": false, "md5_digest": "72903fbb9bbd543686d008b7844ffbc8", "packagetype": "sdist", "python_version": "source", "requires_python": ">=2.7", "size": 11431, "upload_time": "2018-05-22T09:32:27", "url": "https://files.pythonhosted.org/packages/9e/10/29255cc7ffce2cf25fb2be0b11fd14c2af3b23fbbc6e1790869e0a01bb43/protovtor-0.0.9.tar.gz" } ], "1.0.1": [ { "comment_text": "", "digests": { "md5": "5a4a234e318902b105c4b56bcb3a95ab", "sha256": "f7577665bee5be12f3605f32ab8c45cb166f4d58ffbd97ea4553e8f0b3823c81" }, "downloads": -1, "filename": "protovtor-1.0.1-py3-none-any.whl", "has_sig": false, "md5_digest": "5a4a234e318902b105c4b56bcb3a95ab", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=2.7", "size": 10101, "upload_time": "2018-09-25T03:05:25", "url": "https://files.pythonhosted.org/packages/f6/20/e84217685d59f53d3ff58d19979cccbc07fb96100498317ad260d30c3193/protovtor-1.0.1-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "1f21150cd8b3480759fa7b1224856fa8", "sha256": "2f4e8104aa4b529a62088a719381cddacc713a0777ea6863844558b3a26ed733" }, "downloads": -1, "filename": "protovtor-1.0.1.tar.gz", "has_sig": false, "md5_digest": "1f21150cd8b3480759fa7b1224856fa8", "packagetype": "sdist", "python_version": "source", "requires_python": ">=2.7", "size": 11621, "upload_time": "2018-09-25T03:05:27", "url": "https://files.pythonhosted.org/packages/c8/12/93e116f27594b6884c4f5fb22ac4a8694e0e2b78469072bea09ea40b23e1/protovtor-1.0.1.tar.gz" } ], "1.0.2": [ { "comment_text": "", "digests": { "md5": "378af1188680904b8f6babe6b4505c97", "sha256": "caf73de16bed29522af437ea16a4eb529a512ca5807a5818a85d840d20e76a68" }, "downloads": -1, "filename": "protovtor-1.0.2.tar.gz", "has_sig": false, "md5_digest": "378af1188680904b8f6babe6b4505c97", "packagetype": "sdist", "python_version": "source", "requires_python": ">=2.7", "size": 11651, "upload_time": "2018-11-02T03:30:26", "url": "https://files.pythonhosted.org/packages/7d/03/1c4fd4eec4befd3eabb645241a17bf8b94805478af14abc601fb62161702/protovtor-1.0.2.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "378af1188680904b8f6babe6b4505c97", "sha256": "caf73de16bed29522af437ea16a4eb529a512ca5807a5818a85d840d20e76a68" }, "downloads": -1, "filename": "protovtor-1.0.2.tar.gz", "has_sig": false, "md5_digest": "378af1188680904b8f6babe6b4505c97", "packagetype": "sdist", "python_version": "source", "requires_python": ">=2.7", "size": 11651, "upload_time": "2018-11-02T03:30:26", "url": "https://files.pythonhosted.org/packages/7d/03/1c4fd4eec4befd3eabb645241a17bf8b94805478af14abc601fb62161702/protovtor-1.0.2.tar.gz" } ] }