Spaces:
Sleeping
Sleeping
"""Module contains pre-built validators.""" | |
import re | |
from pathlib import Path | |
from typing import Optional | |
from prompt_toolkit.validation import ValidationError, Validator | |
__all__ = [ | |
"PathValidator", | |
"EmptyInputValidator", | |
"PasswordValidator", | |
"NumberValidator", | |
] | |
class NumberValidator(Validator): | |
""":class:`~prompt_toolkit.validation.Validator` to validate if input is a number. | |
Args: | |
message: Error message to display in the validatation toolbar when validation failed. | |
float_allowed: Allow input to contain floating number (with decimal). | |
""" | |
def __init__( | |
self, message: str = "Input should be a number", float_allowed: bool = False | |
) -> None: | |
self._message = message | |
self._float_allowed = float_allowed | |
def validate(self, document) -> None: | |
"""Check if user input is a valid number. | |
This method is used internally by `prompt_toolkit <https://python-prompt-toolkit.readthedocs.io/en/master/>`_. | |
See Also: | |
https://python-prompt-toolkit.readthedocs.io/en/master/pages/asking_for_input.html?highlight=validator#input-validation | |
""" | |
try: | |
if self._float_allowed: | |
float(document.text) | |
else: | |
int(document.text) | |
except ValueError: | |
raise ValidationError( | |
message=self._message, cursor_position=document.cursor_position | |
) | |
class PathValidator(Validator): | |
""":class:`~prompt_toolkit.validation.Validator` to validate if input is a valid filepath on the system. | |
Args: | |
message: Error message to display in the validatation toolbar when validation failed. | |
is_file: Explicitly check if the input is a valid file on the system. | |
is_dir: Explicitly check if the input is a valid directory/folder on the system. | |
""" | |
def __init__( | |
self, | |
message: str = "Input is not a valid path", | |
is_file: bool = False, | |
is_dir: bool = False, | |
) -> None: | |
self._message = message | |
self._is_file = is_file | |
self._is_dir = is_dir | |
def validate(self, document) -> None: | |
"""Check if user input is a filepath that exists on the system based on conditions. | |
This method is used internally by `prompt_toolkit <https://python-prompt-toolkit.readthedocs.io/en/master/>`_. | |
See Also: | |
https://python-prompt-toolkit.readthedocs.io/en/master/pages/asking_for_input.html?highlight=validator#input-validation | |
""" | |
path = Path(document.text).expanduser() | |
if self._is_file and not path.is_file(): | |
raise ValidationError( | |
message=self._message, | |
cursor_position=document.cursor_position, | |
) | |
elif self._is_dir and not path.is_dir(): | |
raise ValidationError( | |
message=self._message, | |
cursor_position=document.cursor_position, | |
) | |
elif not path.exists(): | |
raise ValidationError( | |
message=self._message, | |
cursor_position=document.cursor_position, | |
) | |
class EmptyInputValidator(Validator): | |
""":class:`~prompt_toolkit.validation.Validator` to validate if the input is empty. | |
Args: | |
message: Error message to display in the validatation toolbar when validation failed. | |
""" | |
def __init__(self, message: str = "Input cannot be empty") -> None: | |
self._message = message | |
def validate(self, document) -> None: | |
"""Check if user input is empty. | |
This method is used internally by `prompt_toolkit <https://python-prompt-toolkit.readthedocs.io/en/master/>`_. | |
See Also: | |
https://python-prompt-toolkit.readthedocs.io/en/master/pages/asking_for_input.html?highlight=validator#input-validation | |
""" | |
if not len(document.text) > 0: | |
raise ValidationError( | |
message=self._message, | |
cursor_position=document.cursor_position, | |
) | |
class PasswordValidator(Validator): | |
""":class:`~prompt_toolkit.validation.Validator` to validate password compliance. | |
Args: | |
message: Error message to display in the validatation toolbar when validation failed. | |
length: The minimum length of the password. | |
cap: Password should include at least one capital letter. | |
special: Password should include at least one special char "@$!%*#?&". | |
number: Password should include at least one number. | |
""" | |
def __init__( | |
self, | |
message: str = "Input is not compliant with the password constraints", | |
length: Optional[int] = None, | |
cap: bool = False, | |
special: bool = False, | |
number: bool = False, | |
) -> None: | |
password_pattern = r"^" | |
if cap: | |
password_pattern += r"(?=.*[A-Z])" | |
if special: | |
password_pattern += r"(?=.*[@$!%*#?&])" | |
if number: | |
password_pattern += r"(?=.*[0-9])" | |
password_pattern += r"." | |
if length: | |
password_pattern += r"{%s,}" % length | |
else: | |
password_pattern += r"*" | |
password_pattern += r"$" | |
self._re = re.compile(password_pattern) | |
self._message = message | |
def validate(self, document) -> None: | |
"""Check if user input is compliant with the specified password constraints. | |
This method is used internally by `prompt_toolkit <https://python-prompt-toolkit.readthedocs.io/en/master/>`_. | |
See Also: | |
https://python-prompt-toolkit.readthedocs.io/en/master/pages/asking_for_input.html?highlight=validator#input-validation | |
""" | |
if not self._re.match(document.text): | |
raise ValidationError( | |
message=self._message, cursor_position=document.cursor_position | |
) | |