Skip to main content

Validating payload datas for Python

Project description

To validate the payload data.

Quick Start

pip install payload-validator

Example Code

CodeSandBox Link:

https://codesandbox.io/p/sandbox/payload-validator-zngckp?file=%2Fmain.py%3A1%2C1

More Example

Example List:

https://github.com/cwadven/payload-validator/blob/master/examples/example1.py

Explain

Normal ValidatorErrorContext Usage

using_this_payload.py:

from datetime import datetime
from payload_validator.exceptions import (
    InvalidValueError,
    ValidationException,
)
from utils import validate_date_parsing
from payload_validator.validators import PayloadValidator


def validate_date_parsing(date_str):
    try:
        datetime.strptime(date_str, '%Y-%m-%d')
        return True
    except (TypeError, ValueError):
        return False


# [ Examples of using validators ]
# 1. Inherit 'PayloadValidator' and define 'Meta class'
# 2. Define 'DEFAULT_MANDATORY_ERROR_MESSAGE' in 'PayloadValidator'
# 3-1. Define 'mandatory_keys' and 'type_of_keys' in 'Meta class'
# 3-2. 'mandatory_keys' is a 'dictionary' that contains key and error message
# 3-3. 'type_of_keys' is a 'dictionary' that contains key and type of key
# 3-4. 'type_of_keys' value of first index can contain 'function' returning 'boolean' accepted
# 4-1. Define 'validate_{key}' method in 'PayloadValidator'
# 4-2. 'validate_{key}' validating sequence is top to bottom code written in 'PayloadValidator'
# 4-3. If 'validate_{key}' raise 'InvalidValueError', it will be added to 'error_context'
# 4-4. 'InvalidValueError' 'error_value_by_key' input should be 'dictionary' that contains payload key and error message (this message could be iterator)
# 4-5. 'InvalidValueError' input can contain 'ignore_existing_error_keys' which skip if there is already payload key of error
# 5. Can override 'common_validate' method to add 'common_validation'
# 6. Validating Sequence: Mandatory Check -> Type Check -> validate_{key} (top from bottom code) -> common_validate
# 7. Use 'validate()' method to validate payload or execute 'is_valid()' method to check validation even once
# 8. 'ValidationException' will raise when error exists

# [ Extra Information ]
# you can use 'add_error_context' or 'add_error_and_skip_validation_key'
# instead of 'InvalidValueError' to define errors

# 1
class NewPayloadValidator(PayloadValidator):
    # 2
    DEFAULT_MANDATORY_ERROR_MESSAGE = 'mandatory data missing2'

    class Meta:
        # 3-1, 3-2
        mandatory_keys = {
            'displayable': 'displayable is required',
            'mode': 'mode is always required',
            'amount': 'why are you not setting amount?',
            'minimum_order_value': 'minimum order value is required',
            'applicable_order_types': 'really you are not setting applicable order types?',
            'start_date': 'start date is required',
            'end_date': 'end date is required for your job',
        }
        # 3-1, 3-3
        type_of_keys = {
            'amount': [int, 'integer_type_needs'],
            'minimum_order_value': [int, 'integer_type_needs'],
            'maximum_download_count': [(int, type(None)), 'integer_type_needs or NoneType'],
            # 3-4
            'start_date': [validate_date_parsing, 'need to be date type'],
            'end_date': [validate_date_parsing, 'need to be date type'],
        }

    # 4-1, 4-2
    def validate_hello_world(self):
        if not self.get_payload('displayable'):
            # 4-3, 4-4
            raise InvalidValueError({'displayable': 'displayable is false'})

    # 4-1, 4-2
    def validate_max_length(self):
        if self.get_payload('max_length') <= 0:
            # 4-3, 4-4, 4-5
            raise InvalidValueError(
                {
                    'max_length': 'min_length should be greater than 0'
                },
                ignore_existing_error_keys=['max_length']
            )

    # 5
    def common_validate(self):
        if self.get_payload('max_length') < self.get_payload('min_length'):
            raise InvalidValueError(
                {
                    'max_length': 'max_length should be greater than min_length',
                    'min_length': 'min_length should be lesser than max_length'
                },
            )



validator = NewPayloadValidator({'displayable': True, 'start_date': 1, 'min_length': 10, 'max_length': 0})

try:
    # 7
    validator.validate()
except ValidationException as e:
    print(validator.error_context)

# 8
if not validator.is_valid():
    print(validator.error_context)

# [ Result ]
# {
#     'mode': ['mode is always required'],
#     'amount': ['why are you not setting amount?'],
#     'minimum_order_value': ['minimum order value is required'],
#     'applicable_order_types': ['really you are not setting applicable order types?'],
#     'end_date': ['end date is required for your job'],
#     'start_date': ['need to be date type'],
#     'max_length': ['min_length should be greater than 0'],
#     'min_length': ['min_length should be lesser than max_length']
# }

Custom ValidatorErrorContext Usage

custom_using_this_payload.py:

from datetime import datetime
from payload_validator.exceptions import (
    InvalidValueError,
    ValidationException,
)
from utils import validate_date_parsing
from payload_validator.validators import PayloadValidator, ValidatorErrorContext

def validate_date_parsing(date_str):
    try:
        datetime.strptime(date_str, '%Y-%m-%d')
        return True
    except (TypeError, ValueError):
        return False

# [ Examples of using validators ]
# 1. Inherit 'PayloadValidator' and define 'Meta class'
# 2. Define 'DEFAULT_MANDATORY_ERROR_MESSAGE' in 'PayloadValidator'
# 3-1. Define 'mandatory_keys' and 'type_of_keys' in 'Meta class'
# 3-2. 'mandatory_keys' is a 'dictionary' that contains key and error message
# 3-3. 'type_of_keys' is a 'dictionary' that contains key and type of key
# 3-4. 'type_of_keys' value of first index can contain 'function' returning 'boolean' accepted
# 4-1. Define 'validate_{key}' method in 'PayloadValidator'
# 4-2. 'validate_{key}' validating sequence is top to bottom code written in 'PayloadValidator'
# 4-3. If 'validate_{key}' raise 'InvalidValueError', it will be added to 'error_context'
# 4-4. 'InvalidValueError' 'error_value_by_key' input should be 'dictionary' that contains payload key and error message (this message could be iterator)
# 4-5. 'InvalidValueError' input can contain 'ignore_existing_error_keys' which skip if there is already payload key of error
# 5. Can override 'common_validate' method to add 'common_validation'
# 6. Validating Sequence: Mandatory Check -> Type Check -> validate_{key} (top from bottom code) -> common_validate
# 7. Use 'validate()' method to validate payload or execute 'is_valid()' method to check validation even once
# 8. 'ValidationException' will raise when error exists

# [ Extra Information ]
# you can use 'add_error_context' or 'add_error_and_skip_validation_key'
# instead of 'InvalidValueError' to define errors

# Extra: Customize Error Context
# 'ColorValidatorErrorContext' is a 'PayloadValidator' can return error message with color
class ColorValidatorErrorContext(ValidatorErrorContext):
    DEFAULT_COLOR = '#FFFFFF'

    def add_error(self, field: str, error: str):
        value = self.setdefault(field, [])
        try:
            error, color = error.split(',')
        except (IndexError, ValueError):
            color = self.DEFAULT_COLOR
        value.append([error, color])


# 1
class ColorPayloadValidator(PayloadValidator):
    # 2
    DEFAULT_MANDATORY_ERROR_MESSAGE = 'mandatory data missing2'

    class Meta:
        # 3-1, 3-2
        mandatory_keys = {
            'displayable': 'displayable is required',
            'mode': 'mode is always required',
            'amount': 'why are you not setting amount?',
            'minimum_order_value': 'minimum order value is required',
            'applicable_order_types': 'really you are not setting applicable order types?',
            'start_date': 'start date is required',
            'end_date': 'end date is required for your job',
        }
        # 3-1, 3-3
        type_of_keys = {
            'amount': [int, 'integer_type_needs'],
            'minimum_order_value': [int, 'integer_type_needs'],
            'maximum_download_count': [(int, type(None)), 'integer_type_needs or NoneType'],
            # 3-4
            'start_date': [validate_date_parsing, 'need to be date type'],
            'end_date': [validate_date_parsing, 'need to be date type'],
        }

    # 4-1, 4-2
    def validate_hello_world(self):
        if not self.get_payload('displayable'):
            # 4-3, 4-4
            raise InvalidValueError({'displayable': 'displayable is false,#123456'})

    # 4-1, 4-2
    def validate_max_length(self):
        if self.get_payload('max_length') <= 0:
            # 4-3, 4-4, 4-5
            raise InvalidValueError(
                {
                    'max_length': 'min_length should be greater than 0,#000000'
                },
                ignore_existing_error_keys=['max_length']
            )

    # 5
    def common_validate(self):
        if self.get_payload('max_length') < self.get_payload('min_length'):
            raise InvalidValueError(
                {
                    'max_length': 'max_length should be greater than min_length,#000000',
                    'min_length': 'min_length should be lesser than max_length,#123123'
                },
            )


validator = ColorPayloadValidator(
    {'displayable': True, 'start_date': 1, 'min_length': 10, 'max_length': 0},
    ColorValidatorErrorContext(),
)

try:
    # 7
    validator.validate()
except ValidationException as e:
    print(validator.error_context)

# 8
if not validator.is_valid():
    print(validator.error_context)

# [ Result ]
# {
#     'mode': [['mode is always required', '#FFFFFF']],
#     'amount': [['why are you not setting amount?', '#FFFFFF']],
#     'minimum_order_value': [['minimum order value is required', '#FFFFFF']],
#     'applicable_order_types': [['really you are not setting applicable order types?', '#FFFFFF']],
#     'end_date': [['end date is required for your job', '#FFFFFF']],
#     'start_date': [['need to be date type', '#FFFFFF']],
#     'max_length': [['min_length should be greater than 0', '#000000']],
#     'min_length': [['min_length should be lesser than max_length', '#123123']]
# }

Extra

Issue or Pull Request are welcome.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

payload-validator-0.1.11.tar.gz (16.6 kB view hashes)

Uploaded Source

Built Distribution

payload_validator-0.1.11-py3-none-any.whl (17.8 kB view hashes)

Uploaded Python 3

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page