Validators
Context
BasicQuestion
allows the user to provide arbitrary text as the answer to the question. However, there are frequently
constraints on what is considered a valid answer. Providing a Validator
for the question allows columbo
to verify
that the text provided by the user satisfies those constraints. If the answer is not valid, columbo
will tell the user
that the answer is not valid and ask them to try again.
The default
value for the BasicQuestion
must satisfy the Validator
. An exception will be raised if that is not
the case. This is because it could lead to:
* An infinite loop when prompting a user
* Command line parsing always failing if a value is not given
Note
While Choice
and Confirm
do not expose a validator
argument they still ensure that the answer is valid.
A Confirm
question will only continue when Y, N, or Enter are pressed. Any other keys will be ignored.
A Choice
question will only continue when Enter is pressed if the input matches the number columbo
assigned
to one of the choices.
Validator Structure
A Validator
must be a function which has the following type signature: Callable[[str, Answers], ValidationResponse]
1. We'll walk through this signature explaining each part.
A Validator
takes two arguments: a string (which is the response provided by the user to a question) and an Answers
dictionary containing the answer for each previous question.
The Validator
must return a ValidationResponse
which is a type alias for: Union[ValidationFailure, ValidationSuccess]
1. Thus, a Validator
must return either a ValidationFailure
or a ValidationSuccess
object. You should use a ValidationSuccess
when the user's response is valid and ValidationFailure
when the user's response is invalid. Both ValidationFailure
and ValidationSuccess
have a valid
attribute that is False
and True
, respectively. A ValidationFailure
requires that you provide an error
which describes why the given value was invalid (columbo
will display this message before asking users to answer the question again so users get some feedback about what they are doing wrong).
Upgrading Validator Structure
Validators could return Optional[str]
before <0.10.0
, this was removed in 1.0.0
.
The docs in this section detail how to upgrade a Validator
from a columbo version < 0.10.0
to the newer Validator
structure. Feel free to skip this section if it's not pertinent to you.
Previously, a Validator
would return either an error message (as a string) if validation failed or None
if the validation succeeded. To update a Validator
, you should update the validator function to return ValidationFailure
if validation fails and ValidationSuccess
if the validation succeeds. The table below describes the old and new return values for different validation statuses.
Validation Status | Old Return Value (before 0.10.0 ) |
New Return Value (since 0.10.0 ) |
---|---|---|
Failed | "Some error message" | ValidationFailure(error="Some error message") |
Succeeded | None | ValidationSuccess() |
Example Validator
Let's say we were asking for a user's email address.
The Validator
below provides a simple check to see if
the email address seems valid1. If the user's response doesn't contain an @
character with at least one
word character on each side then the response is invalid and the user will have to
enter an email address again (hopefully a valid one this time).
import re
from typing import List
import columbo
def is_email_address(value: str, _: columbo.Answers) -> columbo.ValidationResponse:
if not re.match(r"^\w+@\w+", value):
error_message = f"{value} is not a valid email address"
return columbo.ValidationFailure(error=error_message)
return columbo.ValidationSuccess()
interactions: List[columbo.Interaction] = [
columbo.BasicQuestion(
"user_email_address",
"What email address should be used to contact you?",
default="me@example.com",
validator=is_email_address,
)
]
user_answers = columbo.get_answers(interactions)
print(user_answers)
-
The regular expression for checking for an RFC 822 compliant email address is overly complicated. Additionally, that only ensures that the text is valid. It does not confirm if the host will accept emails sent to that address or if the user is the owner of the email address. ↩↩↩