{ "info": { "author": "George Sakkis", "author_email": "george.sakkis@gmail.com", "bugtrack_url": null, "classifiers": [ "Development Status :: 5 - Production/Stable", "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Operating System :: OS Independent", "Programming Language :: Python :: 2", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.3", "Programming Language :: Python :: 3.4", "Topic :: Software Development :: Libraries :: Python Modules" ], "description": "========\nValideer\n========\n\n.. image:: https://travis-ci.org/podio/valideer.svg?branch=master\n :target: https://travis-ci.org/podio/valideer\n\n.. image:: https://coveralls.io/repos/podio/valideer/badge.svg?branch=master\n :target: https://coveralls.io/r/podio/valideer?branch=master\n\n.. image:: https://pypip.in/status/valideer/badge.svg\n :target: https://pypi.python.org/pypi/valideer/\n\n.. image:: https://pypip.in/version/valideer/badge.svg\n :target: https://pypi.python.org/pypi/valideer/\n\n.. image:: https://pypip.in/py_versions/valideer/badge.svg\n :target: https://pypi.python.org/pypi/valideer/\n\n.. image:: https://pypip.in/license/valideer/badge.svg\n :target: https://pypi.python.org/pypi/valideer/\n\nLightweight data validation and adaptation library for Python.\n\n**At a Glance**:\n\n- Supports both validation (check if a value is valid) and adaptation (convert\n a valid input to an appropriate output).\n- Succinct: validation schemas can be specified in a declarative and extensible\n mini \"language\"; no need to define verbose schema classes upfront. A regular\n Python API is also available if the compact syntax is not your cup of tea.\n- Batteries included: validators for most common types are included out of the box.\n- Extensible: New custom validators and adaptors can be easily defined and\n registered.\n- Informative, customizable error messages: Validation errors include the reason\n and location of the error.\n- Agnostic: not tied to any particular framework or application domain (e.g.\n Web form validation).\n- Well tested: Extensive test suite with 100% coverage.\n- Production ready: Used for validating every access to the `Podio API`_.\n- Licence: MIT.\n\n\nInstallation\n------------\n\nTo install run::\n\n pip install valideer\n\nOr for the latest version::\n\n git clone git@github.com:podio/valideer.git\n cd valideer\n python setup.py install\n\nYou may run the unit tests with::\n\n $ python setup.py test --quiet\n running test\n running egg_info\n writing dependency_links to valideer.egg-info/dependency_links.txt\n writing requirements to valideer.egg-info/requires.txt\n writing valideer.egg-info/PKG-INFO\n writing top-level names to valideer.egg-info/top_level.txt\n reading manifest file 'valideer.egg-info/SOURCES.txt'\n reading manifest template 'MANIFEST.in'\n writing manifest file 'valideer.egg-info/SOURCES.txt'\n running build_ext\n ...........................................................................................................................................................................\n ----------------------------------------------------------------------\n Ran 171 tests in 0.106s\n\n OK\n\nBasic Usage\n-----------\n\nWe'll demonstrate ``valideer`` using the following `JSON schema example`_::\n\n\t{\n\t \"name\": \"Product\",\n\t \"properties\": {\n\t \"id\": {\n\t \"type\": \"number\",\n\t \"description\": \"Product identifier\",\n\t \"required\": true\n\t },\n\t \"name\": {\n\t \"type\": \"string\",\n\t \"description\": \"Name of the product\",\n\t \"required\": true\n\t },\n\t \"price\": {\n\t \"type\": \"number\",\n\t \"minimum\": 0,\n\t \"required\": true\n\t },\n\t \"tags\": {\n\t \"type\": \"array\",\n\t \"items\": {\n\t \"type\": \"string\"\n\t }\n\t },\n\t \"stock\": {\n\t \"type\": \"object\",\n\t \"properties\": {\n\t \"warehouse\": {\n\t \"type\": \"number\"\n\t },\n\t \"retail\": {\n\t \"type\": \"number\"\n\t }\n\t }\n\t }\n\t }\n\t}\n\nThis can be specified by passing a similar but less verbose structure to the\n``valideer.parse`` function::\n\n\t>>> import valideer as V\n\t>>> product_schema = {\n\t>>> \"+id\": \"number\",\n\t>>> \"+name\": \"string\",\n\t>>> \"+price\": V.Range(\"number\", min_value=0),\n\t>>> \"tags\": [\"string\"],\n\t>>> \"stock\": {\n\t>>> \"warehouse\": \"number\",\n\t>>> \"retail\": \"number\",\n\t>>> }\n\t>>> }\n\t>>> validator = V.parse(product_schema)\n\n``parse`` returns a ``Validator`` instance, which can be then used to validate\nor adapt values.\n\nValidation\n##########\n\nTo check if an input is valid call the ``is_valid`` method::\n\n\t>>> product1 = {\n\t>>> \"id\": 1,\n\t>>> \"name\": \"Foo\",\n\t>>> \"price\": 123,\n\t>>> \"tags\": [\"Bar\", \"Eek\"],\n\t>>> \"stock\": {\n\t>>> \"warehouse\": 300,\n\t>>> \"retail\": 20\n\t>>> }\n\t>>> }\n\t>>> validator.is_valid(product1)\n\tTrue\n\t>>> product2 = {\n\t>>> \"id\": 1,\n\t>>> \"price\": 123,\n\t>>> }\n\t>>> validator.is_valid(product2)\n\tFalse\n\nAnother option is the ``validate`` method. If the input is invalid, it raises\n``ValidationError``::\n\n\t>>> validator.validate(product2)\n\tValidationError: Invalid value {'price': 123, 'id': 1} (dict): missing required properties: ['name']\n\nFor the common use case of validating inputs when entering a function, the\n``@accepts`` decorator provides some nice syntax sugar (shamelessly stolen from\ntypecheck_)::\n\n\t>>> from valideer import accepts\n\t>>> @accepts(product=product_schema, quantity=\"integer\")\n\t>>> def get_total_price(product, quantity=1):\n\t>>> return product[\"price\"] * quantity\n\t>>>\n\t>>> get_total_price(product1, 2)\n\t246\n\t>>> get_total_price(product1, 0.5)\n\tValidationError: Invalid value 0.5 (float): must be integer (at quantity)\n\t>>> get_total_price(product2)\n\tValidationError: Invalid value {'price': 123, 'id': 1} (dict): missing required properties: ['name'] (at product)\n\nAdaptation\n##########\n\nOften input data have to be converted from their original form before they are\nready to use; for example a number that may arrive as integer or string and\nneeds to be adapted to a float. Since validation and adaptation usually happen\nsimultaneously, ``validate`` returns the adapted version of the (valid) input\nby default.\n\nAn existing class can be easily used as an adaptor by being wrapped in ``AdaptTo``::\n\n\t>>> import valideer as V\n\t>>> adapt_prices = V.parse({\"prices\": [V.AdaptTo(float)]}).validate\n\t>>> adapt_prices({\"prices\": [\"2\", \"3.1\", 1]})\n\t{'prices': [2.0, 3.1, 1.0]}\n\t>>> adapt_prices({\"prices\": [\"2\", \"3f\"]})\n\tValidationError: Invalid value '3f' (str): invalid literal for float(): 3f (at prices[1])\n\t>>> adapt_prices({\"prices\": [\"2\", 1, None]})\n\tValidationError: Invalid value None (NoneType): float() argument must be a string or a number (at prices[2])\n\nSimilar to ``@accepts``, the ``@adapts`` decorator provides a convenient syntax\nfor adapting function inputs::\n\n\t>>> from valideer import adapts\n\t>>> @adapts(json={\"prices\": [AdaptTo(float)]})\n\t>>> def get_sum_price(json):\n\t>>> return sum(json[\"prices\"])\n\t>>> get_sum_price({\"prices\": [\"2\", \"3.1\", 1]})\n\t6.1\n\t>>> get_sum_price({\"prices\": [\"2\", \"3f\"]})\n\tValidationError: Invalid value '3f' (str): invalid literal for float(): 3f (at json['prices'][1])\n\t>>> get_sum_price({\"prices\": [\"2\", 1, None]})\n\tValidationError: Invalid value None (NoneType): float() argument must be a string or a number (at json['prices'][2])\n\nRequired and optional object properties\n#######################################\n\nBy default object properties are considered optional unless they start with \"+\".\nThis default can be inverted by using the ``parsing`` context manager with\n``required_properties=True``. In this case object properties are considered\nrequired by default unless they start with \"?\". For example::\n\n\tvalidator = V.parse({\n\t \"+name\": \"string\",\n\t \"duration\": {\n\t \"+hours\": \"integer\",\n\t \"+minutes\": \"integer\",\n\t \"seconds\": \"integer\"\n\t }\n\t})\n\nis equivalent to::\n\n with V.parsing(required_properties=True):\n \tvalidator = V.parse({\n \t \"name\": \"string\",\n \t \"?duration\": {\n \t \"hours\": \"integer\",\n \t \"minutes\": \"integer\",\n \t \"?seconds\": \"integer\"\n \t }\n \t})\n\nIgnoring optional object property errors\n########################################\n\nBy default an invalid object property value raises ``ValidationError``,\nregardless of whether it's required or optional. It is possible to ignore invalid\nvalues for optional properties by using the ``parsing`` context manager with\n``ignore_optional_property_errors=True``::\n\n >>> schema = {\n ... \"+name\": \"string\",\n ... \"price\": \"number\",\n ... }\n >>> data = {\"name\": \"wine\", \"price\": \"12.50\"}\n >>> V.parse(schema).validate(data)\n valideer.base.ValidationError: Invalid value '12.50' (str): must be number (at price)\n >>> with V.parsing(ignore_optional_property_errors=True):\n ... print V.parse(schema).validate(data)\n {'name': 'wine'}\n\nAdditional object properties\n############################\n\nAny properties that are not specified as either required or optional are allowed\nby default. This default can be overriden by calling ``parsing`` with\n``additional_properties=``\n\n- ``False`` to disallow all additional properties\n- ``Object.REMOVE`` to remove all additional properties from the adapted value\n- any validator or parseable schema to validate all additional property\n values using this schema::\n\n\t>>> schema = {\n\t>>> \"name\": \"string\",\n\t>>> \"duration\": {\n\t>>> \"hours\": \"integer\",\n\t>>> \"minutes\": \"integer\",\n\t>>> }\n\t>>> }\n\t>>> data = {\"name\": \"lap\", \"duration\": {\"hours\":3, \"minutes\":33, \"seconds\": 12}}\n\t>>> V.parse(schema).validate(data)\n\t{'duration': {'hours': 3, 'minutes': 33, 'seconds': 12}, 'name': 'lap'}\n\t>>> with V.parsing(additional_properties=False):\n\t... V.parse(schema).validate(data)\n\tValidationError: Invalid value {'hours': 3, 'seconds': 12, 'minutes': 33} (dict): additional properties: ['seconds'] (at duration)\n\t>>> with V.parsing(additional_properties=V.Object.REMOVE):\n\t... print V.parse(schema).validate(data)\n\t{'duration': {'hours': 3, 'minutes': 33}, 'name': 'lap'}\n\t>>> with V.parsing(additional_properties=\"string\"):\n\t... V.parse(schema).validate(data)\n\tValidationError: Invalid value 12 (int): must be string (at duration['seconds'])\n\n\nExplicit Instantiation\n######################\n\nThe usual way to create a validator is by passing an appropriate nested structure\nto ``parse``, as outlined above. This enables concise schema definitions with\nminimal boilerplate. In case this seems too cryptic or \"unpythonic\" for your\ntaste, a validator can be also created explicitly from regular Python classes::\n\n\t>>> from valideer import Object, HomogeneousSequence, Number, String, Range\n\t>>> validator = Object(\n\t>>> required={\n\t>>> \"id\": Number(),\n\t>>> \"name\": String(),\n\t>>> \"price\": Range(Number(), min_value=0),\n\t>>> },\n\t>>> optional={\n\t>>> \"tags\": HomogeneousSequence(String()),\n\t>>> \"stock\": Object(\n\t>>> optional={\n\t>>> \"warehouse\": Number(),\n\t>>> \"retail\": Number(),\n\t>>> }\n\t>>> )\n\t>>> }\n\t>>> )\n\n\nBuilt-in Validators\n-------------------\n``valideer`` comes with several predefined validators, each implemented as a\n``Validator`` subclass. As shown above, some validator classes also support a\nshortcut form that can be used to specify implicitly a validator instance.\n\nBasic\n#####\n\n* ``valideer.Boolean()``: Accepts ``bool`` instances.\n\n :Shortcut: ``\"boolean\"``\n\n* ``valideer.Integer()``: Accepts integers (``numbers.Integral`` instances),\n excluding ``bool``.\n\n :Shortcut: ``\"integer\"``\n\n* ``valideer.Number()``: Accepts numbers (``numbers.Number`` instances),\n excluding ``bool``.\n\n :Shortcut: ``\"number\"``\n\n* ``valideer.Date()``: Accepts ``datetime.date`` instances.\n\n :Shortcut: ``\"date\"``\n\n* ``valideer.Time()``: Accepts ``datetime.time`` instances.\n\n :Shortcut: ``\"time\"``\n\n* ``valideer.Datetime()``: Accepts ``datetime.datetime`` instances.\n\n :Shortcut: ``\"datetime\"``\n\n* ``valideer.String(min_length=None, max_length=None)``: Accepts strings\n (``basestring`` instances).\n\n :Shortcut: ``\"string\"``\n\n* ``valideer.Pattern(regexp)``: Accepts strings that match the given regular\n expression.\n\n :Shortcut: *Compiled regular expression*\n\n* ``valideer.Condition(predicate, traps=Exception)``: Accepts values for which\n ``predicate(value)`` is true. Any raised exception that is instance of ``traps``\n is re-raised as a ``ValidationError``.\n\n :Shortcut: *Python function or method*.\n\n* ``valideer.Type(accept_types=None, reject_types=None)``: Accepts instances of\n the given ``accept_types`` but excluding instances of ``reject_types``.\n\n :Shortcut: *Python type*. For example ``int`` is equivalent to ``valideer.Type(int)``.\n\n* ``valideer.Enum(values)``: Accepts a fixed set of values.\n\n :Shortcut: *N/A*\n\nContainers\n##########\n\n* ``valideer.HomogeneousSequence(item_schema=None, min_length=None, max_length=None)``:\n Accepts sequences (``collections.Sequence`` instances excluding strings) with\n elements that are valid for ``item_schema`` (if specified) and length between\n ``min_length`` and ``max_length`` (if specified).\n\n :Shortcut: [*item_schema*]\n\n* ``valideer.HeterogeneousSequence(*item_schemas)``: Accepts fixed length\n sequences (``collections.Sequence`` instances excluding strings) where the\n ``i``-th element is valid for the ``i``-th ``item_schema``.\n\n :Shortcut: (*item_schema*, *item_schema*, ..., *item_schema*)\n\n* ``valideer.Mapping(key_schema=None, value_schema=None)``: Accepts mappings\n (``collections.Mapping`` instances) with keys that are valid for ``key_schema``\n (if specified) and values that are valid for ``value_schema`` (if specified).\n\n :Shortcut: *N/A*\n\n* ``valideer.Object(optional={}, required={}, additional=True)``: Accepts JSON-like\n objects (``collections.Mapping`` instances with string keys). Properties that\n are specified as ``optional`` or ``required`` are validated against the respective\n value schema. Any additional properties are either allowed (if ``additional``\n is True), disallowed (if ``additional`` is False) or validated against the\n ``additional`` schema.\n\n :Shortcut: {\"*property*\": *value_schema*, \"*property*\": *value_schema*, ...,\n \t\t\t \"*property*\": *value_schema*}. Properties that start with ``'+'``\n \t\t\t are required, the rest are optional and additional properties are\n \t\t\t allowed.\n\nAdaptors\n########\n\n* ``valideer.AdaptBy(adaptor, traps=Exception)``: Adapts a value by calling\n ``adaptor(value)``. Any raised exception that is instance of ``traps`` is\n wrapped into a ``ValidationError``.\n\n :Shortcut: *N/A*\n\n* ``valideer.AdaptTo(adaptor, traps=Exception, exact=False)``: Similar to\n ``AdaptBy`` but for types. Any value that is already instance of ``adaptor``\n is returned as is, otherwise it is adapted by calling ``adaptor(value)``. If\n ``exact`` is ``True``, instances of ``adaptor`` subclasses are also adapted.\n\n :Shortcut: *N/A*\n\nComposite\n#########\n\n* ``valideer.Nullable(schema, default=None)``: Accepts values that are valid for\n ``schema`` or ``None``. ``default`` is returned as the adapted value of ``None``.\n ``default`` can also be a zero-argument callable, in which case the adapted\n value of ``None`` is ``default()``.\n\n :Shortcut: \"?{*validator_name*}\". For example ``\"?integer\"`` accepts any integer\n \t\t\t or ``None`` value.\n\n* ``valideer.NonNullable(schema=None)``: Accepts values that are valid for\n ``schema`` (if specified) except for ``None``.\n\n :Shortcut: \"+{*validator_name*}\"\n\n* ``valideer.Range(schema, min_value=None, max_value=None)``: Accepts values that\n are valid for ``schema`` and within the given ``[min_value, max_value]`` range.\n\n :Shortcut: *N/A*\n\n* ``valideer.AnyOf(*schemas)``: Accepts values that are valid for at least one\n of the given ``schemas``.\n\n :Shortcut: *N/A*\n\n* ``valideer.AllOf(*schemas)``: Accepts values that are valid for all the given\n ``schemas``.\n\n :Shortcut: *N/A*\n\n* ``valideer.ChainOf(*schemas)``: Passes values through a chain of validator and\n adaptor ``schemas``.\n\n :Shortcut: *N/A*\n\n\nUser Defined Validators\n-----------------------\n\nThe set of predefined validators listed above can be easily extended with user\ndefined validators. All you need to do is extend ``Validator`` (or a more\nconvenient subclass) and implement the ``validate`` method. Here is an example\nof a custom validator that could be used to enforce minimal password strength::\n\n\tfrom valideer import String, ValidationError\n\n\tclass Password(String):\n\n\t name = \"password\"\n\n\t def __init__(self, min_length=6, min_lower=1, min_upper=1, min_digits=0):\n\t super(Password, self).__init__(min_length=min_length)\n\t self.min_lower = min_lower\n\t self.min_upper = min_upper\n\t self.min_digits = min_digits\n\n\t def validate(self, value, adapt=True):\n\t super(Password, self).validate(value)\n\n\t if len(filter(str.islower, value)) < self.min_lower:\n\t raise ValidationError(\"At least %d lowercase characters required\" % self.min_lower)\n\n\t if len(filter(str.isupper, value)) < self.min_upper:\n\t raise ValidationError(\"At least %d uppercase characters required\" % self.min_upper)\n\n\t if len(filter(str.isdigit, value)) < self.min_digits:\n\t raise ValidationError(\"At least %d digits required\" % self.min_digits)\n\n\t return value\n\nA few notes:\n\n* The optional ``name`` class attribute creates a shortcut for referring to a\n default instance of the validator. In this example the string ``\"password\"``\n becomes an alias to a ``Password()`` instance.\n\n* ``validate`` takes an optional boolean ``adapt`` parameter that defaults to\n ``True``. If it is ``False``, the validator is allowed to skip adaptation and\n perform validation only. This is basically an optimization hint that can be\n useful if adaptation happens to be significantly more expensive than validation.\n This isn't common though and so ``adapt`` is usually ignored.\n\nShortcut Registration\n#####################\n\nSetting a ``name`` class attribute is the simplest way to create a validator\nshortcut. A shortcut can also be created explicitly with the ``valideer.register``\nfunction::\n\n\t>>> import valideer as V\n\t>>> V.register(\"strong_password\", Password(min_length=8, min_digits=1))\n\t>>> is_fair_password = V.parse(\"password\").is_valid\n\t>>> is_strong_password = V.parse(\"strong_password\").is_valid\n\t>>> for pwd in \"passwd\", \"Passwd\", \"PASSWd\", \"Pas5word\":\n\t>>> print (pwd, is_fair_password(pwd), is_strong_password(pwd))\n\t('passwd', False, False)\n\t('Passwd', True, False)\n\t('PASSWd', True, False)\n\t('Pas5word', True, True)\n\nFinally it is possible to parse arbitrary Python objects as validator shortcuts.\nFor example let's define a ``Not`` composite validator, a validator that accepts\na value if and only if it is rejected by another validator::\n\n\tclass Not(Validator):\n\n\t def __init__(self, schema):\n\t self._validator = Validator.parse(schema)\n\n\t def validate(self, value, adapt=True):\n\t if self._validator.is_valid(value):\n\t raise ValidationError(\"Should not be a %s\" % self._validator.__class__.__name__, value)\n\t return value\n\nIf we'd like to parse ``'!foo'`` strings as a shortcut for ``Not('foo')``, we\ncan do so with the ``valideer.register_factory`` decorator::\n\n\t>>> @V.register_factory\n\t>>> def NotFactory(obj):\n\t>>> if isinstance(obj, basestring) and obj.startswith(\"!\"):\n\t>>> return Not(obj[1:])\n\t>>>\n\t>>> validate = V.parse({\"i\": \"integer\", \"s\": \"!number\"}).validate\n\t>>> validate({\"i\": 4, \"s\": \"\"})\n\t{'i': 4, 's': ''}\n\t>>> validate({\"i\": 4, \"s\": 1.2})\n\tValidationError: Invalid value 1.2 (float): Should not be a Number (at s)\n\n\n.. _valideer: https://github.com/podio/valideer\n.. _JSON Schema: https://tools.ietf.org/html/draft-zyp-json-schema-03\n.. _Podio API: https://developers.podio.com\n.. _nose: http://pypi.python.org/pypi/nose\n.. _coverage: http://pypi.python.org/pypi/coverage\n.. _JSON schema example: http://en.wikipedia.org/wiki/JSON#Schema\n.. _typecheck: http://pypi.python.org/pypi/typecheck", "description_content_type": null, "docs_url": null, "download_url": "UNKNOWN", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/podio/valideer", "keywords": "validation adaptation typechecking jsonschema", "license": "UNKNOWN", "maintainer": null, "maintainer_email": null, "name": "valideer", "package_url": "https://pypi.org/project/valideer/", "platform": "any", "project_url": "https://pypi.org/project/valideer/", "project_urls": { "Download": "UNKNOWN", "Homepage": "https://github.com/podio/valideer" }, "release_url": "https://pypi.org/project/valideer/0.4.2/", "requires_dist": null, "requires_python": null, "summary": "Lightweight data validation and adaptation library for Python", "version": "0.4.2" }, "last_serial": 1870730, "releases": { "0.1": [ { "comment_text": "", "digests": { "md5": "12cc48fe3504a4678c299680e7db7808", "sha256": "558840b51c5c731b8c6511b32d7db776ad8e0e33684709d9c8af872a6e4e12ca" }, "downloads": -1, "filename": "valideer-0.1.tar.gz", "has_sig": false, "md5_digest": "12cc48fe3504a4678c299680e7db7808", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 17887, "upload_time": "2012-08-29T20:57:19", "url": "https://files.pythonhosted.org/packages/e8/79/0d02e6c870ffd4b89f9034fe4d89125cc2c6a0ffca6b8482f84c23c079d2/valideer-0.1.tar.gz" } ], "0.2": [ { "comment_text": "", "digests": { "md5": "1d9f8d04dca179a176822344cf3a00f1", "sha256": "46c4f222d96e4f7a8f392d0c87f1d95f0ec78946d4505737f3743a43f94e5f3d" }, "downloads": -1, "filename": "valideer-0.2.tar.gz", "has_sig": false, "md5_digest": "1d9f8d04dca179a176822344cf3a00f1", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 19323, "upload_time": "2013-04-09T12:31:26", "url": "https://files.pythonhosted.org/packages/82/00/d0bd234919153ec55229821b63c0560027e1c57a11ef08095197bc7a6cce/valideer-0.2.tar.gz" } ], "0.3": [ { "comment_text": "", "digests": { "md5": "6b693a5b67f078f60fb94233a2c5e9f0", "sha256": "59aa9e9a43e6bf5428e47f5ac420fb0cce7b37fc13270884530b756edaf3d924" }, "downloads": -1, "filename": "valideer-0.3.tar.gz", "has_sig": false, "md5_digest": "6b693a5b67f078f60fb94233a2c5e9f0", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 21874, "upload_time": "2013-08-13T19:26:32", "url": "https://files.pythonhosted.org/packages/c6/d5/717de28e5c12ade50cfa12e862d22449cda477457af8cb19123692ccbeb3/valideer-0.3.tar.gz" } ], "0.3.1": [ { "comment_text": "", "digests": { "md5": "9e40710377daae16194406c65386d6d0", "sha256": "1742d8c0485cd79134f7f76dee10462cc78f6a7234b1723f400fa6f2db9d87f4" }, "downloads": -1, "filename": "valideer-0.3.1.tar.gz", "has_sig": false, "md5_digest": "9e40710377daae16194406c65386d6d0", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 23444, "upload_time": "2014-07-22T08:38:52", "url": "https://files.pythonhosted.org/packages/b7/84/86a09b2e9ced23801758ff48966bb0dfddc956d8e6e76dd896c7a464b653/valideer-0.3.1.tar.gz" } ], "0.3.2": [ { "comment_text": "", "digests": { "md5": "4bef0de27b862d3fda9d36c41183ad5a", "sha256": "d3f23567c85004faa2fb619e0b97f3beb7003601c12d238894b281425c14b026" }, "downloads": -1, "filename": "valideer-0.3.2.tar.gz", "has_sig": false, "md5_digest": "4bef0de27b862d3fda9d36c41183ad5a", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 23812, "upload_time": "2014-09-14T06:48:27", "url": "https://files.pythonhosted.org/packages/ff/c9/fba7a1bafa9ee280d44e00eae94454ea8d3e6cff62787f70fc9b4ba05b48/valideer-0.3.2.tar.gz" } ], "0.4": [ { "comment_text": "", "digests": { "md5": "599e23ae24aef1ce5606aa1a1f0801bb", "sha256": "8ff03ea4fd9eb43c10829a1db0fc4a7d90d3d8910d14c7637ae374c1871eb19e" }, "downloads": -1, "filename": "valideer-0.4.tar.gz", "has_sig": false, "md5_digest": "599e23ae24aef1ce5606aa1a1f0801bb", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 24349, "upload_time": "2014-11-24T08:32:12", "url": "https://files.pythonhosted.org/packages/b9/6d/70c767cd1c7c28f53006f6620c195b365e460d7a003d3e8c5979ccec4a15/valideer-0.4.tar.gz" } ], "0.4.1": [ { "comment_text": "", "digests": { "md5": "1bcc3aea368dd7f815969d0381f9d901", "sha256": "53ca649b6540b0255d7f8cc8f9bbdc84dbf6d2dad232c8a33c9ca4b77bda2d0e" }, "downloads": -1, "filename": "valideer-0.4.1.tar.gz", "has_sig": false, "md5_digest": "1bcc3aea368dd7f815969d0381f9d901", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 24503, "upload_time": "2015-04-09T14:39:21", "url": "https://files.pythonhosted.org/packages/0d/56/1ea99967483695c6e8e5d33fabdae5d680eeea4931391824ef0a1f0f01b4/valideer-0.4.1.tar.gz" } ], "0.4.2": [ { "comment_text": "", "digests": { "md5": "9129e0c2394e2b30947f07c5e1bf5d4a", "sha256": "4b997751d514e9c8990321bf46c09b3b15c398472dae3ef993e2e0f72fe82596" }, "downloads": -1, "filename": "valideer-0.4.2.tar.gz", "has_sig": false, "md5_digest": "9129e0c2394e2b30947f07c5e1bf5d4a", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 25542, "upload_time": "2015-12-20T08:56:50", "url": "https://files.pythonhosted.org/packages/ef/57/b545a847c8b9028cb0ff34def26023011fb8da64e3348992db9e0464c601/valideer-0.4.2.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "9129e0c2394e2b30947f07c5e1bf5d4a", "sha256": "4b997751d514e9c8990321bf46c09b3b15c398472dae3ef993e2e0f72fe82596" }, "downloads": -1, "filename": "valideer-0.4.2.tar.gz", "has_sig": false, "md5_digest": "9129e0c2394e2b30947f07c5e1bf5d4a", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 25542, "upload_time": "2015-12-20T08:56:50", "url": "https://files.pythonhosted.org/packages/ef/57/b545a847c8b9028cb0ff34def26023011fb8da64e3348992db9e0464c601/valideer-0.4.2.tar.gz" } ] }