validator-collection


Namevalidator-collection JSON
Version 1.5.0 PyPI version JSON
download
home_pagehttps://github.com/insightindustry/validator-collection
SummaryCollection of 60+ Python functions for validating data
upload_time2020-10-12 17:24:21
maintainer
docs_urlNone
authorInsight Industry Inc.
requires_python>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, <4
licenseMIT
keywords validator validate validation validators
VCS
bugtrack_url
requirements alabaster attrs Babel certifi cffi chardet codecov colorama coverage docutils filelock html5lib idna imagesize isort Jinja2 jsonschema lazy-object-proxy MarkupSafe mccabe more-itertools packaging pkginfo pluggy py py-cpuinfo pycparser pyfakefs Pygments pyparsing pytest pytest-benchmark pytest-cov pytz readme-renderer requests requests-toolbelt restview six snowballstemmer Sphinx sphinx-rtd-theme sphinx-tabs sphinxcontrib-websupport toml tox tqdm twine urllib3 virtualenv webencodings wrapt
Travis-CI
coveralls test coverage No coveralls.
            
======================
Validator Collection
======================

**Python library of 60+ commonly-used validator functions**

.. list-table::
   :widths: 10 90
   :header-rows: 1

   * - Branch
     - Unit Tests
   * - `latest <https://github.com/insightindustry/validator-collection/tree/master>`_
     -
       .. image:: https://travis-ci.org/insightindustry/validator-collection.svg?branch=master
          :target: https://travis-ci.org/insightindustry/validator-collection
          :alt: Build Status (Travis CI)

       .. image:: https://codecov.io/gh/insightindustry/validator-collection/branch/master/graph/badge.svg
          :target: https://codecov.io/gh/insightindustry/validator-collection
          :alt: Code Coverage Status (Codecov)

       .. image:: https://readthedocs.org/projects/validator-collection/badge/?version=latest
          :target: http://validator-collection.readthedocs.io/en/latest/?badge=latest
          :alt: Documentation Status (ReadTheDocs)

   * - `v. 1.5 <https://github.com/insightindustry/validator-collection/tree/v.1.5.0>`_
     -
       .. image:: https://travis-ci.org/insightindustry/validator-collection.svg?branch=v.1.5.0
          :target: https://travis-ci.org/insightindustry/validator-collection
          :alt: Build Status (Travis CI)

       .. image:: https://codecov.io/gh/insightindustry/validator-collection/branch/v.1.5.0/graph/badge.svg
          :target: https://codecov.io/gh/insightindustry/validator-collection
          :alt: Code Coverage Status (Codecov)

       .. image:: https://readthedocs.org/projects/validator-collection/badge/?version=v.1.5.0
          :target: http://validator-collection.readthedocs.io/en/latest/?badge=v.1.5.0
          :alt: Documentation Status (ReadTheDocs)

   * - `v. 1.4 <https://github.com/insightindustry/validator-collection/tree/v.1.4.2>`_
     -
       .. image:: https://travis-ci.org/insightindustry/validator-collection.svg?branch=v.1.4.2
          :target: https://travis-ci.org/insightindustry/validator-collection
          :alt: Build Status (Travis CI)

       .. image:: https://codecov.io/gh/insightindustry/validator-collection/branch/v.1.4.2/graph/badge.svg
          :target: https://codecov.io/gh/insightindustry/validator-collection
          :alt: Code Coverage Status (Codecov)

       .. image:: https://readthedocs.org/projects/validator-collection/badge/?version=v.1.4.2
          :target: http://validator-collection.readthedocs.io/en/latest/?badge=v.1.4.2
          :alt: Documentation Status (ReadTheDocs)

   * - `v. 1.3 <https://github.com/insightindustry/validator-collection/tree/v.1.3.8>`_
     -
       .. image:: https://travis-ci.org/insightindustry/validator-collection.svg?branch=v.1.3.8
          :target: https://travis-ci.org/insightindustry/validator-collection
          :alt: Build Status (Travis CI)

       .. image:: https://codecov.io/gh/insightindustry/validator-collection/branch/v.1.3.8/graph/badge.svg
          :target: https://codecov.io/gh/insightindustry/validator-collection
          :alt: Code Coverage Status (Codecov)

       .. image:: https://readthedocs.org/projects/validator-collection/badge/?version=v.1.3.8
          :target: http://validator-collection.readthedocs.io/en/latest/?badge=v.1.3.8
          :alt: Documentation Status (ReadTheDocs)

   * - `v. 1.2 <https://github.com/insightindustry/validator-collection/tree/v.1.2.0>`_
     -
       .. image:: https://travis-ci.org/insightindustry/validator-collection.svg?branch=v.1.2.0
          :target: https://travis-ci.org/insightindustry/validator-collection
          :alt: Build Status (Travis CI)

       .. image:: https://codecov.io/gh/insightindustry/validator-collection/branch/v.1.2.0/graph/badge.svg
          :target: https://codecov.io/gh/insightindustry/validator-collection
          :alt: Code Coverage Status (Codecov)

       .. image:: https://readthedocs.org/projects/validator-collection/badge/?version=v.1.2.0
          :target: http://validator-collection.readthedocs.io/en/latest/?badge=v.1.2.0
          :alt: Documentation Status (ReadTheDocs)

   * - `v. 1.1 <https://github.com/insightindustry/validator-collection/tree/v.1.1.0>`_
     -
       .. image:: https://travis-ci.org/insightindustry/validator-collection.svg?branch=v.1.1.0
          :target: https://travis-ci.org/insightindustry/validator-collection
          :alt: Build Status (Travis CI)

       .. image:: https://codecov.io/gh/insightindustry/validator-collection/branch/v.1.1.0/graph/badge.svg
          :target: https://codecov.io/gh/insightindustry/validator-collection
          :alt: Code Coverage Status (Codecov)

       .. image:: https://readthedocs.org/projects/validator-collection/badge/?version=v.1.1.0
          :target: http://validator-collection.readthedocs.io/en/latest/?badge=v.1.1.0
          :alt: Documentation Status (ReadTheDocs)

   * - `v. 1.0 <https://github.com/insightindustry/validator-collection/tree/v1-0-0>`_
     -
       .. image:: https://travis-ci.org/insightindustry/validator-collection.svg?branch=v.1.0.0
          :target: https://travis-ci.org/insightindustry/validator-collection
          :alt: Build Status (Travis CI)

       .. image:: https://codecov.io/gh/insightindustry/validator-collection/branch/v.1.0.0/graph/badge.svg
          :target: https://codecov.io/gh/insightindustry/validator-collection
          :alt: Code Coverage Status (Codecov)

       .. image:: https://readthedocs.org/projects/validator-collection/badge/?version=v.1.0.0
          :target: http://validator-collection.readthedocs.io/en/latest/?badge=v.1.0.0
          :alt: Documentation Status (ReadTheDocs)

   * - `develop <https://github.com/insightindustry/validator-collection/tree/develop>`_
     -
       .. image:: https://travis-ci.org/insightindustry/validator-collection.svg?branch=develop
          :target: https://travis-ci.org/insightindustry/validator-collection
          :alt: Build Status (Travis CI)

       .. image:: https://codecov.io/gh/insightindustry/validator-collection/branch/develop/graph/badge.svg
          :target: https://codecov.io/gh/insightindustry/validator-collection
          :alt: Code Coverage Status (Codecov)

       .. image:: https://readthedocs.org/projects/validator-collection/badge/?version=develop
          :target: http://validator-collection.readthedocs.io/en/latest/?badge=develop
          :alt: Documentation Status (ReadTheDocs)


The **Validator Collection** is a Python library that provides more than 60
functions that can be used to validate the type and contents of an input value.

Each function has a consistent syntax for easy use, and has been tested on
Python 2.7, 3.4, 3.5, 3.6, 3.7, and 3.8.

For a list of validators available, please see the lists below.

**COMPLETE DOCUMENTATION ON READTHEDOCS:** http://validator-collection.readthedocs.io/en/latest

------

.. contents:: Contents
  :local:
  :depth: 3
  :backlinks: entry

--------

***************
Installation
***************

To install the **Validator Collection**, just execute:

.. code:: bash

  $ pip install validator-collection

**Dependencies:**

.. list-table::
  :widths: 50 50
  :header-rows: 1

  * - Python 3.x
    - Python 2.7
  * - `jsonschema <https://pypi.org/project/jsonschema/>`_ for JSON Schema Validation.
    - `jsonschema <https://pypi.org/project/jsonschema/>`_ for JSON Schema Validation.

      The `regex <https://pypi.python.org/pypi/regex>`_ drop-in replacement for
      Python's (buggy) standard ``re`` module.

      Conditional dependencies will be automatically installed if you are
      installing to Python 2.x.

-------

***********************************
Available Validators and Checkers
***********************************

Validators
=============

**SEE:** `Validator Reference <http://validator-collection.readthedocs.io/en/latest/validators.html>`_

.. list-table::
  :widths: 30 30 30 30 30
  :header-rows: 1

  * - Core
    - Date/Time
    - Numbers
    - File-related
    - Internet-related
  * - ``dict``
    - ``date``
    - ``numeric``
    - ``bytesIO``
    - ``email``
  * - ``json``
    - ``datetime``
    - ``integer``
    - ``stringIO``
    - ``url``
  * - ``string``
    - ``time``
    - ``float``
    - ``path``
    - ``domain``
  * - ``iterable``
    - ``timezone``
    - ``fraction``
    - ``path_exists``
    - ``ip_address``
  * - ``none``
    - ``timedelta``
    - ``decimal``
    - ``file_exists``
    - ``ipv4``
  * - ``not_empty``
    -
    -
    - ``directory_exists``
    - ``ipv6``
  * - ``uuid``
    -
    -
    - ``readable``
    - ``mac_address``
  * - ``variable_name``
    -
    -
    - ``writeable``
    - ``mimetype``
  * -
    -
    -
    - ``executable``
    -

Checkers
==========

**SEE:** `Checker Reference <http://validator-collection.readthedocs.io/en/latest/checkers.html>`_

.. list-table::
  :widths: 30 30 30 30 30
  :header-rows: 1

  * - Core
    - Date/Time
    - Numbers
    - File-related
    - Internet-related
  * - ``is_type``
    - ``is_date``
    - ``is_numeric``
    - ``is_bytesIO``
    - ``is_email``
  * - ``is_between``
    - ``is_datetime``
    - ``is_integer``
    - ``is_stringIO``
    - ``is_url``
  * - ``has_length``
    - ``is_time``
    - ``is_float``
    - ``is_pathlike``
    - ``is_domain``
  * - ``are_equivalent``
    - ``is_timezone``
    - ``is_fraction``
    - ``is_on_filesystem``
    - ``is_ip_address``
  * - ``are_dicts_equivalent``
    - ``is_timedelta``
    - ``is_decimal``
    - ``is_file``
    - ``is_ipv4``
  * - ``is_dict``
    -
    -
    - ``is_directory``
    - ``is_ipv6``
  * - ``is_json``
    -
    -
    - ``is_readable``
    - ``is_mac_address``
  * - ``is_string``
    -
    -
    - ``is_writeable``
    - ``is_mimetype``
  * - ``is_iterable``
    -
    -
    - ``is_executable``
    -
  * - ``is_not_empty``
    -
    -
    -
    -
  * - ``is_none``
    -
    -
    -
    -
  * - ``is_callable``
    -
    -
    -
    -
  * - ``is_uuid``
    -
    -
    -
    -
  * - ``is_variable_name``
    -
    -
    -
    -

-----

************************************
Hello, World and Standard Usage
************************************

All validator functions have a consistent syntax so that using them is pretty
much identical. Here's how it works:

.. code-block:: python

  from validator_collection import validators, checkers, errors

  email_address = validators.email('test@domain.dev')
  # The value of email_address will now be "test@domain.dev"

  email_address = validators.email('this-is-an-invalid-email')
  # Will raise a ValueError

  try:
      email_address = validators.email(None)
      # Will raise an EmptyValueError
  except errors.EmptyValueError:
      # Handling logic goes here
  except errors.InvalidEmailError:
      # More handlign logic goes here

  email_address = validators.email(None, allow_empty = True)
  # The value of email_address will now be None

  email_address = validators.email('', allow_empty = True)
  # The value of email_address will now be None

  is_email_address = checkers.is_email('test@domain.dev')
  # The value of is_email_address will now be True

  is_email_address = checkers.is_email('this-is-an-invalid-email')
  # The value of is_email_address will now be False

  is_email_address = checkers.is_email(None)
  # The value of is_email_address will now be False

Pretty simple, right? Let's break it down just in case: Each validator comes in
two flavors: a validator and a checker.

.. _validators-explained:

Using Validators
==================

**SEE:** `Validator Reference <http://validator-collection.readthedocs.io/en/latest/validators.html>`_

A validator does what it says on the tin: It validates that an input value is
what you think it should be, and returns its valid form.

Each validator is expressed as the name of the thing being validated, for example
``email()``.

Each validator accepts a value as its first argument, and an optional ``allow_empty``
boolean as its second argument. For example:

.. code-block:: python

  email_address = validators.email(value, allow_empty = True)

If the value you're validating validates successfully, it will be returned. If
the value you're validating needs to be coerced to a different type, the
validator will try to do that. So for example:

.. code-block:: python

  validators.integer(1)
  validators.integer('1')

will both return an ``int`` of ``1``.

If the value you're validating is empty/falsey and ``allow_empty`` is ``False``,
then the validator will raise a ``EmptyValueError`` exception (which inherits from
the built-in ``ValueError``). If ``allow_empty`` is ``True``, then an empty/falsey
input value will be converted to a ``None`` value.

**CAUTION:** By default, ``allow_empty`` is always set to ``False``.

**HINT:** Some validators (particularly numeric ones like ``integer``) have additional
options which are used to make sure the value meets criteria that you set for
it. These options are always included as keyword arguments *after* the
``allow_empty`` argument, and are documented for each validator below.

When Validation Fails
-----------------------

Validators raise exceptions when validation fails. All exceptions raised inherit
from built-in exceptions like ``ValueError``, ``TypeError``, and ``IOError``.

If the value you're validating fails its validation for some reason, the validator
may raise different exceptions depending on the reason. In most cases, this will
be a descendent of ``ValueError`` though it can sometimes be a
``TypeError``, or an ``IOError``, etc.

For specifics on each validator's likely exceptions and what can cause them, please
review the
`Validator Reference <http://validator-collection.readthedocs.io/en/latest/validators.html>`_

**HINT:** While validators will always raise built-in exceptions from the standard library,
to give you greater programmatic control over how to respond when validation
fails, we have defined a set of custom exceptions that inherit from those
built-ins.

Our custom exceptions provide you with very specific, fine-grained information
as to *why* validation for a given value failed. In general, most validators
will raise ``ValueError`` or ``TypeError`` exceptions, and you can safely catch those
and be fine. But if you want to handle specific types of situations with greater
control, then you can instead catch ``EmptyValueError``, ``CannotCoerceError``,
``MaximumValueError``, and the like.

For more detailed information, please see:

* `Error Reference <http://validator-collection.readthedocs.io/en/latest/errors.html>`_
* `Validator Reference <http://validator-collection.readthedocs.io/en/latest/validators.html>`_

Disabling Validation
----------------------

**CAUTION:**  If you are `disabling validators <#disabling-validation>`_ using the
``VALIDATORS_DISABLED`` environment variable, their related checkers will **also**
be disabled (meaning they will always return ``True``).

Validation can at times be an expensive (in terms of performance) operation. As
a result, there are times when you want to disable certain kinds of validation
when running in production. Using the **Validator-Collection** this is simple:

Just add the name of the validator you want disabled to the ``VALIDATORS_DISABLED``
environment variable, and validation will automatically be skipped.

**CAUTION:** ``VALIDATORS_DISABLED`` expects a comma-separated list of values. If it isn't
comma-separated, it won't work properly.

Here's how it works in practice. Let's say we define the following environment
variable:

.. code-block:: bash

  $ export VALIDATORS_DISABLED = "variable_name, email, ipv4"

This disables the ``variable_name()``, ``email()``, and ``ipv4()`` validators respectively.

Now if we run:

.. code-block:: python

  from validator_collection import validators, errors

  try:
      result = validators.variable_name('this is an invalid variable name')
  except ValueError:
      # handle the error

The validator will return the ``value`` supplied to it un-changed. So that means
``result`` will be equal to ``this is an invalid variable name``.

However, if we run:

.. code-block:: python

  from validator_collection import validators, errors

  try:
      result = validators.integer('this is an invalid variable name')
  except errors.NotAnIntegerError:
      # handle the error

the validator will run and raise ``NotAnIntegerError``.

We can force validators to run (even if disabled using the environment variable)
by passing a ``force_run = True`` keyword argument. For example:

.. code-block:: python

  from validator_collection import validators, errors

  try:
      result = validators.variable_name('this is an invalid variable name',
                                        force_run = True)
  except ValueError:
      # handle the error

will produce a ``InvalidVariableNameError`` (which is a type of
``ValueError``).

.. _checkers-explained:

Using Checkers
================

Please see the `Checker Reference <http://validator-collection.readthedocs.io/en/latest/checkers.html>`_

Likewise, a checker is what it sounds like: It checks that an input value
is what you expect it to be, and tells you ``True``/``False`` whether it is or not.

**IMPORTANT:** Checkers do *not* verify or convert object types. You can think of a checker as
a tool that tells you whether its corresponding `validator <#using-validators>`_
would fail. See `Best Practices <#best-practices>`_ for tips and tricks on
using the two together.

Each checker is expressed as the name of the thing being validated, prefixed by
``is_``. So the checker for an email address is ``is_email()`` and the checker
for an integer is ``is_integer()``.

Checkers take the input value you want to check as their first (and often only)
positional argumet. If the input value validates, they will return ``True``. Unlike
`validators <#using-validators>`_, checkers will not raise an exception if
validation fails. They will instead return ``False``.

**HINT:** If you need to know *why* a given value failed to validate, use the validator
instead.

**HINT:** Some checkers (particularly numeric ones like ``is_integer()``) have additional
options which are used to make sure the value meets criteria that you set for
it. These options are always *optional* and are included as keyword arguments
*after* the input value argument. For details, please see the
`Checker Reference <http://validator-collection.readthedocs.io/en/latest/checkers.html>`_.

Disabling Checking
----------------------

**CAUTION:**  If you are disabling validators using the ``VALIDATORS_DISABLED``
environment variable, their related checkers will **also** be disabled. This means
they will always return ``True`` unless called with ``force_run = True``.

Checking can at times be an expensive (in terms of performance) operation. As
a result, there are times when you want to disable certain kinds of checking
when running in production. Using the **Validator-Collection** this is simple:

Just add the name of the checker you want disabled to the ``CHECKERS_DISABLED``
environment variable, and validation will automatically be skipped.

**CAUTION:** ``CHECKERS_DISABLED`` expects a comma-separated list of values. If
it isn't comma-separated, it won't work properly.

Here's how it works in practice. Let's say we define the following environment
variable:

.. code-block:: bash

  $ export CHECKERS_DISABLED = "is_variable_name, is_email, is_ipv4"

This disables the ``is_variable_name()``, ``is_email()``, and ``is_ipv4()``
checkers respectively.

Now if we run:

.. code-block:: python

  from validator_collection import checkers

  result = checkers.is_variable_name('this is an invalid variable name')
  # result will be True

The checker will return ``True``.

However, if we run:

.. code-block:: python

  from validator_collection import checkers

  result = validators.is_integer('this is an invalid variable name')
  # result will be False

the checker will return ``False``

We can force checkers to run (even if disabled using the environment variable)
by passing a ``force_run = True`` keyword argument. For example:

.. code-block:: python

  from validator_collection import checkers

  result = checkers.is_variable_name('this is an invalid variable name',
                                     force_run = True)
  # result will be False

will return ``False``.

.. _best-practices:

------

*****************
Best Practices
*****************

`Checkers <#using-checkers>`_ and `Validators <#using-validators>`_
are designed to be used together. You can think of them as a way to quickly and
easily verify that a value contains the information you expect, and then make
sure that value is in the form your code needs it in.

There are two fundamental patterns that we find work well in practice.

Defensive Approach: Check, then Convert if Necessary
=======================================================

We find this pattern is best used when we don't have any certainty over a given
value might contain. It's fundamentally defensive in nature, and applies the
following logic:

#. Check whether ``value`` contains the information we need it to or can be
   converted to the form we need it in.
#. If ``value`` does not contain what we need but *can* be converted to what
   we need, do the conversion.
#. If ``value`` does not contain what we need but *cannot* be converted to what
   we need, raise an error (or handle it however it needs to be handled).

We tend to use this where we're first receiving data from outside of our control,
so when we get data from a user, from the internet, from a third-party API, etc.

Here's a quick example of how that might look in code:

.. code-block:: python

  from validator_collection import checkers, validators

  def some_function(value):
      # Check whether value contains a whole number.
      is_valid = checkers.is_integer(value,
                                     coerce_value = False)

      # If the value does not contain a whole number, maybe it contains a
      # numeric value that can be rounded up to a whole number.
      if not is_valid and checkers.is_integer(value, coerce_value = True):
          # If the value can be rounded up to a whole number, then do so:
          value = validators.integer(value, coerce_value = True)
      elif not is_valid:
          # Since the value does not contain a whole number and cannot be converted to
          # one, this is where your code to handle that error goes.
          raise ValueError('something went wrong!')

      return value

  value = some_function(3.14)
  # value will now be 4

  new_value = some_function('not-a-number')
  # will raise ValueError

Let's break down what this code does. First, we define ``some_function()`` which
takes a value. This function uses the
``is_integer()``
checker to see if ``value`` contains a whole number, regardless of its type.

If it doesn't contain a whole number, maybe it contains a numeric value that can
be rounded up to a whole number? It again uses the
``is_integer()`` to check if that's
possible. If it is, then it calls the
``integer()`` validator to coerce
``value`` to a whole number.

If it can't coerce ``value`` to a whole number? It raises a ``ValueError``.


Confident Approach: try ... except
=====================================

Sometimes, we'll have more confidence in the values that we can expect to work
with. This means that we might expect ``value`` to *generally* have the kind of
data we need to work with. This means that situations where ``value`` doesn't
contain what we need will truly be exceptional situations, and can be handled
accordingly.

In this situation, a good approach is to apply the following logic:

#. Skip a checker entirely, and just wrap the validator in a
   ``try...except`` block.

We tend to use this in situations where we're working with data that our own
code has produced (meaning we know - generally - what we can expect, unless
something went seriously wrong).

Here's an example:

.. code-block:: python

  from validator_collection import validators, errors

  def some_function(value):
      try:
          email_address = validators.email(value, allow_empty = False)
      except errors.InvalidEmailError as error:
          # handle the error here
      except ValueError as error:
          # handle other ValueErrors here

      # do something with your new email address value

      return email_address

  email = some_function('email@domain.com')
  # This will return the email address.

  email = some_function('not-a-valid-email')
  # This will raise a ValueError that some_function() will handle.

  email = some_function(None)
  # This will raise a ValueError that some_function() will handle.

So what's this code do? It's pretty straightforward. ``some_function()`` expects
to receive a ``value`` that contains an email address. We expect that ``value``
will *typically* be an email address, and not something weird (like a number or
something). So we just try the validator - and if validation fails, we handle
the error appropriately.

----------

*********************
Questions and Issues
*********************

You can ask questions and report issues on the project's
`Github Issues Page <https://github.com/insightindustry/validator-collection/issues>`_

*********************
Contributing
*********************

We welcome contributions and pull requests! For more information, please see the
`Contributor Guide <http://validator-collection.readthedocs.io/en/latest/contributing.html>`_.

And thanks to `all those who have contributed <https://github.com/insightindustry/validator-collection/graphs/contributors>`_!

*********************
Testing
*********************

We use `TravisCI <http://travisci.org>`_ for our build automation and
`ReadTheDocs <https://readthedocs.org>`_ for our documentation.

Detailed information about our test suite and how to run tests locally can be
found in our `Testing Reference <http://validator-collection.readthedocs.io/en/latest/testing.html>`_.

**********************
License
**********************

The **Validator Collection** is made available on a **MIT License**.



            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/insightindustry/validator-collection",
    "name": "validator-collection",
    "maintainer": "",
    "docs_url": null,
    "requires_python": ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, <4",
    "maintainer_email": "",
    "keywords": "validator validate validation validators",
    "author": "Insight Industry Inc.",
    "author_email": "software@insightindustry.com",
    "download_url": "https://files.pythonhosted.org/packages/e0/18/037926fffcdb09dd9ccde56de6bbffa379270f2c8f5474857ad6c04b55f2/validator-collection-1.5.0.tar.gz",
    "platform": "",
    "description": "\n======================\nValidator Collection\n======================\n\n**Python library of 60+ commonly-used validator functions**\n\n.. list-table::\n   :widths: 10 90\n   :header-rows: 1\n\n   * - Branch\n     - Unit Tests\n   * - `latest <https://github.com/insightindustry/validator-collection/tree/master>`_\n     -\n       .. image:: https://travis-ci.org/insightindustry/validator-collection.svg?branch=master\n          :target: https://travis-ci.org/insightindustry/validator-collection\n          :alt: Build Status (Travis CI)\n\n       .. image:: https://codecov.io/gh/insightindustry/validator-collection/branch/master/graph/badge.svg\n          :target: https://codecov.io/gh/insightindustry/validator-collection\n          :alt: Code Coverage Status (Codecov)\n\n       .. image:: https://readthedocs.org/projects/validator-collection/badge/?version=latest\n          :target: http://validator-collection.readthedocs.io/en/latest/?badge=latest\n          :alt: Documentation Status (ReadTheDocs)\n\n   * - `v. 1.5 <https://github.com/insightindustry/validator-collection/tree/v.1.5.0>`_\n     -\n       .. image:: https://travis-ci.org/insightindustry/validator-collection.svg?branch=v.1.5.0\n          :target: https://travis-ci.org/insightindustry/validator-collection\n          :alt: Build Status (Travis CI)\n\n       .. image:: https://codecov.io/gh/insightindustry/validator-collection/branch/v.1.5.0/graph/badge.svg\n          :target: https://codecov.io/gh/insightindustry/validator-collection\n          :alt: Code Coverage Status (Codecov)\n\n       .. image:: https://readthedocs.org/projects/validator-collection/badge/?version=v.1.5.0\n          :target: http://validator-collection.readthedocs.io/en/latest/?badge=v.1.5.0\n          :alt: Documentation Status (ReadTheDocs)\n\n   * - `v. 1.4 <https://github.com/insightindustry/validator-collection/tree/v.1.4.2>`_\n     -\n       .. image:: https://travis-ci.org/insightindustry/validator-collection.svg?branch=v.1.4.2\n          :target: https://travis-ci.org/insightindustry/validator-collection\n          :alt: Build Status (Travis CI)\n\n       .. image:: https://codecov.io/gh/insightindustry/validator-collection/branch/v.1.4.2/graph/badge.svg\n          :target: https://codecov.io/gh/insightindustry/validator-collection\n          :alt: Code Coverage Status (Codecov)\n\n       .. image:: https://readthedocs.org/projects/validator-collection/badge/?version=v.1.4.2\n          :target: http://validator-collection.readthedocs.io/en/latest/?badge=v.1.4.2\n          :alt: Documentation Status (ReadTheDocs)\n\n   * - `v. 1.3 <https://github.com/insightindustry/validator-collection/tree/v.1.3.8>`_\n     -\n       .. image:: https://travis-ci.org/insightindustry/validator-collection.svg?branch=v.1.3.8\n          :target: https://travis-ci.org/insightindustry/validator-collection\n          :alt: Build Status (Travis CI)\n\n       .. image:: https://codecov.io/gh/insightindustry/validator-collection/branch/v.1.3.8/graph/badge.svg\n          :target: https://codecov.io/gh/insightindustry/validator-collection\n          :alt: Code Coverage Status (Codecov)\n\n       .. image:: https://readthedocs.org/projects/validator-collection/badge/?version=v.1.3.8\n          :target: http://validator-collection.readthedocs.io/en/latest/?badge=v.1.3.8\n          :alt: Documentation Status (ReadTheDocs)\n\n   * - `v. 1.2 <https://github.com/insightindustry/validator-collection/tree/v.1.2.0>`_\n     -\n       .. image:: https://travis-ci.org/insightindustry/validator-collection.svg?branch=v.1.2.0\n          :target: https://travis-ci.org/insightindustry/validator-collection\n          :alt: Build Status (Travis CI)\n\n       .. image:: https://codecov.io/gh/insightindustry/validator-collection/branch/v.1.2.0/graph/badge.svg\n          :target: https://codecov.io/gh/insightindustry/validator-collection\n          :alt: Code Coverage Status (Codecov)\n\n       .. image:: https://readthedocs.org/projects/validator-collection/badge/?version=v.1.2.0\n          :target: http://validator-collection.readthedocs.io/en/latest/?badge=v.1.2.0\n          :alt: Documentation Status (ReadTheDocs)\n\n   * - `v. 1.1 <https://github.com/insightindustry/validator-collection/tree/v.1.1.0>`_\n     -\n       .. image:: https://travis-ci.org/insightindustry/validator-collection.svg?branch=v.1.1.0\n          :target: https://travis-ci.org/insightindustry/validator-collection\n          :alt: Build Status (Travis CI)\n\n       .. image:: https://codecov.io/gh/insightindustry/validator-collection/branch/v.1.1.0/graph/badge.svg\n          :target: https://codecov.io/gh/insightindustry/validator-collection\n          :alt: Code Coverage Status (Codecov)\n\n       .. image:: https://readthedocs.org/projects/validator-collection/badge/?version=v.1.1.0\n          :target: http://validator-collection.readthedocs.io/en/latest/?badge=v.1.1.0\n          :alt: Documentation Status (ReadTheDocs)\n\n   * - `v. 1.0 <https://github.com/insightindustry/validator-collection/tree/v1-0-0>`_\n     -\n       .. image:: https://travis-ci.org/insightindustry/validator-collection.svg?branch=v.1.0.0\n          :target: https://travis-ci.org/insightindustry/validator-collection\n          :alt: Build Status (Travis CI)\n\n       .. image:: https://codecov.io/gh/insightindustry/validator-collection/branch/v.1.0.0/graph/badge.svg\n          :target: https://codecov.io/gh/insightindustry/validator-collection\n          :alt: Code Coverage Status (Codecov)\n\n       .. image:: https://readthedocs.org/projects/validator-collection/badge/?version=v.1.0.0\n          :target: http://validator-collection.readthedocs.io/en/latest/?badge=v.1.0.0\n          :alt: Documentation Status (ReadTheDocs)\n\n   * - `develop <https://github.com/insightindustry/validator-collection/tree/develop>`_\n     -\n       .. image:: https://travis-ci.org/insightindustry/validator-collection.svg?branch=develop\n          :target: https://travis-ci.org/insightindustry/validator-collection\n          :alt: Build Status (Travis CI)\n\n       .. image:: https://codecov.io/gh/insightindustry/validator-collection/branch/develop/graph/badge.svg\n          :target: https://codecov.io/gh/insightindustry/validator-collection\n          :alt: Code Coverage Status (Codecov)\n\n       .. image:: https://readthedocs.org/projects/validator-collection/badge/?version=develop\n          :target: http://validator-collection.readthedocs.io/en/latest/?badge=develop\n          :alt: Documentation Status (ReadTheDocs)\n\n\nThe **Validator Collection** is a Python library that provides more than 60\nfunctions that can be used to validate the type and contents of an input value.\n\nEach function has a consistent syntax for easy use, and has been tested on\nPython 2.7, 3.4, 3.5, 3.6, 3.7, and 3.8.\n\nFor a list of validators available, please see the lists below.\n\n**COMPLETE DOCUMENTATION ON READTHEDOCS:** http://validator-collection.readthedocs.io/en/latest\n\n------\n\n.. contents:: Contents\n  :local:\n  :depth: 3\n  :backlinks: entry\n\n--------\n\n***************\nInstallation\n***************\n\nTo install the **Validator Collection**, just execute:\n\n.. code:: bash\n\n  $ pip install validator-collection\n\n**Dependencies:**\n\n.. list-table::\n  :widths: 50 50\n  :header-rows: 1\n\n  * - Python 3.x\n    - Python 2.7\n  * - `jsonschema <https://pypi.org/project/jsonschema/>`_ for JSON Schema Validation.\n    - `jsonschema <https://pypi.org/project/jsonschema/>`_ for JSON Schema Validation.\n\n      The `regex <https://pypi.python.org/pypi/regex>`_ drop-in replacement for\n      Python's (buggy) standard ``re`` module.\n\n      Conditional dependencies will be automatically installed if you are\n      installing to Python 2.x.\n\n-------\n\n***********************************\nAvailable Validators and Checkers\n***********************************\n\nValidators\n=============\n\n**SEE:** `Validator Reference <http://validator-collection.readthedocs.io/en/latest/validators.html>`_\n\n.. list-table::\n  :widths: 30 30 30 30 30\n  :header-rows: 1\n\n  * - Core\n    - Date/Time\n    - Numbers\n    - File-related\n    - Internet-related\n  * - ``dict``\n    - ``date``\n    - ``numeric``\n    - ``bytesIO``\n    - ``email``\n  * - ``json``\n    - ``datetime``\n    - ``integer``\n    - ``stringIO``\n    - ``url``\n  * - ``string``\n    - ``time``\n    - ``float``\n    - ``path``\n    - ``domain``\n  * - ``iterable``\n    - ``timezone``\n    - ``fraction``\n    - ``path_exists``\n    - ``ip_address``\n  * - ``none``\n    - ``timedelta``\n    - ``decimal``\n    - ``file_exists``\n    - ``ipv4``\n  * - ``not_empty``\n    -\n    -\n    - ``directory_exists``\n    - ``ipv6``\n  * - ``uuid``\n    -\n    -\n    - ``readable``\n    - ``mac_address``\n  * - ``variable_name``\n    -\n    -\n    - ``writeable``\n    - ``mimetype``\n  * -\n    -\n    -\n    - ``executable``\n    -\n\nCheckers\n==========\n\n**SEE:** `Checker Reference <http://validator-collection.readthedocs.io/en/latest/checkers.html>`_\n\n.. list-table::\n  :widths: 30 30 30 30 30\n  :header-rows: 1\n\n  * - Core\n    - Date/Time\n    - Numbers\n    - File-related\n    - Internet-related\n  * - ``is_type``\n    - ``is_date``\n    - ``is_numeric``\n    - ``is_bytesIO``\n    - ``is_email``\n  * - ``is_between``\n    - ``is_datetime``\n    - ``is_integer``\n    - ``is_stringIO``\n    - ``is_url``\n  * - ``has_length``\n    - ``is_time``\n    - ``is_float``\n    - ``is_pathlike``\n    - ``is_domain``\n  * - ``are_equivalent``\n    - ``is_timezone``\n    - ``is_fraction``\n    - ``is_on_filesystem``\n    - ``is_ip_address``\n  * - ``are_dicts_equivalent``\n    - ``is_timedelta``\n    - ``is_decimal``\n    - ``is_file``\n    - ``is_ipv4``\n  * - ``is_dict``\n    -\n    -\n    - ``is_directory``\n    - ``is_ipv6``\n  * - ``is_json``\n    -\n    -\n    - ``is_readable``\n    - ``is_mac_address``\n  * - ``is_string``\n    -\n    -\n    - ``is_writeable``\n    - ``is_mimetype``\n  * - ``is_iterable``\n    -\n    -\n    - ``is_executable``\n    -\n  * - ``is_not_empty``\n    -\n    -\n    -\n    -\n  * - ``is_none``\n    -\n    -\n    -\n    -\n  * - ``is_callable``\n    -\n    -\n    -\n    -\n  * - ``is_uuid``\n    -\n    -\n    -\n    -\n  * - ``is_variable_name``\n    -\n    -\n    -\n    -\n\n-----\n\n************************************\nHello, World and Standard Usage\n************************************\n\nAll validator functions have a consistent syntax so that using them is pretty\nmuch identical. Here's how it works:\n\n.. code-block:: python\n\n  from validator_collection import validators, checkers, errors\n\n  email_address = validators.email('test@domain.dev')\n  # The value of email_address will now be \"test@domain.dev\"\n\n  email_address = validators.email('this-is-an-invalid-email')\n  # Will raise a ValueError\n\n  try:\n      email_address = validators.email(None)\n      # Will raise an EmptyValueError\n  except errors.EmptyValueError:\n      # Handling logic goes here\n  except errors.InvalidEmailError:\n      # More handlign logic goes here\n\n  email_address = validators.email(None, allow_empty = True)\n  # The value of email_address will now be None\n\n  email_address = validators.email('', allow_empty = True)\n  # The value of email_address will now be None\n\n  is_email_address = checkers.is_email('test@domain.dev')\n  # The value of is_email_address will now be True\n\n  is_email_address = checkers.is_email('this-is-an-invalid-email')\n  # The value of is_email_address will now be False\n\n  is_email_address = checkers.is_email(None)\n  # The value of is_email_address will now be False\n\nPretty simple, right? Let's break it down just in case: Each validator comes in\ntwo flavors: a validator and a checker.\n\n.. _validators-explained:\n\nUsing Validators\n==================\n\n**SEE:** `Validator Reference <http://validator-collection.readthedocs.io/en/latest/validators.html>`_\n\nA validator does what it says on the tin: It validates that an input value is\nwhat you think it should be, and returns its valid form.\n\nEach validator is expressed as the name of the thing being validated, for example\n``email()``.\n\nEach validator accepts a value as its first argument, and an optional ``allow_empty``\nboolean as its second argument. For example:\n\n.. code-block:: python\n\n  email_address = validators.email(value, allow_empty = True)\n\nIf the value you're validating validates successfully, it will be returned. If\nthe value you're validating needs to be coerced to a different type, the\nvalidator will try to do that. So for example:\n\n.. code-block:: python\n\n  validators.integer(1)\n  validators.integer('1')\n\nwill both return an ``int`` of ``1``.\n\nIf the value you're validating is empty/falsey and ``allow_empty`` is ``False``,\nthen the validator will raise a ``EmptyValueError`` exception (which inherits from\nthe built-in ``ValueError``). If ``allow_empty`` is ``True``, then an empty/falsey\ninput value will be converted to a ``None`` value.\n\n**CAUTION:** By default, ``allow_empty`` is always set to ``False``.\n\n**HINT:** Some validators (particularly numeric ones like ``integer``) have additional\noptions which are used to make sure the value meets criteria that you set for\nit. These options are always included as keyword arguments *after* the\n``allow_empty`` argument, and are documented for each validator below.\n\nWhen Validation Fails\n-----------------------\n\nValidators raise exceptions when validation fails. All exceptions raised inherit\nfrom built-in exceptions like ``ValueError``, ``TypeError``, and ``IOError``.\n\nIf the value you're validating fails its validation for some reason, the validator\nmay raise different exceptions depending on the reason. In most cases, this will\nbe a descendent of ``ValueError`` though it can sometimes be a\n``TypeError``, or an ``IOError``, etc.\n\nFor specifics on each validator's likely exceptions and what can cause them, please\nreview the\n`Validator Reference <http://validator-collection.readthedocs.io/en/latest/validators.html>`_\n\n**HINT:** While validators will always raise built-in exceptions from the standard library,\nto give you greater programmatic control over how to respond when validation\nfails, we have defined a set of custom exceptions that inherit from those\nbuilt-ins.\n\nOur custom exceptions provide you with very specific, fine-grained information\nas to *why* validation for a given value failed. In general, most validators\nwill raise ``ValueError`` or ``TypeError`` exceptions, and you can safely catch those\nand be fine. But if you want to handle specific types of situations with greater\ncontrol, then you can instead catch ``EmptyValueError``, ``CannotCoerceError``,\n``MaximumValueError``, and the like.\n\nFor more detailed information, please see:\n\n* `Error Reference <http://validator-collection.readthedocs.io/en/latest/errors.html>`_\n* `Validator Reference <http://validator-collection.readthedocs.io/en/latest/validators.html>`_\n\nDisabling Validation\n----------------------\n\n**CAUTION:**  If you are `disabling validators <#disabling-validation>`_ using the\n``VALIDATORS_DISABLED`` environment variable, their related checkers will **also**\nbe disabled (meaning they will always return ``True``).\n\nValidation can at times be an expensive (in terms of performance) operation. As\na result, there are times when you want to disable certain kinds of validation\nwhen running in production. Using the **Validator-Collection** this is simple:\n\nJust add the name of the validator you want disabled to the ``VALIDATORS_DISABLED``\nenvironment variable, and validation will automatically be skipped.\n\n**CAUTION:** ``VALIDATORS_DISABLED`` expects a comma-separated list of values. If it isn't\ncomma-separated, it won't work properly.\n\nHere's how it works in practice. Let's say we define the following environment\nvariable:\n\n.. code-block:: bash\n\n  $ export VALIDATORS_DISABLED = \"variable_name, email, ipv4\"\n\nThis disables the ``variable_name()``, ``email()``, and ``ipv4()`` validators respectively.\n\nNow if we run:\n\n.. code-block:: python\n\n  from validator_collection import validators, errors\n\n  try:\n      result = validators.variable_name('this is an invalid variable name')\n  except ValueError:\n      # handle the error\n\nThe validator will return the ``value`` supplied to it un-changed. So that means\n``result`` will be equal to ``this is an invalid variable name``.\n\nHowever, if we run:\n\n.. code-block:: python\n\n  from validator_collection import validators, errors\n\n  try:\n      result = validators.integer('this is an invalid variable name')\n  except errors.NotAnIntegerError:\n      # handle the error\n\nthe validator will run and raise ``NotAnIntegerError``.\n\nWe can force validators to run (even if disabled using the environment variable)\nby passing a ``force_run = True`` keyword argument. For example:\n\n.. code-block:: python\n\n  from validator_collection import validators, errors\n\n  try:\n      result = validators.variable_name('this is an invalid variable name',\n                                        force_run = True)\n  except ValueError:\n      # handle the error\n\nwill produce a ``InvalidVariableNameError`` (which is a type of\n``ValueError``).\n\n.. _checkers-explained:\n\nUsing Checkers\n================\n\nPlease see the `Checker Reference <http://validator-collection.readthedocs.io/en/latest/checkers.html>`_\n\nLikewise, a checker is what it sounds like: It checks that an input value\nis what you expect it to be, and tells you ``True``/``False`` whether it is or not.\n\n**IMPORTANT:** Checkers do *not* verify or convert object types. You can think of a checker as\na tool that tells you whether its corresponding `validator <#using-validators>`_\nwould fail. See `Best Practices <#best-practices>`_ for tips and tricks on\nusing the two together.\n\nEach checker is expressed as the name of the thing being validated, prefixed by\n``is_``. So the checker for an email address is ``is_email()`` and the checker\nfor an integer is ``is_integer()``.\n\nCheckers take the input value you want to check as their first (and often only)\npositional argumet. If the input value validates, they will return ``True``. Unlike\n`validators <#using-validators>`_, checkers will not raise an exception if\nvalidation fails. They will instead return ``False``.\n\n**HINT:** If you need to know *why* a given value failed to validate, use the validator\ninstead.\n\n**HINT:** Some checkers (particularly numeric ones like ``is_integer()``) have additional\noptions which are used to make sure the value meets criteria that you set for\nit. These options are always *optional* and are included as keyword arguments\n*after* the input value argument. For details, please see the\n`Checker Reference <http://validator-collection.readthedocs.io/en/latest/checkers.html>`_.\n\nDisabling Checking\n----------------------\n\n**CAUTION:**  If you are disabling validators using the ``VALIDATORS_DISABLED``\nenvironment variable, their related checkers will **also** be disabled. This means\nthey will always return ``True`` unless called with ``force_run = True``.\n\nChecking can at times be an expensive (in terms of performance) operation. As\na result, there are times when you want to disable certain kinds of checking\nwhen running in production. Using the **Validator-Collection** this is simple:\n\nJust add the name of the checker you want disabled to the ``CHECKERS_DISABLED``\nenvironment variable, and validation will automatically be skipped.\n\n**CAUTION:** ``CHECKERS_DISABLED`` expects a comma-separated list of values. If\nit isn't comma-separated, it won't work properly.\n\nHere's how it works in practice. Let's say we define the following environment\nvariable:\n\n.. code-block:: bash\n\n  $ export CHECKERS_DISABLED = \"is_variable_name, is_email, is_ipv4\"\n\nThis disables the ``is_variable_name()``, ``is_email()``, and ``is_ipv4()``\ncheckers respectively.\n\nNow if we run:\n\n.. code-block:: python\n\n  from validator_collection import checkers\n\n  result = checkers.is_variable_name('this is an invalid variable name')\n  # result will be True\n\nThe checker will return ``True``.\n\nHowever, if we run:\n\n.. code-block:: python\n\n  from validator_collection import checkers\n\n  result = validators.is_integer('this is an invalid variable name')\n  # result will be False\n\nthe checker will return ``False``\n\nWe can force checkers to run (even if disabled using the environment variable)\nby passing a ``force_run = True`` keyword argument. For example:\n\n.. code-block:: python\n\n  from validator_collection import checkers\n\n  result = checkers.is_variable_name('this is an invalid variable name',\n                                     force_run = True)\n  # result will be False\n\nwill return ``False``.\n\n.. _best-practices:\n\n------\n\n*****************\nBest Practices\n*****************\n\n`Checkers <#using-checkers>`_ and `Validators <#using-validators>`_\nare designed to be used together. You can think of them as a way to quickly and\neasily verify that a value contains the information you expect, and then make\nsure that value is in the form your code needs it in.\n\nThere are two fundamental patterns that we find work well in practice.\n\nDefensive Approach: Check, then Convert if Necessary\n=======================================================\n\nWe find this pattern is best used when we don't have any certainty over a given\nvalue might contain. It's fundamentally defensive in nature, and applies the\nfollowing logic:\n\n#. Check whether ``value`` contains the information we need it to or can be\n   converted to the form we need it in.\n#. If ``value`` does not contain what we need but *can* be converted to what\n   we need, do the conversion.\n#. If ``value`` does not contain what we need but *cannot* be converted to what\n   we need, raise an error (or handle it however it needs to be handled).\n\nWe tend to use this where we're first receiving data from outside of our control,\nso when we get data from a user, from the internet, from a third-party API, etc.\n\nHere's a quick example of how that might look in code:\n\n.. code-block:: python\n\n  from validator_collection import checkers, validators\n\n  def some_function(value):\n      # Check whether value contains a whole number.\n      is_valid = checkers.is_integer(value,\n                                     coerce_value = False)\n\n      # If the value does not contain a whole number, maybe it contains a\n      # numeric value that can be rounded up to a whole number.\n      if not is_valid and checkers.is_integer(value, coerce_value = True):\n          # If the value can be rounded up to a whole number, then do so:\n          value = validators.integer(value, coerce_value = True)\n      elif not is_valid:\n          # Since the value does not contain a whole number and cannot be converted to\n          # one, this is where your code to handle that error goes.\n          raise ValueError('something went wrong!')\n\n      return value\n\n  value = some_function(3.14)\n  # value will now be 4\n\n  new_value = some_function('not-a-number')\n  # will raise ValueError\n\nLet's break down what this code does. First, we define ``some_function()`` which\ntakes a value. This function uses the\n``is_integer()``\nchecker to see if ``value`` contains a whole number, regardless of its type.\n\nIf it doesn't contain a whole number, maybe it contains a numeric value that can\nbe rounded up to a whole number? It again uses the\n``is_integer()`` to check if that's\npossible. If it is, then it calls the\n``integer()`` validator to coerce\n``value`` to a whole number.\n\nIf it can't coerce ``value`` to a whole number? It raises a ``ValueError``.\n\n\nConfident Approach: try ... except\n=====================================\n\nSometimes, we'll have more confidence in the values that we can expect to work\nwith. This means that we might expect ``value`` to *generally* have the kind of\ndata we need to work with. This means that situations where ``value`` doesn't\ncontain what we need will truly be exceptional situations, and can be handled\naccordingly.\n\nIn this situation, a good approach is to apply the following logic:\n\n#. Skip a checker entirely, and just wrap the validator in a\n   ``try...except`` block.\n\nWe tend to use this in situations where we're working with data that our own\ncode has produced (meaning we know - generally - what we can expect, unless\nsomething went seriously wrong).\n\nHere's an example:\n\n.. code-block:: python\n\n  from validator_collection import validators, errors\n\n  def some_function(value):\n      try:\n          email_address = validators.email(value, allow_empty = False)\n      except errors.InvalidEmailError as error:\n          # handle the error here\n      except ValueError as error:\n          # handle other ValueErrors here\n\n      # do something with your new email address value\n\n      return email_address\n\n  email = some_function('email@domain.com')\n  # This will return the email address.\n\n  email = some_function('not-a-valid-email')\n  # This will raise a ValueError that some_function() will handle.\n\n  email = some_function(None)\n  # This will raise a ValueError that some_function() will handle.\n\nSo what's this code do? It's pretty straightforward. ``some_function()`` expects\nto receive a ``value`` that contains an email address. We expect that ``value``\nwill *typically* be an email address, and not something weird (like a number or\nsomething). So we just try the validator - and if validation fails, we handle\nthe error appropriately.\n\n----------\n\n*********************\nQuestions and Issues\n*********************\n\nYou can ask questions and report issues on the project's\n`Github Issues Page <https://github.com/insightindustry/validator-collection/issues>`_\n\n*********************\nContributing\n*********************\n\nWe welcome contributions and pull requests! For more information, please see the\n`Contributor Guide <http://validator-collection.readthedocs.io/en/latest/contributing.html>`_.\n\nAnd thanks to `all those who have contributed <https://github.com/insightindustry/validator-collection/graphs/contributors>`_!\n\n*********************\nTesting\n*********************\n\nWe use `TravisCI <http://travisci.org>`_ for our build automation and\n`ReadTheDocs <https://readthedocs.org>`_ for our documentation.\n\nDetailed information about our test suite and how to run tests locally can be\nfound in our `Testing Reference <http://validator-collection.readthedocs.io/en/latest/testing.html>`_.\n\n**********************\nLicense\n**********************\n\nThe **Validator Collection** is made available on a **MIT License**.\n\n\n",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "Collection of 60+ Python functions for validating data",
    "version": "1.5.0",
    "project_urls": {
        "Bug Reports": "https://github.com/insightindustry/validator-collection/issues",
        "Documentation": "http://validator-collection.readthedocs.io/en/latest",
        "Homepage": "https://github.com/insightindustry/validator-collection",
        "Source": "https://github.com/insightindustry/validator-collection/"
    },
    "split_keywords": [
        "validator",
        "validate",
        "validation",
        "validators"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "4ccb051b87d913beb43f7890b16e421965a1550d791637629893a7448bb2b832",
                "md5": "b1f505232547c5478271b3f5fd7cc46f",
                "sha256": "56f6dc65d86c2e5b8f04f22acedd33af2c233edc1082fe4d24fd3996bd19d0fe"
            },
            "downloads": -1,
            "filename": "validator_collection-1.5.0-py2.py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "b1f505232547c5478271b3f5fd7cc46f",
            "packagetype": "bdist_wheel",
            "python_version": "py2.py3",
            "requires_python": ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, <4",
            "size": 36418,
            "upload_time": "2020-10-12T17:24:20",
            "upload_time_iso_8601": "2020-10-12T17:24:20.021709Z",
            "url": "https://files.pythonhosted.org/packages/4c/cb/051b87d913beb43f7890b16e421965a1550d791637629893a7448bb2b832/validator_collection-1.5.0-py2.py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "e018037926fffcdb09dd9ccde56de6bbffa379270f2c8f5474857ad6c04b55f2",
                "md5": "5aafda85b0337812facc63ee4c1c4adc",
                "sha256": "f9395cad9a30cb9864fa0c0d18a84daead1eb8807774f4e09f588f89b7dc77d8"
            },
            "downloads": -1,
            "filename": "validator-collection-1.5.0.tar.gz",
            "has_sig": false,
            "md5_digest": "5aafda85b0337812facc63ee4c1c4adc",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, <4",
            "size": 46010,
            "upload_time": "2020-10-12T17:24:21",
            "upload_time_iso_8601": "2020-10-12T17:24:21.666565Z",
            "url": "https://files.pythonhosted.org/packages/e0/18/037926fffcdb09dd9ccde56de6bbffa379270f2c8f5474857ad6c04b55f2/validator-collection-1.5.0.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2020-10-12 17:24:21",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "insightindustry",
    "github_project": "validator-collection",
    "travis_ci": true,
    "coveralls": false,
    "github_actions": true,
    "requirements": [
        {
            "name": "alabaster",
            "specs": [
                [
                    "==",
                    "0.7.10"
                ]
            ]
        },
        {
            "name": "attrs",
            "specs": [
                [
                    "==",
                    "17.4.0"
                ]
            ]
        },
        {
            "name": "Babel",
            "specs": [
                [
                    "==",
                    "2.5.3"
                ]
            ]
        },
        {
            "name": "certifi",
            "specs": [
                [
                    "==",
                    "2018.1.18"
                ]
            ]
        },
        {
            "name": "cffi",
            "specs": [
                [
                    ">=",
                    "1.11.5"
                ]
            ]
        },
        {
            "name": "chardet",
            "specs": [
                [
                    "==",
                    "3.0.4"
                ]
            ]
        },
        {
            "name": "codecov",
            "specs": [
                [
                    "==",
                    "2.0.15"
                ]
            ]
        },
        {
            "name": "colorama",
            "specs": [
                [
                    "==",
                    "0.4.0"
                ]
            ]
        },
        {
            "name": "coverage",
            "specs": [
                [
                    "==",
                    "4.5.2"
                ]
            ]
        },
        {
            "name": "docutils",
            "specs": [
                [
                    "==",
                    "0.14"
                ]
            ]
        },
        {
            "name": "filelock",
            "specs": [
                [
                    "==",
                    "3.0.10"
                ]
            ]
        },
        {
            "name": "html5lib",
            "specs": [
                [
                    "==",
                    "1.0.1"
                ]
            ]
        },
        {
            "name": "idna",
            "specs": [
                [
                    "==",
                    "2.7"
                ]
            ]
        },
        {
            "name": "imagesize",
            "specs": [
                [
                    "==",
                    "1.1.0"
                ]
            ]
        },
        {
            "name": "isort",
            "specs": [
                [
                    "==",
                    "4.3.4"
                ]
            ]
        },
        {
            "name": "Jinja2",
            "specs": [
                [
                    "==",
                    "2.10.1"
                ]
            ]
        },
        {
            "name": "jsonschema",
            "specs": [
                [
                    "==",
                    "2.6.0"
                ]
            ]
        },
        {
            "name": "lazy-object-proxy",
            "specs": [
                [
                    "==",
                    "1.3.1"
                ]
            ]
        },
        {
            "name": "MarkupSafe",
            "specs": [
                [
                    "==",
                    "1.1.0"
                ]
            ]
        },
        {
            "name": "mccabe",
            "specs": [
                [
                    "==",
                    "0.6.1"
                ]
            ]
        },
        {
            "name": "more-itertools",
            "specs": [
                [
                    "==",
                    "4.3.0"
                ]
            ]
        },
        {
            "name": "packaging",
            "specs": [
                [
                    "==",
                    "18.0"
                ]
            ]
        },
        {
            "name": "pkginfo",
            "specs": [
                [
                    "==",
                    "1.4.2"
                ]
            ]
        },
        {
            "name": "pluggy",
            "specs": [
                [
                    "==",
                    "0.6.0"
                ]
            ]
        },
        {
            "name": "py",
            "specs": [
                [
                    "==",
                    "1.7.0"
                ]
            ]
        },
        {
            "name": "py-cpuinfo",
            "specs": [
                [
                    "==",
                    "4.0.0"
                ]
            ]
        },
        {
            "name": "pycparser",
            "specs": [
                [
                    "==",
                    "2.18"
                ]
            ]
        },
        {
            "name": "pyfakefs",
            "specs": [
                [
                    "==",
                    "3.5.2"
                ]
            ]
        },
        {
            "name": "Pygments",
            "specs": [
                [
                    "==",
                    "2.2.0"
                ]
            ]
        },
        {
            "name": "pyparsing",
            "specs": [
                [
                    "==",
                    "2.3.0"
                ]
            ]
        },
        {
            "name": "pytest",
            "specs": [
                [
                    "==",
                    "3.5.0"
                ]
            ]
        },
        {
            "name": "pytest-benchmark",
            "specs": [
                [
                    "==",
                    "3.1.1"
                ]
            ]
        },
        {
            "name": "pytest-cov",
            "specs": [
                [
                    "==",
                    "2.6.0"
                ]
            ]
        },
        {
            "name": "pytz",
            "specs": [
                [
                    "==",
                    "2018.4"
                ]
            ]
        },
        {
            "name": "readme-renderer",
            "specs": [
                [
                    "==",
                    "24.0"
                ]
            ]
        },
        {
            "name": "requests",
            "specs": [
                [
                    "==",
                    "2.20.1"
                ]
            ]
        },
        {
            "name": "requests-toolbelt",
            "specs": [
                [
                    "==",
                    "0.8.0"
                ]
            ]
        },
        {
            "name": "restview",
            "specs": [
                [
                    "==",
                    "2.9.1"
                ]
            ]
        },
        {
            "name": "six",
            "specs": [
                [
                    "==",
                    "1.11.0"
                ]
            ]
        },
        {
            "name": "snowballstemmer",
            "specs": [
                [
                    "==",
                    "1.2.1"
                ]
            ]
        },
        {
            "name": "Sphinx",
            "specs": [
                [
                    "==",
                    "1.8.2"
                ]
            ]
        },
        {
            "name": "sphinx-rtd-theme",
            "specs": [
                [
                    "==",
                    "0.4.2"
                ]
            ]
        },
        {
            "name": "sphinx-tabs",
            "specs": [
                [
                    "==",
                    "1.1.8"
                ]
            ]
        },
        {
            "name": "sphinxcontrib-websupport",
            "specs": [
                [
                    "==",
                    "1.1.0"
                ]
            ]
        },
        {
            "name": "toml",
            "specs": [
                [
                    "==",
                    "0.10.0"
                ]
            ]
        },
        {
            "name": "tox",
            "specs": [
                [
                    "==",
                    "3.5.3"
                ]
            ]
        },
        {
            "name": "tqdm",
            "specs": [
                [
                    "==",
                    "4.28.1"
                ]
            ]
        },
        {
            "name": "twine",
            "specs": [
                [
                    "==",
                    "1.12.1"
                ]
            ]
        },
        {
            "name": "urllib3",
            "specs": [
                [
                    "==",
                    "1.24.2"
                ]
            ]
        },
        {
            "name": "virtualenv",
            "specs": [
                [
                    "==",
                    "16.1.0"
                ]
            ]
        },
        {
            "name": "webencodings",
            "specs": [
                [
                    "==",
                    "0.5.1"
                ]
            ]
        },
        {
            "name": "wrapt",
            "specs": [
                [
                    "==",
                    "1.10.11"
                ]
            ]
        }
    ],
    "tox": true,
    "lcname": "validator-collection"
}
        
Elapsed time: 0.22082s