API Documentation
- class filters.base.BaseFilter
Base functionality for all Filters, macros, etc.
- CODE_EXCEPTION = 'exception'
- apply(value)
Applies the filter to a value.
- property handler: BaseInvalidValueHandler
Returns the invalid value handler for the filter.
- property parent: BaseFilter | None
Returns the parent Filter.
- classmethod resolve_filter(the_filter: BaseFilter | FilterMeta | Callable[[], BaseFilter] | None, parent: BaseFilter | None = None, key: str | None = None) FilterChain | None
Converts a filter-compatible value into a consistent type.
- set_handler(handler: BaseInvalidValueHandler) BaseFilter
Cascading method for setting the filter’s invalid value handler.
- templates = {'exception': 'An error occurred while processing this value.'}
- class filters.base.BaseInvalidValueHandler
Base functionality for classes that handle invalid values.
- abstractmethod handle_invalid_value(message: str, exc_info: bool, context: MutableMapping) Any
Handles an invalid value.
- Parameters:
message – Error message.
exc_info – Whether to include output from :py:func:
sys.exc_info.context – Additional context values for the error.
- class filters.base.ExceptionHandler
Invalid value handler that raises an exception.
- handle_invalid_value(message: str, exc_info: bool, context: MutableMapping) None
Handles an invalid value.
- Parameters:
message – Error message.
exc_info – Whether to include output from :py:func:
sys.exc_info.context – Additional context values for the error.
- class filters.base.FilterChain(start_filter: BaseFilter | FilterMeta | Callable[[], BaseFilter] | None = None)
Allows you to chain multiple filters together so that they are treated as a single filter.
- templates = {'exception': 'An error occurred while processing this value.'}
- filters.base.FilterCompatible = ForwardRef('BaseFilter') | ForwardRef('FilterMeta') | collections.abc.Callable[[], 'BaseFilter'] | None
Used in PEP-484 type hints to indicate a value that can be normalised into an instance of a BaseFilter subclass.
- exception filters.base.FilterError(*args, **kwargs)
Indicates that a parsed value could not be filtered because the value was invalid.
Provides a container to include additional variables and other information to help troubleshoot errors.
- class filters.base.FilterMeta(name, bases, namespace, /, **kwargs)
Metaclass for filters.
- class filters.base.Type(allowed_types: type | tuple[type, ...], allow_subclass: bool = True, aliases: Mapping[type, str] | None = None)
Checks the type of a value.
- Parameters:
allowed_types – The type (or types) that incoming values are allowed to have.
allow_subclass – Whether to allow subclasses when checking for type matches.
aliases –
Aliases to use for type names in error messages.
This is useful for providing more context- appropriate names to end users and/or masking native Python type names.
- CODE_WRONG_TYPE = 'wrong_type'
- get_type_name(type_: type, aliased: bool = True) str
Returns the name of the specified type.
Note
Reference: https://bugs.python.org/issue34422
- templates = {'exception': 'An error occurred while processing this value.', 'wrong_type': '{incoming} is not valid (allowed types: {allowed}).'}
- class filters.complex.FilterMapper(filter_map: Mapping[str, BaseFilter | FilterMeta | Callable[[], BaseFilter] | None], allow_missing_keys: bool | Iterable[str] = True, allow_extra_keys: bool | Iterable[str] = True)
Given a dict of filters, applies each filter to the corresponding value in incoming mappings.
The resulting value is a dict. The order of keys in the
filter_mappassed to the initialiser determines the order of keys in the filtered value.Note
The order of extra keys is undefined, but they will always be last.
Initialises the FilterMapper filter.
- Parameters:
filter_map – Maps each filter chain to the corresponding key that it will be applied to.
allow_missing_keys –
Determines how values with missing keys (according to
filter_map) get handled:True: The missing values are set to
Noneand then filtered as normal.False: Missing keys are treated as invalid values.
<Iterable>: Only the specified keys are allowed to be omitted.
allow_extra_keys –
Determines how values with extra keys (according to
filter_map) get handled:True: The extra values are passed through to the filtered value.
False: Extra values are treated as invalid values and omitted from the filtered value.
<Iterable>: Only the specified extra keys are allowed.
- CODE_EXTRA_KEY = 'unexpected'
- CODE_MISSING_KEY = 'missing'
- templates = {'exception': 'An error occurred while processing this value.', 'missing': '{key} is required.', 'unexpected': 'Unexpected key "{actual_key}".'}
- class filters.complex.FilterRepeater(filter_chain: BaseFilter | FilterMeta | Callable[[], BaseFilter] | None, restrict_keys: Iterable | None = None)
Applies a filter to every value in an Iterable.
You can apply a FilterRepeater to a dict (or other Mapping). The filters will be applied to the Mapping’s values.
Note
The resulting value will be coerced to a list or dict (depending on the input value).
Initialises the FilterRepeater filter.
- Parameters:
filter_chain – The filter(s) that will be applied to each item in the incoming iterables.
restrict_keys –
Only these keys/indexes will be allowed (any other keys/indexes encountered will be treated as invalid values).
Important: If this is an empty container will result in EVERY key/index being rejected!
Set to
None(default) to allow any key/index.
- CODE_EXTRA_KEY = 'unexpected'
- templates = {'exception': 'An error occurred while processing this value.', 'unexpected': 'Unexpected key "{key}".'}
- class filters.complex.FilterSwitch(getter: Callable[[Any], Hashable], cases: Mapping[Hashable, BaseFilter | FilterMeta | Callable[[], BaseFilter] | None], default: BaseFilter | FilterMeta | Callable[[], BaseFilter] | None = None)
Chooses the next filter to apply based on the output of a callable.
Initialises the FilterSwitch filter.
- Parameters:
getter – Callable used to extract the value to match against switch cases.
cases – Mapping of possible values to the corresponding filters.
default –
Default filter to use, if none of the cases are matched.
If null (default) then the value will be considered invalid if it doesn’t match any cases.
- templates = {'exception': 'An error occurred while processing this value.'}
- class filters.complex.NamedTuple(type_: type[tuple], filter_map: Mapping[str, BaseFilter | FilterMeta | Callable[[], BaseFilter] | None] | None = None)
Attempts to convert the incoming value into a namedtuple.
Initialises the NamedTuple filter.
- Parameters:
type – The type of namedtuple into which the filter will attempt to convert incoming values.
filter_map –
Specifies additional filters that should be applied to each attribute in the resulting namedtuple object.
For example:
>>> import filters as f >>> from collections import namedtuple >>> Color = namedtuple('Color', ('r', 'g', 'b')) >>> # noinspection PyTypeChecker >>> filter_chain = f.NamedTuple(Color, { ... 'r': f.Required | f.Int | f.Min(0) | f.Max(255), ... 'g': f.Required | f.Int | f.Min(0) | f.Max(255), ... 'b': f.Required | f.Int | f.Min(0) | f.Max(255), ... }) >>> filter_chain.apply(['64', '128', '192']) Color(r=64, g=128, b=192)
- templates = {'exception': 'An error occurred while processing this value.'}
- class filters.extensions.FilterExtensionRegistry(group: str = 'filters.extensions')
Creates a registry that can be used to dynamically load 3rd-party filters into the (nearly) top-level namespace.
Initialises the FilterExtensionRegistry.
- Parameters:
group – The entry point group name to use. Defaults to GROUP_NAME.
- static create_instance(class_: type, *args, **kwargs) Any
Returns the class itself when called with no arguments.
Overrides the default behaviour (which would instantiate the class) so that extension filters behave consistently with
filters.base.FilterMeta.__or__(), which chains uninstantiated filter classes directly (e.g.filters.ext.MyFilter | OtherFilter).- Parameters:
class – The filter class to return or instantiate.
*args – Positional arguments forwarded to the class constructor.
**kwargs – Keyword arguments forwarded to the class constructor.
- Returns:
The class itself if no arguments are provided; otherwise a new instance of the class.
- filters.extensions.GROUP_NAME = 'filters.extensions'
The key to use when declaring entry points in
pyproject.toml.Example:
[project.entry-points."filters.extensions"] Country = "filters_iso:Country" Currency = "filters_iso:Currency"
Filters that are loaded this way are accessible from
filters.ext(not imported into the global namespace because it gives IDEs a heart attack).
- class filters.handlers.FilterMessage(message: str, context: MutableMapping, exc_info: str | None = None)
Provides a consistent API for messages sent to MemoryHandler.
Initialises the FilterMessage.
- Parameters:
message – The error message.
context – The context mapping.
exc_info – Exception traceback (if applicable).
- as_dict(with_debug_info: bool = False) dict
Returns a dict representation of the FilterMessage.
- Parameters:
with_debug_info – Whether to include context and exception traceback in the result.
- Returns:
Dict representation with code and message, and optionally context and exc_info if with_debug_info is True.
- class filters.handlers.FilterRunner(starting_filter: BaseFilter | FilterMeta | Callable[[], BaseFilter] | None, incoming_data: Any = None, capture_exc_info: bool = False)
Wrapper for a filter that provides an API similar to what you would expect from a Django form – at least, when it comes to methods related to data validation :)
Initialises the FilterRunner.
- Parameters:
starting_filter – The filter to run.
incoming_data – E.g.,
request.POST.capture_exc_info –
Whether to capture
sys.exc_infowhen handling an exception.This is turned off by default to reduce memory usage, but it is useful in certain cases (e.g., if you want to send exceptions to a logger).
Regardless, you can still check
self.has_exceptionsto see if an exception occurred.
- apply(incoming_data: Any)
Reruns the filter chain against a new value.
- Parameters:
incoming_data – The new value to filter.
- property cleaned_data
Returns the resulting value after applying the filter.
- Returns:
The resulting value after applying the request filter.
- property error_codes: dict[str, list[str]]
Returns a dict of error codes generated by the Filter.
- Returns:
Dict mapping keys to lists of error codes.
- property errors: dict[str, list[dict[str, str]]]
Returns a dict of error messages generated by the Filter.
The format is suitable for inclusion in e.g., a 400 Bad Request response payload.
Example:
{ 'authToken': [ { 'code': 'not_found', 'message': 'No AuthToken found matching this value.', }, ], 'data.foobar': [ { 'code': 'unexpected', 'message': 'Unexpected key "foobar".', }, ], # etc. }
- Returns:
Dict mapping keys to lists of error dicts.
- property exc_info: list[tuple[type, Exception, TracebackType]]
Returns tracebacks from any exceptions that were captured.
- Returns:
List of exception info tuples (type, exception, traceback).
- property filter_messages: dict[str, list[FilterMessage]]
Returns the raw FilterMessages generated by the Filter.
- Returns:
Dict mapping keys to lists of FilterMessage objects.
- full_clean()
Applies the filter to the request data.
- get_errors(with_context: bool = False) dict[str, list[dict[str, str]]]
Returns a dict of error messages generated by the Filter.
The format is suitable for inclusion in e.g., a 400 Bad Request response payload.
- Parameters:
with_context –
Whether to include the context object in the result (for debugging purposes).
Note: context is usually not safe to expose to clients!
- Returns:
Dict mapping keys to lists of error dicts.
- class filters.handlers.LogHandler(logger: Logger | LoggerAdapter, level: int = 40)
Invalid value handler that sends the details to a logger.
Initialises the LogHandler.
- Parameters:
logger – The logger that log messages will get sent to.
level – Level of the logged messages.
- handle_invalid_value(message: str, exc_info: bool, context: MutableMapping) None
Handles an invalid value.
- Parameters:
message – Error message.
exc_info – Whether to include output from :py:func:
sys.exc_info.context – Additional context values for the error.
- class filters.handlers.MemoryHandler(capture_exc_info: bool = False)
Invalid value handler that stores messages locally.
Initialises the MemoryHandler.
- Parameters:
capture_exc_info –
Whether to capture sys.exc_info when handling an exception.
This is turned off by default to reduce memory usage, but it is useful in certain cases (e.g., if you want to send exceptions to a logger that expect exc_info).
Regardless, you can still check
self.has_exceptionsto see if an exception occurred.
- handle_invalid_value(message: str, exc_info: bool, context: MutableMapping) None
Handles an invalid value.
- Parameters:
message – Error message.
exc_info – Whether to include output from :py:func:
sys.exc_info.context – Additional context values for the error.
- class filters.macros.FilterMacroType
Base type for filter macros.
Doesn’t do anything on its own, but it is useful for identifying filter macros when paired with an
issubclasscheck.Important: Use
issubclass, notisinstance!Example:
@filter_macro def MyMacro(): return f.NoOp # ``MyMacro`` is now a *subclass* of ``FilterMacroType``! assert issubclass(MyMacro, FilterMacroType) # It is *not* an *instance* of ``FilterMacroType``! assert not isinstance(MyMacro, FilterMacroType)
- templates = {'exception': 'An error occurred while processing this value.'}
- filters.macros.filter_macro(func, *args, **kwargs)
Promotes a function returning a filter into its own filter type.
Example:
@filter_macro def String(): return Unicode | Strip | NotEmpty # You can now use `String` anywhere you would use a regular # Filter: (String | Split(':')).apply('...')
You can also use
filter_macroto create partials, allowing you to preset one or more initialisation arguments:Minor = filter_macro(Max, max_value=18, inclusive=False) Minor(inclusive=True).apply(18)
- Parameters:
func – The function to promote to a filter type.
*args – Positional arguments to preset.
**kwargs – Keyword arguments to preset.
- Returns:
A new filter type based on the function.
- class filters.number.Decimal(max_precision: int | Decimal | None = None, allow_tuples: bool = True)
Interprets the value as a
decimal.Decimalobject.Initialises the Decimal filter.
- Parameters:
max_precision –
Max number of decimal places the resulting value is allowed to have. Values that are too precise will be rounded to fit.
To avoid ambiguity, specify
max_precisionas adecimal.Decimalobject.For example, to round to the nearest 1/100:
Decimal(max_precision=decimal.Decimal('0.01'))
allow_tuples –
Whether to allow tuple-like inputs.
Allowing tuple inputs might couple the implementation more tightly to Python’s Decimal type, so you have the option to disallow it.
- CODE_INVALID = 'not_numeric'
- CODE_NON_FINITE = 'not_finite'
- templates = {'exception': 'An error occurred while processing this value.', 'not_finite': 'Numeric value expected.', 'not_numeric': 'Numeric value expected.'}
- class filters.number.Int
Interprets the value as an int.
Strings and other compatible values will be converted, but floats will be treated as INVALID.
Note
Python handles really, really big int values transparently, so you don’t need to worry about overflow.
Reference: http://stackoverflow.com/a/538583
- CODE_DECIMAL = 'not_int'
- templates = {'exception': 'An error occurred while processing this value.', 'not_int': 'Integer value expected.'}
- class filters.number.Max(max_value: Any, exclusive: bool = False)
Enforces a maximum value.
Note
Technically, this filter can operate on any type that supports comparison, but it tends to be used exclusively with numeric types.
Initialises the Max filter.
- Parameters:
max_value – The max value that the Filter will accept.
exclusive –
Whether to exclude the max value itself as a valid value:
True: The incoming value must be less than the max value.
False (default): The incoming value must be less than or equal to the max value.
- CODE_TOO_BIG = 'too_big'
- templates = {'exception': 'An error occurred while processing this value.', 'too_big': 'Value is too large (must be {operator} {max}).'}
- class filters.number.Min(min_value: Any, exclusive: bool = False)
Enforces a minimum value.
Note
Technically, this filter can operate on any type that supports comparison, but it tends to be used exclusively with numeric types.
Initialises the Min filter.
- Parameters:
min_value – The min value that the Filter will accept.
exclusive –
Whether to exclude the min value itself as a valid value:
True: The incoming value must be greater than the min value.
False (default): The incoming value must be greater than or equal to the min value.
- CODE_TOO_SMALL = 'too_small'
- templates = {'exception': 'An error occurred while processing this value.', 'too_small': 'Value is too small (must be {operator} {min}).'}
- class filters.number.Round(to_nearest: int | str | Decimal = 1, rounding: str = 'ROUND_HALF_UP', result_type: type = <class 'decimal.Decimal'>)
Rounds incoming values to whole numbers or decimals.
Initialises the Round filter.
- Parameters:
to_nearest –
The value that the filter should round to.
E.g.,
Round(1)rounds to the nearest whole number.If you want to round to a float value, it is recommended that you provide it as a string or Decimal, to avoid floating point precision errors.
rounding – Controls how to round values.
result_type – The type of result to return.
- templates = {'exception': 'An error occurred while processing this value.'}
- class filters.simple.Array(aliases: Mapping[type, str] | None = None)
Validates that the incoming value is a non-string sequence.
- Parameters:
allowed_types – The type (or types) that incoming values are allowed to have.
allow_subclass – Whether to allow subclasses when checking for type matches.
aliases –
Aliases to use for type names in error messages.
This is useful for providing more context- appropriate names to end users and/or masking native Python type names.
- templates = {'exception': 'An error occurred while processing this value.', 'wrong_type': '{incoming} is not valid (allowed types: {allowed}).'}
- class filters.simple.ByteArray(encoding: str = 'utf-8')
Converts an incoming value into a bytearray.
Initialises the ByteArray filter.
- Parameters:
encoding – The encoding to use when decoding strings into bytes.
- CODE_BAD_ENCODING = 'bad_encoding'
- templates = {'bad_encoding': 'Unable to encode this value using {encoding}.', 'exception': 'An error occurred while processing this value.'}
- class filters.simple.Call(callable_: Callable[[...], Any], *extra_args, **extra_kwargs)
Runs the value through a callable.
Usually, creating a custom filter type works better, as you have more control over how invalid values are handled, you can specify custom error codes, it’s easier to write tests for, etc.
But, in a pinch, this is a handy way to quickly integrate a custom function into a filter chain.
Initialises the Call filter.
- Parameters:
callable – The callable that will be applied to incoming values.
extra_args – Extra positional arguments to pass to the callable.
extra_kwargs – Extra keyword arguments to pass to the callable.
- templates = {'exception': 'An error occurred while processing this value.'}
- class filters.simple.Date(timezone: tzinfo | int | float | None = None, naive: bool = False)
Interprets the value as a UTC date.
Note
The value is first converted to a datetime with UTC timezone, which may cause the resulting date to appear to be off by +/- 1 day (does not apply if the value is already a date object).
Initialises the Datetime filter.
- Parameters:
timezone – Specifies the timezone to use when the incoming value is a naive timestamp. Has no effect on timezone-aware timestamps. The result is always converted to UTC, regardless of the value of the
timezoneparam! You can provide an int/float here, which is the offset from UTC in hours (e.g., 5 = UTC+5).naive – If True, the filter will return naive datetime objects (sans tzinfo). This is useful e.g., for datetime values that will be stored in a database that doesn’t understand aware timestamps. Incoming values are still converted to UTC before stripping tzinfo!
- CODE_INVALID = 'not_date'
- templates = {'exception': 'An error occurred while processing this value.', 'not_date': 'This value does not appear to be a date.', 'not_datetime': 'This value does not appear to be a datetime.'}
- class filters.simple.Datetime(timezone: tzinfo | int | float | None = None, naive: bool = False)
Interprets the value as a UTC datetime.
Initialises the Datetime filter.
- Parameters:
timezone – Specifies the timezone to use when the incoming value is a naive timestamp. Has no effect on timezone-aware timestamps. The result is always converted to UTC, regardless of the value of the
timezoneparam! You can provide an int/float here, which is the offset from UTC in hours (e.g., 5 = UTC+5).naive – If True, the filter will return naive datetime objects (sans tzinfo). This is useful e.g., for datetime values that will be stored in a database that doesn’t understand aware timestamps. Incoming values are still converted to UTC before stripping tzinfo!
- CODE_INVALID = 'not_datetime'
- templates = {'exception': 'An error occurred while processing this value.', 'not_datetime': 'This value does not appear to be a datetime.'}
- class filters.simple.Empty
Expects the value to be empty.
In this context, “empty” is defined as having zero length. Note that this Filter considers values that do not have length to be not empty (in particular, False and 0 are not considered empty here).
- CODE_NOT_EMPTY = 'not_empty'
- templates = {'exception': 'An error occurred while processing this value.', 'not_empty': 'Empty value expected.'}
- class filters.simple.Item(key: Hashable | None = None)
Returns a single item from an incoming mapping or sequence.
- CODE_MISSING_KEY = 'missing'
- templates = {'exception': 'An error occurred while processing this value.', 'missing': '{key} is required.'}
- class filters.simple.Len(exact: int | None = None, *, min: int | None = None, max: int | None = None)
Validates that a value’s length satisfies the configured constraint.
Modes (mutually exclusive):
Len(n)— exact length (equivalent toLength(n))Len(min=n)— minimum length only (equivalent toMinLength(n))Len(max=n)— maximum length only (equivalent toMaxLength(n))Len(min=m, max=n)— length within a range
- Parameters:
exact – Required length. Mutually exclusive with
minandmax.min – Minimum allowed length.
max – Maximum allowed length.
- Raises:
ValueError – If
exactis combined withminormax, if any value is negative, or ifmin>max.
- CODE_TOO_LONG = 'too_long'
- CODE_TOO_SHORT = 'too_short'
- templates = {'exception': 'An error occurred while processing this value.', 'too_long': 'Value is too long (length must be {constraint}).', 'too_short': 'Value is too short (length must be {constraint}).'}
- class filters.simple.Length(length: int)
Ensures incoming values have exactly the right length.
- CODE_TOO_LONG = 'too_long'
- CODE_TOO_SHORT = 'too_short'
- templates = {'exception': 'An error occurred while processing this value.', 'too_long': 'Value is too long (length must be exactly {expected}).', 'too_short': 'Value is too short (length must be exactly {expected}).'}
- class filters.simple.MaxLength(max_length: int, truncate: bool = False)
Enforces a maximum length on the value.
Initialises the MaxLength filter.
- Parameters:
max_length – Incoming value must have at most this many items to be valid.
truncate – Whether to truncate values that are too long.
- CODE_TOO_LONG = 'too_long'
- templates = {'exception': 'An error occurred while processing this value.', 'too_long': 'Value is too long (length must be < {max}).'}
- class filters.simple.MinLength(min_length: int)
Enforces a minimum length on the value.
- CODE_TOO_SHORT = 'too_short'
- templates = {'exception': 'An error occurred while processing this value.', 'too_short': 'Value is too short (length must be > {min}).'}
- class filters.simple.NoOp
Filter that does nothing, used when you need a placeholder Filter in a FilterChain.
- templates = {'exception': 'An error occurred while processing this value.'}
- class filters.simple.NotEmpty(allow_none: bool = True)
Expects the value not to be empty.
In this context, “empty” is defined as having zero length. Note that this filter considers values that do not have length to be not empty (in particular, False and 0 are not considered empty here).
By default, this filter treats
Noneas valid, just like every other filter. However, you can configure the filter to rejectNonein its initialiser method.Initialises the NotEmpty filter.
- Parameters:
allow_none – Whether to allow
None.
- CODE_EMPTY = 'empty'
- templates = {'empty': 'Non-empty value expected.', 'exception': 'An error occurred while processing this value.'}
- class filters.simple.Omit(keys: Iterable)
Returns a copy of an incoming mapping or sequence, with the specified keys omitted. Any other items will be passed through.
Initialises the Omit filter.
- Parameters:
keys – List of keys that will be omitted from incoming values.
- templates = {'exception': 'An error occurred while processing this value.'}
- class filters.simple.Optional(default: Any = None, call_default: bool | None = None)
Changes empty and null values into a default value.
In this context, “empty” is defined as having zero length.
Note
If an incoming value does not have a length, it is considered to be not empty (in particular, note that
Falseand0are considered not empty in this context).Initialises the Optional filter.
- Parameters:
default –
The default value used to replace empty values.
If
defaultis callable, then when the filter encounters an empty incoming value, it will calldefaultand use the return value as the replacement, instead of usingdefaultitself.For example, if
default=list, then each time the filter encounters an empty value, it will create a newlistto use as the replacement.call_default –
Whether to call
defaultto determine the replacement value.Effect:
None(default) - only calldefaultif it is callable.False- do not calldefaulteven if it is callable.True- calldefaulteven if it is not callable (pretty sure you’d never need this, but we’re all consenting adults here).
- templates = {'exception': 'An error occurred while processing this value.'}
- class filters.simple.Pick(keys: Iterable, allow_missing_keys: bool | Iterable = True)
Returns a copy of an incoming mapping or sequence, with only the specified keys included.
Initialises the Pick filter.
- Parameters:
keys – List of keys that will be picked from incoming values.
allow_missing_keys –
Determines how values with missing keys get handled:
True (default): Missing keys are ignored.
False: Missing keys are treated as invalid values.
<Iterable>: Only the specified keys are allowed to be omitted.
- CODE_MISSING_KEY = 'missing'
- templates = {'exception': 'An error occurred while processing this value.', 'missing': '{key} is required.'}
- class filters.simple.Required
Same as NotEmpty, but with
allow_nonehard-wired toFalse.This filter is the only exception to the “
Nonepasses by default” rule.Initialises the NotEmpty filter.
- Parameters:
allow_none – Whether to allow
None.
- templates = {'empty': 'This value is required.', 'exception': 'An error occurred while processing this value.'}
- class filters.string.Base64Decode
Decodes an incoming value using the Base64 algo.
- CODE_INVALID = 'not_base64'
- templates = {'exception': 'An error occurred while processing this value.', 'not_base64': 'Base64-encoded value expected.'}
- class filters.string.ByteString(encoding: str = 'utf-8', normalize: bool = False)
Converts a value into a byte string, encoded as UTF-8.
IMPORTANT: This filter returns bytes objects, not bytearrays!
Initialises the ByteString filter.
- Parameters:
encoding – Used to decode non-unicode values.
normalize –
Whether to normalise the unicode value before converting back into bytes:
Convert to NFC form.
Remove non-printable characters.
Convert all line endings to unix-style (’n’).
Note that
normalizeisFalseby default forByteString, butTrueby default forUnicode.
- templates = {'exception': 'An error occurred while processing this value.', 'wrong_encoding': 'This value cannot be decoded using {encoding}.'}
- class filters.string.CaseFold
Applies case folding to an incoming string, allowing you to perform case-insensitive comparisons.
The result tends to be lowercase, but it is recommended that you NOT treat CaseFold as a Unicode-aware lowercase filter! The proper way to lowercase a string is very much locale-dependent.
Note
The built-in
str.upper()andstr.lower()methods tend do a pretty good job of properly changing the case of unicode strings.References:
- templates = {'exception': 'An error occurred while processing this value.'}
- class filters.string.Choice(choices: Iterable[Hashable], case_sensitive: bool = True)
Requires an incoming value to match one of a set of allowed options.
By default, the comparison is case-sensitive, but you can control this via the filter’s initialiser.
Note
This filter is technically able to work with any hashable value, not just strings.
- Parameters:
choices – The allowed options; if an incoming value doesn’t match any of these values, it is invalid.
case_sensitive – Whether the comparison should be case-sensitive.
- CODE_INVALID = 'not_valid_choice'
- templates = {'exception': 'An error occurred while processing this value.', 'not_valid_choice': 'Valid options are: {choices}'}
- class filters.string.IpAddress(ipv4: bool = True, ipv6: bool = False)
Validates an incoming value as an IPv[46] address.
Initialises the IpAddress filter.
- Parameters:
ipv4 – Whether to accept IPv4 addresses.
ipv6 – Whether to accept IPv6 addresses.
- CODE_INVALID = 'not_ip_address'
- property ip_type: str
Returns the IP address versions that this Filter accepts.
- Returns:
String indicating accepted IP versions (e.g., “IPv4”, “IPv6”, “IPv4/IPv6”).
- templates = {'exception': 'An error occurred while processing this value.', 'not_ip_address': 'This value is not a valid {ip_type} address.'}
- class filters.string.JsonDecode(decoder: Callable = <function loads>)
Interprets the value as JSON.
Initialises the JsonDecode filter.
- Parameters:
decoder – Callable used to decode JSON strings. Defaults to json.loads.
- CODE_INVALID = 'not_json'
- templates = {'exception': 'An error occurred while processing this value.', 'not_json': 'This value is not valid JSON.'}
- class filters.string.MaxBytes(max_bytes: int, truncate: bool = False, prefix: str = '', suffix: str = '', encoding: str = 'utf-8')
Ensures an incoming string fits in a specified number of bytes.
Note
The resulting value is always byte string (
bytestype).Initialises the MaxBytes filter.
- Parameters:
max_bytes – Max number of bytes to allow.
truncate –
How to handle values that are too long:
truncate is True: Return truncated string.truncate is False: Treat as invalid value.
prefix –
Prefix to apply to truncated values.
The prefix will count towards the number of bytes, so even with a prefix the resulting string will not exceed
max_bytesin length.Ignored when the incoming value is short enough, or when
truncate is False.suffix –
Suffix to apply to truncated values.
The suffix will count towards the number of bytes, so even with a suffix the resulting string will not exceed
max_bytesin length.Ignored when the incoming value is short enough, or when
truncate is False.encoding – The character encoding to check against.
- CODE_TOO_LONG = 'too_long'
- templates = {'exception': 'An error occurred while processing this value.', 'too_long': 'Value is too long (must be < {max_bytes} bytes when encoded using {encoding}).'}
- truncate_bytes(bytes_value: bytes) bytes
Truncates a too-long bytes value to the specified length.
Uses the filter’s current configuration to truncate the value.
- Parameters:
bytes_value – The bytes value to truncate.
- Returns:
Returns bytes, truncated to the correct length.
Note: Might be a bit shorter than
self.max_bytes, to avoid orphaning a multibyte sequence.
- class filters.string.MaxChars(max_chars: int, truncate: bool = False, prefix: str = '', suffix: str = '')
Ensures incoming value fits in a certain number of characters.
Note
The resulting value is always a unicode string (
strtype).Initialises the MaxChars filter.
- Parameters:
max_chars – Max number of characters to allow.
truncate –
How to handle values that are too long:
truncate is True: Return truncated string.truncate is False: Treat as invalid value.
prefix –
Prefix to apply to truncated values.
The prefix will count towards the max number of characters, so even with a prefix the resulting string will not exceed
max_charsin length.Ignored when the incoming value is short enough, or when
truncate is False.suffix –
Suffix to apply to truncated values.
The suffix will count towards the max number of characters, so even with a suffix the resulting string will not exceed
max_charsin length.Ignored when the incoming value is short enough, or when
truncate is False.
- CODE_TOO_LONG = 'too_long'
- templates = {'exception': 'An error occurred while processing this value.', 'too_long': 'Value is too long (must be < {max_chars} characters).'}
- class filters.string.Regex(pattern: str | Pattern)
Matches a regular expression in the value.
IMPORTANT: This filter returns a LIST of all sequences in the input value that matched the regex!
IMPORTANT: This Filter uses the
regexlibrary, which behaves slightly differently than Python’srelibrary.If you’ve never used
regexbefore, try it; you’ll never want to go back!Note
Reference: https://pypi.python.org/pypi/regex
Initialises the Regex filter.
- Parameters:
pattern –
String pattern, or pre-compiled regex.
IMPORTANT: If you specify your own compiled regex, be sure to add the
UNICODEflag for Unicode support!
- CODE_INVALID = 'malformed'
- pattern_types = (<class 're.Pattern'>, <class '_regex.Pattern'>)
- templates = {'exception': 'An error occurred while processing this value.', 'malformed': 'Value does not match regular expression {pattern}.'}
- class filters.string.Split(pattern: str | Pattern, keys: Sequence[str] | None = None)
Splits an incoming string into parts.
The result is either a list or a dict, depending on whether you specify keys to map to the result.
Initialises the Split filter.
- Parameters:
pattern –
Regex used to split incoming string values.
IMPORTANT: If you specify your own compiled regex, be sure to add the
UNICODEflag for Unicode support!keys –
If set, the resulting list will be converted into a dict, using the specified keys.
Important: If
keysis set, the split value’s length must be less than or equal tolen(keys).
- templates = {'exception': 'An error occurred while processing this value.'}
- class filters.string.Strip(leading: str = '[\\p{C}\\s]+', trailing: str = '[\\p{C}\\s]+')
Strips characters from the end(s) of a string.
Strips whitespace and non-printables by default.
IMPORTANT: This Filter uses the
regexlibrary, which behaves slightly differently than Python’srelibrary.If you’ve never used
regexbefore, try it; you’ll never want to go back!Initialises the Strip filter.
- Parameters:
leading – Regex to match at the start of the string.
trailing – Regex to match at the end of the string.
- templates = {'exception': 'An error occurred while processing this value.'}
- class filters.string.TomlDecode
Interprets the value as TOML.
- CODE_INVALID = 'not_toml'
- templates = {'exception': 'An error occurred while processing this value.', 'not_toml': 'This value is not valid TOML.'}
- class filters.string.Unicode(encoding: str = 'utf-8', normalize: bool = True)
Converts a value into a unicode string.
Note
By default, additional normalisation is applied to the resulting value. See the initialiser docstring for more info.
References:
Initialises the Unicode filter.
- Parameters:
encoding – Used to decode non-unicode values.
normalize –
Whether to normalise the resulting value:
Convert to NFC form.
Remove non-printable characters.
Convert all line endings to unix-style (’n’).
- CODE_DECODE_ERROR = 'wrong_encoding'
- templates = {'exception': 'An error occurred while processing this value.', 'wrong_encoding': 'This value cannot be decoded using {encoding}.'}
- class filters.string.Uuid(version: int | None = None)
Interprets an incoming value as a UUID.
Note
Reference: https://en.wikipedia.org/wiki/Uuid#RFC_4122_Variant
Initialises the Uuid filter.
- Parameters:
version – If specified, requires the resulting UUID to match the specified version.
- CODE_INVALID = 'not_uuid'
- CODE_WRONG_VERSION = 'wrong_version'
- templates = {'exception': 'An error occurred while processing this value.', 'not_uuid': 'This value is not a well-formed UUID.', 'wrong_version': 'v{incoming} UUID not allowed (expected v{expected}).'}
- class filters.test.BaseFilterTestCase(methodName='runTest')
Base functionality for request filter unit tests.
Prevents typos from causing invalid test passes/failures by abstracting the Filter type out of filtering ops; just set
filter_typeat the top of your test case, and then useassertFilterPassesandassertFilterErrorsto check use cases.Create an instance of the class that will use the named test method when executed. Raises a ValueError if the instance does not have a method with the specified name.
- assertFilterErrors(runner: Any, expected_codes: Mapping[str, Sequence[str]] | Sequence[str], expected_value: Any = None) FilterRunner
Asserts that the FilterRunner generates the specified errors.
- Parameters:
runner – Usually a FilterRunner instance, but you can pass in the test value itself if you want (it will automatically be run through _filter).
expected_codes – Expected error codes.
expected_value – Expected value for
runner.cleaned_data(usuallyNone).
- Returns:
The FilterRunner instance for further assertions.
- assertFilterPasses(runner: Any, expected_value: Any = <class 'filters.test.BaseFilterTestCase.unmodified'>) FilterRunner
Asserts that the FilterRunner returns the value without errors.
- Parameters:
runner – Usually a FilterRunner instance, but you can pass in the test value itself if you want (it will automatically be run through
_filter).expected_value –
The expected value for
runner.cleaned_data.If omitted, the assertion will check that the incoming value is returned unmodified.
- Returns:
The FilterRunner instance for further assertions.
- filter_type: Callable[[...], BaseFilter] = None
- class skip_value_check
Sentinel value to skip checking the filtered value.
Sentinel value; used by
assertFilterPassesto skip checking the filtered value. This is useful for tests where a simple equality check is not practical.Note
If you use
skip_value_check, you should add extra assertions to your test to make sure the filtered value conforms to expectations.
- class unmodified
Used by assertFilterPasses to omit expected_value parameter.
Used by
assertFilterPassesso that you can omit theexpected_valueparameter.