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 details)

Uploaded Source

Built Distribution

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

Uploaded Python 3

File details

Details for the file payload-validator-0.1.11.tar.gz.

File metadata

  • Download URL: payload-validator-0.1.11.tar.gz
  • Upload date:
  • Size: 16.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/5.0.0 CPython/3.11.4

File hashes

Hashes for payload-validator-0.1.11.tar.gz
Algorithm Hash digest
SHA256 426a8fa8fc5e331c085fdcd54c8822c437c7605cd25846f07f6b603f67c6ba50
MD5 c931af53547c1574949ed7b2cbf3cc75
BLAKE2b-256 543551b3293bc35e80b4e91c06efc4cd713c00e53fff7667d386c998dd23af9a

See more details on using hashes here.

File details

Details for the file payload_validator-0.1.11-py3-none-any.whl.

File metadata

File hashes

Hashes for payload_validator-0.1.11-py3-none-any.whl
Algorithm Hash digest
SHA256 83c47a44b08925ddd265deaa19d8d160d57ffeba84fb0c1af5b7dd76b3010d57
MD5 defd6459cf7a5f9478b4a3a63c06d41f
BLAKE2b-256 17664c474e42a41e88af8bf4da69b10fef5a41b138e4a5c68e55a64edddde4f5

See more details on using hashes here.

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