1

I am using the Python package named Clint to prettify the inputs necessary in my application. In the package you can access the module validators and use it combined with prompt to properly ask users to input data.

I was looking for a possibility to implement a custom validator in Clint, due to a relatively short list of built-in classes of validators in the module:

[FileValidator, IntegerValidator, OptionValidator, PathValidator, RegexValidator, ValidationError]

So I wrote the code bellow:

from clint.textui import prompt, validators

class NumberValidator(object):
    message = 'Input is not valid.'

    def __init__(self, message=None):
        if message is not None:
            self.message = message

    def __call__(self, value):
        """
        Validates the input.
        """
        try:
            if int(value) > 10:
                return value
            else:
                raise ValueError() 
        except (TypeError, ValueError):
            raise validators.ValidationError(self.message)

answer = prompt.query(f'Insert range in days:',
                      '365',
                      validators=[NumberValidator("Must to be > 10")],
                      batch=False)
print(answer)

It works, but I found the solution a bit messy. That is because using this solution I have to create a new class every time I need to perform a new different type of validation.

I think it would be better if somehow the class could be dynamic using decorators, accepting a new function each time it would be initiated. But I found myself really bad in the decorators' subject.

So I ask you to help me to make a more Pythonic solution to this problem.

Arnold Souza
  • 601
  • 5
  • 16

1 Answers1

0

Not sure if this is the best way, but I may found a way better to this issue. In the code bellow I can create as much custom functions as I want (custom_validation_1, custom_validation_2, custom_validation_3...) and then just change the parameter validators in the prompt.query

from clint.textui import prompt, validators


class InputValidator(object):
    message = 'Input is not valid.'

    def __init__(self, fun, message=None, *args):
        if message is not None:
            self.message = message
        self.my_function = fun
        self.my_args = args

    def __call__(self, value):
        """
        Validates the input.
        """
        try:
            return self.my_function(value, *self.my_args)
        except (TypeError, ValueError):
            raise validators.ValidationError(self.message)


def custom_validation_1(value, number):
    if int(value) > int(number):
        return value
    else:
        raise ValueError


answer = prompt.query(f'Insert range in days:',
                      '365',
                      validators=[InputValidator(custom_validation_1,
                                                 "Must to be greater than 10",
                                                 10)],
                      batch=False)
print(answer)
Arnold Souza
  • 601
  • 5
  • 16