Validator Collection¶
Python library of 60+ commonly-used validator functions
Branch | Unit Tests |
---|---|
latest | |
v. 1.3 | |
v. 1.2 | |
v. 1.1 | |
v. 1.0.0 | |
develop |
Validator Reference¶
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 |
decimal |
file_exists |
ipv4 |
|
not_empty |
directory_exists |
ipv6 |
||
uuid |
readable |
mac_address |
||
variable_name |
writeable |
|||
executable |
Using Validators¶
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:
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:
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.
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 and Validator Reference.
Disabling Validation¶
Caution
If you are disabling validators 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 theVALIDATORS_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:
$ export VALIDATORS_DISABLED = "variable_name, email, ipv4"
This disables the variable_name()
,
email()
, and
ipv4()
validators respectively.
Now if we run:
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:
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:
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
).
Core¶
dict¶
-
dict
(value, allow_empty=False, json_serializer=None, **kwargs)[source]¶ Validate that
value
is adict
.Hint
If
value
is a string, this validator will assume it is a JSON object and try to convert it into adict
You can override the JSON serializer used by passing it to the
json_serializer
property. By default, will utilize the Pythonjson
encoder/decoder.Parameters: - value – The value to validate.
- allow_empty (
bool
) – IfTrue
, returnsNone
ifvalue
is empty. IfFalse
, raises aEmptyValueError
ifvalue
is empty. Defaults toFalse
. - json_serializer (callable) – The JSON encoder/decoder to use to deserialize a
string passed in
value
. If not supplied, will default to the Pythonjson
encoder/decoder.
Returns: value
/None
Return type: Raises: - EmptyValueError – if
value
is empty andallow_empty
isFalse
- CannotCoerceError – if
value
cannot be coerced to adict
- NotADictError – if
value
is not adict
json¶
-
json
(value, schema=None, allow_empty=False, json_serializer=None, **kwargs)[source]¶ Validate that
value
conforms to the supplied JSON Schema.Note
schema
supports JSON Schema Drafts 3 - 7. Unless the JSON Schema indicates the meta-schema using a$schema
property, the schema will be assumed to conform to Draft 7.Hint
If either
value
orschema
is a string, this validator will assume it is a JSON object and try to convert it into adict
.You can override the JSON serializer used by passing it to the
json_serializer
property. By default, will utilize the Pythonjson
encoder/decoder.Parameters: - value – The value to validate.
- schema – An optional JSON Schema against which
value
will be validated. - allow_empty (
bool
) – IfTrue
, returnsNone
ifvalue
is empty. IfFalse
, raises aEmptyValueError
ifvalue
is empty. Defaults toFalse
. - json_serializer (callable) – The JSON encoder/decoder to use to deserialize a
string passed in
value
. If not supplied, will default to the Pythonjson
encoder/decoder.
Returns: value
/None
Return type: Raises: - EmptyValueError – if
value
is empty andallow_empty
isFalse
- CannotCoerceError – if
value
cannot be coerced to adict
- NotJSONError – if
value
cannot be deserialized from JSON - NotJSONSchemaError – if
schema
is not a valid JSON Schema object - JSONValidationError – if
value
does not validate against the JSON Schema
string¶
-
string
(value, allow_empty=False, coerce_value=False, minimum_length=None, maximum_length=None, whitespace_padding=False, **kwargs)[source]¶ Validate that
value
is a valid string.Parameters: - value (
str
/None
) – The value to validate. - allow_empty (
bool
) – IfTrue
, returnsNone
ifvalue
is empty. IfFalse
, raises aEmptyValueError
ifvalue
is empty. Defaults toFalse
. - coerce_value (
bool
) – IfTrue
, will attempt to coercevalue
to a string if it is not already. IfFalse
, will raise aValueError
ifvalue
is not a string. Defaults toFalse
. - minimum_length (
int
) – If supplied, indicates the minimum number of characters needed to be valid. - maximum_length (
int
) – If supplied, indicates the minimum number of characters needed to be valid. - whitespace_padding (
bool
) – IfTrue
and the value is below theminimum_length
, pad the value with spaces. Defaults toFalse
.
Returns: value
/None
Return type: Raises: - EmptyValueError – if
value
is empty andallow_empty
isFalse
- CannotCoerceError – if
value
is not a valid string andcoerce_value
isFalse
- MinimumLengthError – if
minimum_length
is supplied and the length ofvalue
is less thanminimum_length
andwhitespace_padding
isFalse
- MaximumLengthError – if
maximum_length
is supplied and the length ofvalue
is more than themaximum_length
- value (
iterable¶
-
iterable
(value, allow_empty=False, forbid_literals=(<class 'str'>, <class 'bytes'>), minimum_length=None, maximum_length=None, **kwargs)[source]¶ Validate that
value
is a valid iterable.Parameters: - value – The value to validate.
- allow_empty (
bool
) – IfTrue
, returnsNone
ifvalue
is empty. IfFalse
, raises aEmptyValueError
ifvalue
is empty. Defaults toFalse
. - forbid_literals (iterable) – A collection of literals that will be considered invalid
even if they are (actually) iterable. Defaults to
str
andbytes
. - minimum_length (
int
) – If supplied, indicates the minimum number of members needed to be valid. - maximum_length (
int
) – If supplied, indicates the minimum number of members needed to be valid.
Returns: value
/None
Return type: iterable /
None
Raises: - EmptyValueError – if
value
is empty andallow_empty
isFalse
- NotAnIterableError – if
value
is not a valid iterable orNone
- MinimumLengthError – if
minimum_length
is supplied and the length ofvalue
is less thanminimum_length
andwhitespace_padding
isFalse
- MaximumLengthError – if
maximum_length
is supplied and the length ofvalue
is more than themaximum_length
none¶
-
none
(value, allow_empty=False, **kwargs)[source]¶ Validate that
value
isNone
.Parameters: Returns: Raises: NotNoneError – if
allow_empty
isFalse
andvalue
is empty but notNone
and
not_empty¶
-
not_empty
(value, allow_empty=False, **kwargs)[source]¶ Validate that
value
is not empty.Parameters: - value – The value to validate.
- allow_empty (
bool
) – IfTrue
, returnsNone
ifvalue
is empty. IfFalse
, raises aEmptyValueError
ifvalue
is empty. Defaults toFalse
.
Returns: value
/None
Raises: EmptyValueError – if
value
is empty andallow_empty
isFalse
uuid¶
-
uuid
(value, allow_empty=False, **kwargs)[source]¶ Validate that
value
is a validUUID
.Parameters: - value – The value to validate.
- allow_empty (
bool
) – IfTrue
, returnsNone
ifvalue
is empty. IfFalse
, raises aEmptyValueError
ifvalue
is empty. Defaults toFalse
.
Returns: Return type: Raises: - EmptyValueError – if
value
is empty andallow_empty
isFalse
- CannotCoerceError – if
value
cannot be coerced to aUUID
variable_name¶
-
variable_name
(value, allow_empty=False, **kwargs)[source]¶ Validate that the value is a valid Python variable name.
Caution
This function does NOT check whether the variable exists. It only checks that the
value
would work as a Python variable (or class, or function, etc.) name.Parameters: - value – The value to validate.
- allow_empty (
bool
) – IfTrue
, returnsNone
ifvalue
is empty. IfFalse
, raises aEmptyValueError
ifvalue
is empty. Defaults toFalse
.
Returns: value
/None
Return type: Raises: EmptyValueError – if
allow_empty
isFalse
andvalue
is empty
Date / Time¶
date¶
-
date
(value, allow_empty=False, minimum=None, maximum=None, coerce_value=True, **kwargs)[source]¶ Validate that
value
is a valid date.Parameters: - value (
str
/datetime
/date
/None
) – The value to validate. - allow_empty (
bool
) – IfTrue
, returnsNone
ifvalue
is empty. IfFalse
, raises aEmptyValueError
ifvalue
is empty. Defaults toFalse
. - minimum (
datetime
/date
/ compliantstr
/None
) – If supplied, will make sure thatvalue
is on or after this value. - maximum (
datetime
/date
/ compliantstr
/None
) – If supplied, will make sure thatvalue
is on or before this value. - coerce_value (
bool
) – IfTrue
, will attempt to coercevalue
to adate
if it is a timestamp value. IfFalse
, will not.
Returns: value
/None
Return type: Raises: - EmptyValueError – if
value
is empty andallow_empty
isFalse
- CannotCoerceError – if
value
cannot be coerced to adate
and is notNone
- MinimumValueError – if
minimum
is supplied butvalue
occurs beforeminimum
- MaximumValueError – if
maximum
is supplied butvalue
occurs aftermaximum
- value (
datetime¶
-
datetime
(value, allow_empty=False, minimum=None, maximum=None, coerce_value=True, **kwargs)[source]¶ Validate that
value
is a valid datetime.Caution
If supplying a string, the string needs to be in an ISO 8601-format to pass validation. If it is not in an ISO 8601-format, validation will fail.
Parameters: - value (
str
/datetime
/date
/None
) – The value to validate. - allow_empty (
bool
) – IfTrue
, returnsNone
ifvalue
is empty. IfFalse
, raises aEmptyValueError
ifvalue
is empty. Defaults toFalse
. - minimum (
datetime
/date
/ compliantstr
/None
) – If supplied, will make sure thatvalue
is on or after this value. - maximum (
datetime
/date
/ compliantstr
/None
) – If supplied, will make sure thatvalue
is on or before this value. - coerce_value (
bool
) – IfTrue
, will coerce dates todatetime
objects with times of 00:00:00. IfFalse
, will error ifvalue
is not an unambiguous timestamp. Defaults toTrue
.
Returns: value
/None
Return type: Raises: - EmptyValueError – if
value
is empty andallow_empty
isFalse
- CannotCoerceError – if
value
cannot be coerced to adatetime
value and is notNone
- MinimumValueError – if
minimum
is supplied butvalue
occurs beforeminimum
- MaximumValueError – if
maximum
is supplied butvalue
occurs afterminimum
- value (
time¶
-
time
(value, allow_empty=False, minimum=None, maximum=None, coerce_value=True, **kwargs)[source]¶ Validate that
value
is a validtime
.Caution
This validator will always return the time as timezone naive (effectively UTC). If
value
has a timezone / UTC offset applied, the validator will coerce the value returned back to UTC.Parameters: - value (
datetime
ortime
-compliantstr
/datetime
/time
) – The value to validate. - allow_empty (
bool
) – IfTrue
, returnsNone
ifvalue
is empty. IfFalse
, raises aEmptyValueError
ifvalue
is empty. Defaults toFalse
. - minimum (
datetime
ortime
-compliantstr
/datetime
/time
) – If supplied, will make sure thatvalue
is on or after this value. - maximum (
datetime
ortime
-compliantstr
/datetime
/time
) – If supplied, will make sure thatvalue
is on or before this value. - coerce_value (
bool
) – IfTrue
, will attempt to coerce/extract atime
fromvalue
. IfFalse
, will only respect direct representations of time. Defaults toTrue
.
Returns: value
in UTC time /None
Return type: Raises: - EmptyValueError – if
value
is empty andallow_empty
isFalse
- CannotCoerceError – if
value
cannot be coerced to atime
and is notNone
- MinimumValueError – if
minimum
is supplied butvalue
occurs beforeminimum
- MaximumValueError – if
maximum
is supplied butvalue
occurs afterminimum
- value (
timezone¶
-
timezone
(value, allow_empty=False, positive=True, **kwargs)[source]¶ Validate that
value
is a validtzinfo
.Caution
This does not verify whether the value is a timezone that actually exists, nor can it resolve timezone names (e.g.
'Eastern'
or'CET'
).For that kind of functionality, we recommend you utilize: pytz
Parameters: - value (
str
/tzinfo
/ numeric /None
) – The value to validate. - allow_empty (
bool
) – IfTrue
, returnsNone
ifvalue
is empty. IfFalse
, raises aEmptyValueError
ifvalue
is empty. Defaults toFalse
. - positive (
bool
) – Indicates whether thevalue
is positive or negative (only has meaning ifvalue
is a string). Defaults toTrue
.
Returns: value
/None
Return type: Raises: - EmptyValueError – if
value
is empty andallow_empty
isFalse
- CannotCoerceError – if
value
cannot be coerced totzinfo
and is notNone
- PositiveOffsetMismatchError – if
positive
isTrue
, but the offset indicated byvalue
is actually negative - NegativeOffsetMismatchError – if
positive
isFalse
, but the offset indicated byvalue
is actually positive
- value (
Numbers¶
Note
Because Python’s None
is implemented as an integer
value, numeric validators do not check “falsiness”. Doing so would find
false positives if value
were set to 0
.
Instead, all numeric validators explicitly check for the Python global singleton
None
.
numeric¶
-
numeric
(value, allow_empty=False, minimum=None, maximum=None, **kwargs)[source]¶ Validate that
value
is a numeric value.Parameters: - value – The value to validate.
- allow_empty (
bool
) – IfTrue
, returnsNone
ifvalue
isNone
. IfFalse
, raises anEmptyValueError
ifvalue
isNone
. Defaults toFalse
. - minimum (numeric) – If supplied, will make sure that
value
is greater than or equal to this value. - maximum (numeric) – If supplied, will make sure that
value
is less than or equal to this value.
Returns: value
/None
Raises: - EmptyValueError – if
value
isNone
andallow_empty
isFalse
- MinimumValueError – if
minimum
is supplied andvalue
is less than theminimum
- MaximumValueError – if
maximum
is supplied andvalue
is more than themaximum
- CannotCoerceError – if
value
cannot be coerced to a numeric form
integer¶
-
integer
(value, allow_empty=False, coerce_value=False, minimum=None, maximum=None, base=10, **kwargs)[source]¶ Validate that
value
is anint
.Parameters: - value – The value to validate.
- allow_empty (
bool
) – IfTrue
, returnsNone
ifvalue
isNone
. IfFalse
, raises aEmptyValueError
ifvalue
isNone
. Defaults toFalse
. - coerce_value (
bool
) – IfTrue
, will force any numericvalue
to an integer (always rounding up). IfFalse
, will raise an error ifvalue
is numeric but not a whole number. Defaults toFalse
. - minimum (numeric) – If supplied, will make sure that
value
is greater than or equal to this value. - maximum (numeric) – If supplied, will make sure that
value
is less than or equal to this value. - base – Indicates the base that is used to determine the integer value.
The allowed values are 0 and 2–36. Base-2, -8, and -16 literals can be
optionally prefixed with
0b/0B
,0o/0O/0
, or0x/0X
, as with integer literals in code. Base 0 means to interpret the string exactly as an integer literal, so that the actual base is 2, 8, 10, or 16. Defaults to10
.
Returns: value
/None
Raises: - EmptyValueError – if
value
isNone
andallow_empty
isFalse
- MinimumValueError – if
minimum
is supplied andvalue
is less than theminimum
- MaximumValueError – if
maximum
is supplied andvalue
is more than themaximum
- NotAnIntegerError – if
coerce_value
isFalse
, andvalue
is not an integer - CannotCoerceError – if
value
cannot be coerced to anint
float¶
-
float
(value, allow_empty=False, minimum=None, maximum=None, **kwargs)[source]¶ Validate that
value
is afloat
.Parameters: - value – The value to validate.
- allow_empty (
bool
) – IfTrue
, returnsNone
ifvalue
isNone
. IfFalse
, raises aEmptyValueError
ifvalue
isNone
. Defaults toFalse
.
Returns: value
/None
Return type: Raises: - EmptyValueError – if
value
isNone
andallow_empty
isFalse
- MinimumValueError – if
minimum
is supplied andvalue
is less than theminimum
- MaximumValueError – if
maximum
is supplied andvalue
is more than themaximum
- CannotCoerceError – if unable to coerce
value
to afloat
fraction¶
-
fraction
(value, allow_empty=False, minimum=None, maximum=None, **kwargs)[source]¶ Validate that
value
is aFraction
.Parameters: - value – The value to validate.
- allow_empty (
bool
) – IfTrue
, returnsNone
ifvalue
isNone
. IfFalse
, raises aEmptyValueError
ifvalue
isNone
. Defaults toFalse
.
Returns: value
/None
Return type: Raises: - EmptyValueError – if
value
isNone
andallow_empty
isFalse
- MinimumValueError – if
minimum
is supplied andvalue
is less than theminimum
- MaximumValueError – if
maximum
is supplied andvalue
is more than themaximum
- CannotCoerceError – if unable to coerce
value
to aFraction
decimal¶
-
decimal
(value, allow_empty=False, minimum=None, maximum=None, **kwargs)[source]¶ Validate that
value
is aDecimal
.Parameters: - value – The value to validate.
- allow_empty (
bool
) – IfTrue
, returnsNone
ifvalue
isNone
. IfFalse
, raises aEmptyValueError
ifvalue
isNone
. Defaults toFalse
. - minimum (numeric) – If supplied, will make sure that
value
is greater than or equal to this value. - maximum (numeric) – If supplied, will make sure that
value
is less than or equal to this value.
Returns: value
/None
Return type: Raises: - EmptyValueError – if
value
isNone
andallow_empty
isFalse
- MinimumValueError – if
minimum
is supplied andvalue
is less than theminimum
- MaximumValueError – if
maximum
is supplied andvalue
is more than themaximum
- CannotCoerceError – if unable to coerce
value
to aDecimal
Checker Reference¶
Using Checkers¶
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 would fail. See 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, 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.
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 you
call them using 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 theCHECKERS_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:
$ export CHECKERS_DISABLED = "is_variable_name, is_email, is_ipv4"
This disables the is_variable_name()
,
is_email()
, and
is_ipv4()
validators respectively.
Now if we run:
from validator_collection import checkers, errors
result = checkers.is_variable_name('this is an invalid variable name')
# result will be True
The checker will return True
.
However, if we run:
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:
from validator_collection import checkers, errors
result = checkers.is_variable_name('this is an invalid variable name',
force_run = True)
# result will be False
will return False
.
Core¶
is_type¶
-
is_type
(obj, type_, **kwargs)[source]¶ Indicate if
obj
is a type intype_
.Hint
This checker is particularly useful when you want to evaluate whether
obj
is of a particular type, but importing that type directly to use inisinstance()
would cause a circular import error.To use this checker in that kind of situation, you can instead pass the name of the type you want to check as a string in
type_
. The checker will evaluate it and see whetherobj
is of a type or inherits from a type whose name matches the string you passed.Parameters: Returns: True
ifobj
is a type intype_
. Otherwise,False
.Return type: Raises: SyntaxError – if
kwargs
contains duplicate keyword parameters or duplicates keyword parameters passed to the underlying validator
are_equivalent¶
-
are_equivalent
(*args, **kwargs)[source]¶ Indicate if arguments passed to this function are equivalent.
Hint
This checker operates recursively on the members contained within iterables and
dict
objects.Caution
If you only pass one argument to this checker - even if it is an iterable - the checker will always return
True
.To evaluate members of an iterable for equivalence, you should instead unpack the iterable into the function like so:
obj = [1, 1, 1, 2] result = are_equivalent(*obj) # Will return ``False`` by unpacking and evaluating the iterable's members result = are_equivalent(obj) # Will always return True
Parameters: args – One or more values, passed as positional arguments. Returns: True
ifargs
are equivalent, andFalse
if not.Return type: bool
Raises: SyntaxError – if kwargs
contains duplicate keyword parameters or duplicates keyword parameters passed to the underlying validator
are_dicts_equivalent¶
-
are_dicts_equivalent
(*args, **kwargs)[source]¶ Indicate if dicts passed to this function have identical keys and values.
Parameters: args – One or more values, passed as positional arguments. Returns: True
ifargs
have identical keys/values, andFalse
if not.Return type: bool
Raises: SyntaxError – if kwargs
contains duplicate keyword parameters or duplicates keyword parameters passed to the underlying validator
is_between¶
-
is_between
(value, minimum=None, maximum=None, **kwargs)[source]¶ Indicate whether
value
is greater than or equal to a suppliedminimum
and/or less than or equal tomaximum
.Note
This function works on any
value
that support comparison operators, whether they are numbers or not. Technically, this means thatvalue
,minimum
, ormaximum
need to implement the Python magic methods__lte__
and__gte__
.If
value
,minimum
, ormaximum
do not support comparison operators, they will raiseNotImplemented
.Parameters: - value (anything that supports comparison operators) – The
value
to check. - minimum (anything that supports comparison operators /
None
) – If supplied, will returnTrue
ifvalue
is greater than or equal to this value. - maximum (anything that supports comparison operators /
None
) – If supplied, will returnTrue
ifvalue
is less than or equal to this value.
Returns: True
ifvalue
is greater than or equal to a suppliedminimum
and less than or equal to a suppliedmaximum
. Otherwise, returnsFalse
.Return type: Raises: - SyntaxError – if
kwargs
contains duplicate keyword parameters or duplicates keyword parameters passed to the underlying validator - NotImplemented – if
value
,minimum
, ormaximum
do not support comparison operators - ValueError – if both
minimum
andmaximum
areNone
- value (anything that supports comparison operators) – The
has_length¶
-
has_length
(value, minimum=None, maximum=None, **kwargs)[source]¶ Indicate whether
value
has a length greater than or equal to a suppliedminimum
and/or less than or equal tomaximum
.Note
This function works on any
value
that supports thelen()
operation. This means thatvalue
must implement the__len__
magic method.If
value
does not support length evaluation, the checker will raiseNotImplemented
.Parameters: - value (anything that supports length evaluation) – The
value
to check. - minimum (numeric) – If supplied, will return
True
ifvalue
is greater than or equal to this value. - maximum (numeric) – If supplied, will return
True
ifvalue
is less than or equal to this value.
Returns: True
ifvalue
has length greater than or equal to a suppliedminimum
and less than or equal to a suppliedmaximum
. Otherwise, returnsFalse
.Return type: Raises: - SyntaxError – if
kwargs
contains duplicate keyword parameters or duplicates keyword parameters passed to the underlying validator - TypeError – if
value
does not support length evaluation - ValueError – if both
minimum
andmaximum
areNone
- value (anything that supports length evaluation) – The
is_dict¶
-
is_dict
(value, **kwargs)[source]¶ Indicate whether
value
is a validdict
Note
This will return
True
even ifvalue
is an emptydict
.Parameters: value – The value to evaluate. Returns: True
ifvalue
is valid,False
if it is not.Return type: bool
Raises: SyntaxError – if kwargs
contains duplicate keyword parameters or duplicates keyword parameters passed to the underlying validator
is_json¶
-
is_json
(value, schema=None, json_serializer=None, **kwargs)[source]¶ Indicate whether
value
is a valid JSON object.Note
schema
supports JSON Schema Drafts 3 - 7. Unless the JSON Schema indicates the meta-schema using a$schema
property, the schema will be assumed to conform to Draft 7.Parameters: Returns: True
ifvalue
is valid,False
if it is not.Return type: Raises: SyntaxError – if
kwargs
contains duplicate keyword parameters or duplicates keyword parameters passed to the underlying validator
is_string¶
-
is_string
(value, coerce_value=False, minimum_length=None, maximum_length=None, whitespace_padding=False, **kwargs)[source]¶ Indicate whether
value
is a string.Parameters: - value – The value to evaluate.
- coerce_value (
bool
) – IfTrue
, will check whethervalue
can be coerced to a string if it is not already. Defaults toFalse
. - minimum_length (
int
) – If supplied, indicates the minimum number of characters needed to be valid. - maximum_length (
int
) – If supplied, indicates the minimum number of characters needed to be valid. - whitespace_padding (
bool
) – IfTrue
and the value is below theminimum_length
, pad the value with spaces. Defaults toFalse
.
Returns: True
ifvalue
is valid,False
if it is not.Return type: Raises: SyntaxError – if
kwargs
contains duplicate keyword parameters or duplicates keyword parameters passed to the underlying validator
is_iterable¶
-
is_iterable
(obj, forbid_literals=(<class 'str'>, <class 'bytes'>), minimum_length=None, maximum_length=None, **kwargs)[source]¶ Indicate whether
obj
is iterable.Parameters: - forbid_literals (iterable) – A collection of literals that will be considered invalid
even if they are (actually) iterable. Defaults to a
tuple
containingstr
andbytes
. - minimum_length (
int
) – If supplied, indicates the minimum number of members needed to be valid. - maximum_length (
int
) – If supplied, indicates the minimum number of members needed to be valid.
Returns: True
ifobj
is a valid iterable,False
if not.Return type: Raises: SyntaxError – if
kwargs
contains duplicate keyword parameters or duplicates keyword parameters passed to the underlying validator- forbid_literals (iterable) – A collection of literals that will be considered invalid
even if they are (actually) iterable. Defaults to a
is_not_empty¶
-
is_not_empty
(value, **kwargs)[source]¶ Indicate whether
value
is empty.Parameters: value – The value to evaluate. Returns: True
ifvalue
is empty,False
if it is not.Return type: bool
Raises: SyntaxError – if kwargs
contains duplicate keyword parameters or duplicates keyword parameters passed to the underlying validator
is_none¶
-
is_none
(value, allow_empty=False, **kwargs)[source]¶ Indicate whether
value
isNone
.Parameters: Returns: True
ifvalue
isNone
,False
if it is not.Return type: Raises: SyntaxError – if
kwargs
contains duplicate keyword parameters or duplicates keyword parameters passed to the underlying validator
is_variable_name¶
-
is_variable_name
(value, **kwargs)[source]¶ Indicate whether
value
is a valid Python variable name.Caution
This function does NOT check whether the variable exists. It only checks that the
value
would work as a Python variable (or class, or function, etc.) name.Parameters: value – The value to evaluate. Returns: True
ifvalue
is valid,False
if it is not.Return type: bool
Raises: SyntaxError – if kwargs
contains duplicate keyword parameters or duplicates keyword parameters passed to the underlying validator
is_callable¶
-
is_callable
(value, **kwargs)[source]¶ Indicate whether
value
is callable (like a function, method, or class).Parameters: value – The value to evaluate. Returns: True
ifvalue
is valid,False
if it is not.Return type: bool
Raises: SyntaxError – if kwargs
contains duplicate keyword parameters or duplicates keyword parameters passed to the underlying validator
is_uuid¶
-
is_uuid
(value, **kwargs)[source]¶ Indicate whether
value
contains aUUID
Parameters: value – The value to evaluate. Returns: True
ifvalue
is valid,False
if it is not.Return type: bool
Raises: SyntaxError – if kwargs
contains duplicate keyword parameters or duplicates keyword parameters passed to the underlying validator
Date / Time¶
is_date¶
-
is_date
(value, minimum=None, maximum=None, coerce_value=False, **kwargs)[source]¶ Indicate whether
value
is adate
.Parameters: - value – The value to evaluate.
- minimum (
datetime
/date
/ compliantstr
/None
) – If supplied, will make sure thatvalue
is on or after this value. - maximum (
datetime
/date
/ compliantstr
/None
) – If supplied, will make sure thatvalue
is on or before this value. - coerce_value (
bool
) – IfTrue
, will returnTrue
ifvalue
can be coerced to adate
. IfFalse
, will only returnTrue
ifvalue
is a date value only. Defaults toFalse
.
Returns: True
ifvalue
is valid,False
if it is not.Return type: Raises: SyntaxError – if
kwargs
contains duplicate keyword parameters or duplicates keyword parameters passed to the underlying validator
is_datetime¶
-
is_datetime
(value, minimum=None, maximum=None, coerce_value=False, **kwargs)[source]¶ Indicate whether
value
is adatetime
.Parameters: - value – The value to evaluate.
- minimum (
datetime
/date
/ compliantstr
/None
) – If supplied, will make sure thatvalue
is on or after this value. - maximum (
datetime
/date
/ compliantstr
/None
) – If supplied, will make sure thatvalue
is on or before this value. - coerce_value (
bool
) – IfTrue
, will returnTrue
ifvalue
can be coerced to adatetime
. IfFalse
, will only returnTrue
ifvalue
is a complete timestamp. Defaults toFalse
.
Returns: True
ifvalue
is valid,False
if it is not.Return type: Raises: SyntaxError – if
kwargs
contains duplicate keyword parameters or duplicates keyword parameters passed to the underlying validator
is_time¶
-
is_time
(value, minimum=None, maximum=None, coerce_value=False, **kwargs)[source]¶ Indicate whether
value
is atime
.Parameters: - value – The value to evaluate.
- minimum (
datetime
ortime
-compliantstr
/datetime
/time
) – If supplied, will make sure thatvalue
is on or after this value. - maximum (
datetime
ortime
-compliantstr
/datetime
/time
) – If supplied, will make sure thatvalue
is on or before this value. - coerce_value (
bool
) – IfTrue
, will returnTrue
ifvalue
can be coerced to atime
. IfFalse
, will only returnTrue
ifvalue
is a valid time. Defaults toFalse
.
Returns: True
ifvalue
is valid,False
if it is not.Return type: Raises: SyntaxError – if
kwargs
contains duplicate keyword parameters or duplicates keyword parameters passed to the underlying validator
is_timezone¶
-
is_timezone
(value, positive=True, **kwargs)[source]¶ Indicate whether
value
is atzinfo
.Caution
This does not validate whether the value is a timezone that actually exists, nor can it resolve timzone names (e.g.
'Eastern'
or'CET'
).For that kind of functionality, we recommend you utilize: pytz
Parameters: - value – The value to evaluate.
- positive (
bool
) – Indicates whether thevalue
is positive or negative (only has meaning ifvalue
is a string). Defaults toTrue
.
Returns: True
ifvalue
is valid,False
if it is not.Return type: Raises: SyntaxError – if
kwargs
contains duplicate keyword parameters or duplicates keyword parameters passed to the underlying validator
Numbers¶
is_numeric¶
-
is_numeric
(value, minimum=None, maximum=None, **kwargs)[source]¶ Indicate whether
value
is a numeric value.Parameters: - value – The value to evaluate.
- minimum (numeric) – If supplied, will make sure that
value
is greater than or equal to this value. - maximum (numeric) – If supplied, will make sure that
value
is less than or equal to this value.
Returns: True
ifvalue
is valid,False
if it is not.Return type: Raises: SyntaxError – if
kwargs
contains duplicate keyword parameters or duplicates keyword parameters passed to the underlying validator
is_integer¶
-
is_integer
(value, coerce_value=False, minimum=None, maximum=None, base=10, **kwargs)[source]¶ Indicate whether
value
contains a whole number.Parameters: - value – The value to evaluate.
- coerce_value (
bool
) – IfTrue
, will returnTrue
ifvalue
can be coerced to whole number. IfFalse
, will only returnTrue
ifvalue
is already a whole number (regardless of type). Defaults toFalse
. - minimum (numeric) – If supplied, will make sure that
value
is greater than or equal to this value. - maximum (numeric) – If supplied, will make sure that
value
is less than or equal to this value. - base (
int
) – Indicates the base that is used to determine the integer value. The allowed values are 0 and 2–36. Base-2, -8, and -16 literals can be optionally prefixed with0b/0B
,0o/0O/0
, or0x/0X
, as with integer literals in code. Base 0 means to interpret the string exactly as an integer literal, so that the actual base is 2, 8, 10, or 16. Defaults to10
.
Returns: True
ifvalue
is valid,False
if it is not.Return type: Raises: SyntaxError – if
kwargs
contains duplicate keyword parameters or duplicates keyword parameters passed to the underlying validator
is_float¶
-
is_float
(value, minimum=None, maximum=None, **kwargs)[source]¶ Indicate whether
value
is afloat
.Parameters: - value – The value to evaluate.
- minimum (numeric) – If supplied, will make sure that
value
is greater than or equal to this value. - maximum (numeric) – If supplied, will make sure that
value
is less than or equal to this value.
Returns: True
ifvalue
is valid,False
if it is not.Return type: Raises: SyntaxError – if
kwargs
contains duplicate keyword parameters or duplicates keyword parameters passed to the underlying validator
is_fraction¶
-
is_fraction
(value, minimum=None, maximum=None, **kwargs)[source]¶ Indicate whether
value
is aFraction
.Parameters: - value – The value to evaluate.
- minimum (numeric) – If supplied, will make sure that
value
is greater than or equal to this value. - maximum (numeric) – If supplied, will make sure that
value
is less than or equal to this value.
Returns: True
ifvalue
is valid,False
if it is not.Return type: Raises: SyntaxError – if
kwargs
contains duplicate keyword parameters or duplicates keyword parameters passed to the underlying validator
is_decimal¶
-
is_decimal
(value, minimum=None, maximum=None, **kwargs)[source]¶ Indicate whether
value
contains aDecimal
.Parameters: - value – The value to evaluate.
- minimum (numeric) – If supplied, will make sure that
value
is greater than or equal to this value. - maximum (numeric) – If supplied, will make sure that
value
is less than or equal to this value.
Returns: True
ifvalue
is valid,False
if it is not.Return type: Raises: SyntaxError – if
kwargs
contains duplicate keyword parameters or duplicates keyword parameters passed to the underlying validator
Error Reference¶
- Handling Errors
- Standard Errors
- Core
- MinimumLengthError (from
ValueError
) - MaximumLengthError (from
ValueError
) - NotNoneError (from
ValueError
) - NotADictError (from
ValueError
) - NotJSONError (from
ValueError
) - NotJSONSchemaError (from
ValueError
) - JSONValidationError (from
ValueError
) - NotAnIterableError (from
CannotCoerceError
) - NotCallableError (from
ValueError
) - InvalidVariableNameError (from
ValueError
)
- MinimumLengthError (from
- Date / Time
- Numbers
- File-related
- Internet-related
- InvalidEmailError (from
ValueError
) - InvalidURLError (from
ValueError
) - InvalidDomainError (from
ValueError
) - SlashInDomainError (from
InvalidDomainError
) - AtInDomainError (from
InvalidDomainError
) - ColonInDomainError (from
InvalidDomainError
) - WhitespaceInDomainError (from
InvalidDomainError
) - InvalidIPAddressError (from
ValueError
) - InvalidMACAddressError (from
ValueError
)
- InvalidEmailError (from
Handling Errors¶
Tip
By design, checkers never raise exceptions. If a given
value fails, a checker will just return False
.
Validators always raise exceptions when validation fails.
When validators fail, they raise exceptions. There are three ways for exceptions to provide you with information that is useful in different circumstances:
- Exception Type. The type of the exception itself (and the name of that type)
tells you a lot about the nature of the error. On its own, this should be
enough for you to understand “what went wrong” and “why validation failed”.
Most importantly, this is easy to catch in your code using
try ... except
blocks, giving you fine-grained control over how to handle exceptional situations. - Message. Each exception is raised when a human-readable message, a brief string that says “this is why this exception was raised”. This is primarily useful in debugging your code, because at run-time we don’t want to parse strings to make control flow decisions.
- Stack Trace. Each exception is raised with a stacktrace of the exceptions and calls that preceded it. This helps to provide the context for the error, and is (typically) most useful for debugging and logging purposes. In rare circumstances, we might want to programmatically parse this information…but that’s a pretty rare requirement.
We have designed the exceptions raised by the Validator-Collection to leverage all three of these types of information.
Validator Names/Types¶
By design, all exceptions raised by the Validator-Collection inherit from
the built-in exceptions
defined in the standard library. This makes it simple to plug the Validator-Collection
into existing validation code you have which already catches
ValueError
, TypeError
,
and the like.
However, because we have sub-classed the built-in exceptions, you can easily apply more fine-grained control over your code.
For example, let us imagine a validation which will fail:
from validator_collection import validators
value = validators.decimal('123.45',
allow_empty = False,
minimum = 0,
maximum = 100)
By design, we know that this value will fail validation. We have specified
a maximum
of 100, and the value being passed in is (a string) with a value of
123.45
. This will fail.
We can catch this using a standard/built-in ValueError
like so:
from validator_collection import validators
try:
value = validators.decimal('123.45',
allow_empty = False,
minimum = 0,
maximum = 100)
except ValueError as error:
# Handle the error
Looking at the documentation for
validators.decimal()
, we can
see that this will catch all of the following situations:
- when an empty/false value is passed with
allow_empty = False
,- when a value is less than the allowed minimum,
- when a value is more than the allowed maximum
But maybe we want to handle each of these situations a little differently? In that case, we can use the custom exceptions defined by the Validator-Collection:
from validator_collection import validators, errors
try:
value = validators.decimal('123.45',
allow_empty = False,
minimum = 0,
maximum = 100)
except errors.EmptyValueError as error:
# Handle the situation where an empty value was received.
except errors.MinimumValueError as error:
# Handle the situation when a value is less than the allowed minimum.
except errors.MaximumValueError as error:
# Handle the situation when a value is more than the allowed minimum.
Both approaches will work, but one gives you a little more precise control over how your code handles a failed validation.
Tip
We strongly recommend that you review the exceptions raised by each of the Validator Reference you use. Each validator precisely documents which exceptions it raises, and each exception’s documentation shows what built-in exceptions it inherits from.
Validator Messages¶
Because the Validator-Collection produces exceptions which inherit from the standard library, we leverage the same API. This means they print to standard output with a human-readable message that provides an explanation for “what went wrong.”
Stack Traces¶
Because the Validator-Collection produces exceptions which inherit from the standard library, it leverages the same API for handling stack trace information. This means that it will be handled just like a normal exception in unit test frameworks, logging solutions, and other tools that might need that information.
Standard Errors¶
EmptyValueError (from ValueError
)¶
-
class
EmptyValueError
[source]¶ Exception raised when an empty value is detected, but the validator does not allow for empty values.
Note
While in general, an “empty” value means a value that is falsey, for certain specific validators “empty” means explicitly
None
.Please see: Validator Reference.
INHERITS FROM:
ValueError
MinimumValueError (from ValueError
)¶
-
class
MinimumValueError
[source]¶ Exception raised when a value has a lower or earlier value than the minimum allowed.
INHERITS FROM:
ValueError
MaximumValueError (from ValueError
)¶
-
class
MaximumValueError
[source]¶ Exception raised when a value exceeds a maximum allowed value.
INHERITS FROM:
ValueError
ValidatorUsageError (from ValueError
)¶
-
class
ValidatorUsageError
[source]¶ Exception raised when the validator was used incorrectly.
INHERITS FROM:
ValueError
CoercionFunctionEmptyError (from ValidatorUsageError
)¶
-
class
CoercionFunctionEmptyError
[source]¶ Exception raised when a coercion function was empty.
INHERITS FROM:
ValueError
->ValidatorUsageError
CoercionFunctionError (from ValueError
)¶
-
class
CoercionFunctionError
[source]¶ Exception raised when a Coercion Function produces an
Exception
.INHERITS FROM:
ValueError
Core¶
MinimumLengthError (from ValueError
)¶
-
class
MinimumLengthError
[source]¶ Exception raised when a value has a lower length than the minimum allowed.
INHERITS FROM:
ValueError
MaximumLengthError (from ValueError
)¶
-
class
MaximumLengthError
[source]¶ Exception raised when a value exceeds a maximum allowed length.
INHERITS FROM:
ValueError
NotNoneError (from ValueError
)¶
-
class
NotNoneError
[source]¶ Exception raised when a value of
None
is expected, but a different empty value was detected.INHERITS FROM:
ValueError
NotADictError (from ValueError
)¶
-
class
NotADictError
[source]¶ Exception raised when a value is not a
dict
.INHERITS FROM:
ValueError
NotJSONError (from ValueError
)¶
-
class
NotJSONError
[source]¶ Exception raised when a value cannot be serialized/de-serialized to a JSON object.
INHERITS FROM:
ValueError
NotJSONSchemaError (from ValueError
)¶
-
class
NotJSONSchemaError
[source]¶ Exception raised when a schema supplied is not a valid JSON Schema.
INHERITS FROM:
ValueError
JSONValidationError (from ValueError
)¶
-
class
JSONValidationError
[source]¶ Exception raised when a value fails validation against a JSON Schema.
INHERITS FROM:
ValueError
NotAnIterableError (from CannotCoerceError
)¶
-
class
NotAnIterableError
[source]¶ Exception raised when a value is not an iterable.
INHERITS FROM:
TypeError
->CannotCoerceError
NotCallableError (from ValueError
)¶
-
class
NotCallableError
[source]¶ Exception raised when a given value is not callable.
INHERITS FROM:
ValueError
InvalidVariableNameError (from ValueError
)¶
-
class
InvalidVariableNameError
[source]¶ Exception raised when a value is not a valid Python variable name.
INHERITS FROM:
ValueError
Date / Time¶
UTCOffsetError (from ValueError
)¶
-
class
UTCOffsetError
[source]¶ Exception raised when the UTC offset exceeds +/- 24 hours.
INHERITS FROM:
ValueError
NegativeOffsetMismatchError (from ValueError
)¶
-
class
NegativeOffsetMismatchError
[source]¶ Exception raised when a negative offset is expected, but the value indicates a positive offset.
INHERITS FROM:
ValueError
PositiveOffsetMismatchError (from ValueError
)¶
-
class
PositiveOffsetMismatchError
[source]¶ Exception raised when a positive offset is expected, but the value indicates a negative offset.
INHERITS FROM:
ValueError
Numbers¶
NotAnIntegerError (from ValueError
)¶
-
class
NotAnIntegerError
[source]¶ Exception raised when a value is not being coerced and is not an integer type.
INHERITS FROM:
ValueError
Contributing to the Validator Collection¶
Note
As a general rule of thumb, the Validator Collection applies PEP 8 styling, with some important differences.
Branch | Unit Tests |
---|---|
latest | |
v. 1.3 | |
v. 1.2 | |
v. 1.1 | |
v. 1.0.0 | |
develop |
Contents:
Design Philosophy¶
The Validator Collection is meant to be a “beautiful” and “usable” library. That means that it should offer an idiomatic API that:
- works out of the box as intended,
- minimizes “bootstrapping” to produce meaningful output, and
- does not force users to understand how it does what it does.
In other words:
Users should simply be able to drive the car without looking at the engine.
Style Guide¶
Basic Conventions¶
Do not terminate lines with semicolons.
Line length should have a maximum of approximately 90 characters. If in doubt, make a longer line or break the line between clear concepts.
Each class should be contained in its own file.
If a file runs longer than 2,000 lines…it should probably be refactored and split.
All imports should occur at the top of the file.
Do not use single-line conditions:
# GOOD if x: do_something() # BAD if x: do_something()
When testing if an object has a value, be sure to use
if x is None:
orif x is not None
. Do not confuse this withif x:
andif not x:
.Use the
if x:
construction for testing truthiness, andif not x:
for testing falsiness. This is different from testing:if x is True:
if x is False:
if x is None:
As of right now, because we feel that it negatively impacts readability and is less-widely used in the community, we are not using type annotations.
Naming Conventions¶
variable_name
and notvariableName
orVariableName
. Should be a noun that describes what information is contained in the variable. If abool
, preface withis_
orhas_
or similar question-word that can be answered with a yes-or-no.function_name
and notfunction_name
orfunctionName
. Should be an imperative that describes what the function does (e.g.get_next_page
).CONSTANT_NAME
and notconstant_name
orConstantName
.ClassName
and notclass_name
orClass_Name
.
Design Conventions¶
Functions at the module level can only be aware of objects either at a higher scope or singletons (which effectively have a higher scope).
Functions and methods can use one positional argument (other than
self
orcls
) without a default value. Any other arguments must be keyword arguments with default value given.def do_some_function(argument): # rest of function... def do_some_function(first_arg, second_arg = None, third_arg = True): # rest of function ...
Functions and methods that accept values should start by validating their input, throwing exceptions as appropriate.
When defining a class, define all attributes in
__init__
.When defining a class, start by defining its attributes and methods as private using a single-underscore prefix. Then, only once they’re implemented, decide if they should be public.
Don’t be afraid of the private attribute/public property/public setter pattern:
class SomeClass(object): def __init__(*args, **kwargs): self._private_attribute = None @property def private_attribute(self): # custom logic which may override the default return return self._private_attribute @setter.private_attribute def private_attribute(self, value): # custom logic that creates modified_value self._private_attribute = modified_value
Separate a function or method’s final (or default)
return
from the rest of the code with a blank line (except for single-line functions/methods).
Documentation Conventions¶
We are very big believers in documentation (maybe you can tell). To document the Validator Collection we rely on several tools:
Sphinx [1]¶
Sphinx [1] is used to organize the library’s documentation into this lovely
readable format (which will also be published to ReadTheDocs [2]). This
documentation is written in reStructuredText [3] files which are stored in
<project>/docs
.
Tip
As a general rule of thumb, we try to apply the ReadTheDocs [2] own Documentation Style Guide [4] to our RST documentation.
Hint
To build the HTML documentation locally:
- In a terminal, navigate to
<project>/docs
. - Execute
make html
.
When built locally, the HTML output of the documentation will be available at
./docs/_build/index.html
.
Docstrings¶
- Docstrings are used to document the actual source code itself. When writing docstrings we adhere to the conventions outlined in PEP 257.
Dependencies¶
- jsonschema for JSON Schema validation
jsonschema for JSON Schema validation
The regex drop-in replacement for Python’s (buggy) standard
re
module.Note
This conditional dependency will be automatically installed if you are installing to Python 2.x.
Preparing Your Development Environment¶
In order to prepare your local development environment, you should:
- Fork the Git repository.
- Clone your forked repository.
- Set up a virtual environment (optional).
- Install dependencies:
validator-collection/ $ pip install -r requirements.txt
And you should be good to go!
Ideas and Feature Requests¶
Check for open issues or create a new issue to start a discussion around a bug or feature idea.
Testing¶
If you’ve added a new feature, we recommend you:
- create local unit tests to verify that your feature works as expected, and
- run local unit tests before you submit the pull request to make sure nothing else got broken by accident.
See also
For more information about the Validator Collection testing approach please see: Testing the Validator Collection
Submitting Pull Requests¶
After you have made changes that you think are ready to be included in the main library, submit a pull request on Github and one of our developers will review your changes. If they’re ready (meaning they’re well documented, pass unit tests, etc.) then they’ll be merged back into the main repository and slated for inclusion in the next release.
Building Documentation¶
In order to build documentation locally, you can do so from the command line using:
validator-collection/ $ cd docs
validator-collection/docs $ make html
When the build process has finished, the HTML documentation will be locally available at:
validator-collection/docs/_build/html/index.html
Note
Built documentation (the HTML) is not included in the project’s Git repository. If you need local documentation, you’ll need to build it.
Testing the Validator Collection¶
Contents
Testing Philosophy¶
Note
Unit tests for the Validator Collection are written using pytest [1] and a comprehensive set of test automation are provided by tox [2].
There are many schools of thought when it comes to test design. When building the Validator Collection, we decided to focus on practicality. That means:
- DRY is good, KISS is better. To avoid repetition, our test suite makes extensive use of fixtures, parametrization, and decorator-driven behavior. This minimizes the number of test functions that are nearly-identical. However, there are certain elements of code that are repeated in almost all test functions, as doing so will make future readability and maintenance of the test suite easier.
- Coverage matters…kind of. We have documented the primary intended behavior of every function in the Validator Collection library, and the most-likely failure modes that can be expected. At the time of writing, we have about 85% code coverage. Yes, yes: We know that is less than 100%. But there are edge cases which are almost impossible to bring about, based on confluences of factors in the wide world. Our goal is to test the key functionality, and as bugs are uncovered to add to the test functions as necessary.
Test Organization¶
Each individual test module (e.g. test_validators.py
) corresponds to a
conceptual grouping of functionality. For example:
test_validators.py
tests validator functions found invalidator_collection/_validators.py
Certain test modules are tightly coupled, as the behavior in one test module may
have implications on the execution of tests in another. These test modules use
a numbering convention to ensure that they are executed in their required order,
so that test_1_NAME.py
is always executed before
test_2_NAME.py
.
Configuring & Running Tests¶
Installing with the Test Suite¶
$ pip install validator-collection[tests]
See also
When you create a local development environment, all dependencies for running and extending the test suite are installed.
Command-line Options¶
The Validator Collection does not use any custom command-line options in its test suite.
Tip
For a full list of the CLI options, including the defaults available, try:
validator-collection $ cd tests/
validator-collection/tests/ $ pytest --help
Configuration File¶
Because the Validator Collection has a very simple test suite, we have not
prepared a pytest.ini
configuration file.
Running Tests¶
tests/ $ pytest
tests/ $ pytest tests/test_module.py
tests/ $ pytest tests/test_module.py -k 'test_my_test_function'
Skipping Tests¶
Note
Because of the simplicity of the Validator Collection, the test suite does not currently support any test skipping.
Incremental Tests¶
Note
The Validator Collection test suite does support incremental testing using, however at the moment none of the tests designed rely on this functionality.
A variety of test functions are designed to test related functionality. As a
result, they are designed to execute incrementally. In order to execute tests
incrementally, they need to be defined as methods within a class that you decorate
with the @pytest.mark.incremental
decorator as shown below:
@pytest.mark.incremental
class TestIncremental(object):
def test_function1(self):
pass
def test_modification(self):
assert 0
def test_modification2(self):
pass
This class will execute the TestIncremental.test_function1()
test, execute and
fail on the TestIncremental.test_modification()
test, and automatically fail
TestIncremental.test_modification2()
because of the .test_modification()
failure.
To pass state between incremental tests, add a state
argument to their method
definitions. For example:
@pytest.mark.incremental
class TestIncremental(object):
def test_function(self, state):
state.is_logged_in = True
assert state.is_logged_in = True
def test_modification1(self, state):
assert state.is_logged_in is True
state.is_logged_in = False
assert state.is_logged_in is False
def test_modification2(self, state):
assert state.is_logged_in is True
Given the example above, the third test (test_modification2
) will fail because
test_modification
updated the value of state.is_logged_in
.
Note
state
is instantiated at the level of the entire test session (one run of
the test suite). As a result, it can be affected by tests in other test modules.
[1] | https://docs.pytest.org/en/latest/ |
[2] | https://tox.readthedocs.io |
Release History¶
Contents
- Release History
- Release 1.3.6 (released August 29, 2019)
- Release 1.3.5 (released May 17, 2019)
- Release 1.3.4 (released April 3, 2019)
- Release 1.3.3 (released March 23, 2019)
- Release 1.3.2 (released February 9, 2019)
- Release 1.3.1 (released November 30, 2018)
- Release 1.3.0 (released November 12, 2018)
- Release 1.2.0 (released August 4, 2018)
- Release 1.1.0 (released April 23, 2018)
- Release 1.0.0 (released April 16, 2018)
Release 1.3.6 (released August 29, 2019)¶
- #37: Added regex matching to variable name validation. Still checks compilation but first must pass regex validation.
Release 1.3.5 (released May 17, 2019)¶
- #34: Fixed case sensitivity bugs in URL validator.
Release 1.3.4 (released April 3, 2019)¶
- #32: Removed a print statement left over from debugging.
Release 1.3.3 (released March 23, 2019)¶
- #28 and #29: Fixed an error where special URLs (localhost) and special IPs (e.g. 10.1.1.1) failed when used with an explicit port or path.
Release 1.3.2 (released February 9, 2019)¶
- #25: Fixed an error where an underscore in a host name was not being properly recognized (h/t @mastak) when parsing URLs and domain names.
- #23: Fixed an error where URL / domain validators and checkers were (incorrectly) failing on valid special names (e.g. localhost, etc.) and special IPs (e.g. 10.1.1.1).
- #24: Fixed bug where checkers returned false-negatives when the underlying validator raised a SyntaxError.
Release 1.3.1 (released November 30, 2018)¶
- #21: Fixed validators.datetime() handling of timezone offsets to conform to ISO-8601.
Release 1.3.0 (released November 12, 2018)¶
- #18: Upgraded
requests
requirement to 2.20.1 - #17: Added
validators.json()
with support for JSON Schema validation. - #17: Added
checkers.is_json()
with support for checking against JSON Schema. - Added Python 3.7 to the Travis CI Test Matrix.
Release 1.2.0 (released August 4, 2018)¶
Features Added¶
- #14: Added
coerce_value
argument tovalidators.date()
,validators.datetime()
, andvalidators.time()
.
Bugs Fixed¶
- #11: Removed legacy print statements.
- #13:
checkers.is_time()
,checkers.is_date()
, andcheckers.is_datetime()
no longer return false positives
Release 1.1.0 (released April 23, 2018)¶
Features Added¶
- Added
validators.domain()
andcheckers.is_domain()
support with unit tests. - #8: Added more verbose exceptions while retaining backwards-compatability with standard library exceptions.
- #6: Made it possible to disable validators by adding the validator name to the
VALIDATORS_DISABLED
environment variable. - #6: Made it possible to disable checkers by adding the checker name to the
CHECKERS_DISABLED
environment variable. - #6: Made it possible to force a validator or checker to run (even if disabled)
by passing it a
force_run = True
keyword argument. - #5: Added
validators.readable()
andcheckers.is_readable()
support to validate whether a file (path) is readable. - #4: Added
validators.writeable()
andcheckers.is_writeable()
support to validate whether a file (path) is writeable. Only works on Linux, by design. - #9: Added
validators.executable()
andcheckers.is_executable()
support to validate whether a file is executable. Only works on Linux, by design.
Bugs Fixed¶
- #7: Refactored
validators.email()
to more-comprehensively validate email addresses in compliance with RFC 5322.
Testing¶
- #6: Added unit tests for disabling validators and checkers based on the
VALIDATORS_DISABLED
andCHECKERS_DISABLED
environment variables, with support for theforce_run = True
override. - #7: Added more extensive email address cases to test compliance with RFC 5322.
- Added unit tests for
validators.domain()
andcheckers.is_domain()
. - #5: Added unit tests for
validators.readable()
andcheckers.is_readable()
that work on the Linux platform. Missing unit tests on Windows. - #4: Added unit tests for
validators.writeable()
andcheckers.is_writeable()
. - #9: Added unit tests for
validators.executable()
andcheckers.is_executable()
.
Documentation¶
- Added
CHANGES.rst
. - #7: Added additional detail to
validators.email()
documentation. - #8: Added detailed exception / error handling documentation.
- #8: Updated validator error documentation.
- #6: Added documentation on disabling validators and checkers.
- #5: Added documentation for
validators.readable()
andcheckers.is_readable()
. - #4: Added documentation for
validators.writeable()
andcheckers.is_writeable()
. - #9: Added documentation for
validators.executable()
andcheckers.is_executable()
.
Release 1.0.0 (released April 16, 2018)¶
- First public release
Glossary¶
- Checker
- A function which takes an input value and indicates (
True
/False
) whether it contains what you expect. Will always return a Boolean value, and will not raise an exception on failure. - Validator
- A function which takes an input value and ensures that it is what (the type
or contents) you expect it to be. Will return the value or
None
depending on the arguments you pass to it, and will raise an exception if validation fails.
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, and 3.7.
For a list of validators available, please see the lists below.
Contents
Installation¶
To install the Validator Collection, just execute:
$ pip install validator-collection
Dependencies¶
- jsonschema for JSON Schema validation
jsonschema for JSON Schema validation
The regex drop-in replacement for Python’s (buggy) standard
re
module.Note
This conditional dependency will be automatically installed if you are installing to Python 2.x.
Available Validators and Checkers¶
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 |
decimal |
file_exists |
ipv4 |
|
not_empty |
directory_exists |
ipv6 |
||
uuid |
readable |
mac_address |
||
variable_name |
writeable |
|||
executable |
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:
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.
Using Validators¶
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:
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:
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.
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 and Validator Reference.
Disabling Validation¶
Caution
If you are disabling validators 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 theVALIDATORS_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:
$ export VALIDATORS_DISABLED = "variable_name, email, ipv4"
This disables the variable_name()
,
email()
, and
ipv4()
validators respectively.
Now if we run:
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:
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:
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
).
Using Checkers¶
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 would fail. See 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, 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.
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 you
call them using 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 theCHECKERS_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:
$ export CHECKERS_DISABLED = "is_variable_name, is_email, is_ipv4"
This disables the is_variable_name()
,
is_email()
, and
is_ipv4()
validators respectively.
Now if we run:
from validator_collection import checkers, errors
result = checkers.is_variable_name('this is an invalid variable name')
# result will be True
The checker will return True
.
However, if we run:
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:
from validator_collection import checkers, errors
result = checkers.is_variable_name('this is an invalid variable name',
force_run = True)
# result will be False
will return False
.
Best Practices¶
Checkers and 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:
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:
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
Contributing¶
We welcome contributions and pull requests! For more information, please see the Contributor Guide
Testing¶
We use TravisCI for our build automation and ReadTheDocs for our documentation.
Detailed information about our test suite and how to run tests locally can be found in our Testing Reference.