radubulimac's picture
fix import issue
2d876d1
raw
history blame
5.91 kB
"""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
)