Source code for cryptnox_cli.wallet.validators

# -*- coding: utf-8 -*-
"""
Module for defining validators
"""
import re
from abc import ABC, abstractmethod
from typing import Any


[docs] class ValidationError(Exception): """ Exception for indicating that validation criteria are not met """
[docs] class Validator(ABC): """ Validator class defining setters and getters """
[docs] def __init__(self, valid_values: str = None): self.valid_values = valid_values self.name = None
def __set_name__(self, owner, name): self.name = f"_{name}" def __get__(self, instance, instance_type=None): return getattr(instance, self.name) def __set__(self, instance, value): value = self.validate(value) setattr(instance, self.name, value)
[docs] @abstractmethod def validate(self, value): """ :param value: Evaluated value :return: None :raise ValidationError: Validation criteria not satisfied """
[docs] class AnyValidator(Validator):
[docs] def validate(self, value): return value
[docs] class IntValidator(Validator): """ Class for validating if value is integer """
[docs] def __init__(self, max_value: int = None, min_value: int = None): self.max_value = max_value self.min_value = min_value super().__init__(None)
[docs] def validate(self, value) -> int: if not is_int(value): raise ValidationError("Number must be integer") if self.min_value and self.max_value \ and self.min_value > int(value) > self.max_value: raise ValidationError(f"Number must be integer larger than: " f"{self.min_value} and smaller " f"than {self.max_value}") return int(float(value))
[docs] class EnumValidator(Validator): """ Class for validating if value is part of the enum """
[docs] def __init__(self, current_enum): super().__init__("\n".join(value.name for value in current_enum)) self.current_enum = current_enum
[docs] def validate(self, value) -> None: value = value.upper() try: self.current_enum[value] except LookupError as error: raise ValidationError("Invalid value") from error return value
[docs] class UrlValidator(Validator): """ Class for validating URLs """
[docs] def validate(self, value: str) -> str: regex = re.compile( r'^(?:http|ftp)s?://' # http:// or https:// r'(?:(?:[A-Z0-9](?:[A-Z0-9-]{0,61}[A-Z0-9])?\.)+(?:[A-Z]{2,6}\.?' r'|[A-Z0-9-]{2,}\.?)|' # domain... r'localhost|' # localhost... r'\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})' # ...or ip r'(?::\d+)?' # optional port r'(?:/?|[/?]\S+)$', re.IGNORECASE) if re.match(regex, value) is None: raise ValidationError("Invalid value for the URL") return value
[docs] def is_int(value: Any) -> bool: value = str(value) if value[0] in ('-', '+'): return value[1:].isdigit() else: return value.isdigit()