Form Validation

⚠️

Note: This is material for Rasa 2.x. The syntax has updated slightly in Rasa 3.0 so we recommend new users to check the new course found here.

Users will sometimes give us information that is invalid. That's why Rasa allows you to validate the data before it is stored in a slot.

Video


Code

The custom action that handles the validation is shown below.

from typing import Text, List, Any, Dict
from rasa_sdk import Tracker, FormValidationAction
from rasa_sdk.executor import CollectingDispatcher
from rasa_sdk.types import DomainDict
class ValidateNameForm(FormValidationAction):
def name(self) -> Text:
return "validate_name_form"
def validate_first_name(
self,
slot_value: Any,
dispatcher: CollectingDispatcher,
tracker: Tracker,
domain: DomainDict,
) -> Dict[Text, Any]:
"""Validate `first_name` value."""
# If the user is typing a super short name, it might be misspelled.
# Note that this is an assumption and it might not hold true depending
# on where your users live.
print(f"First name given = {slot_value} length = {len(slot_value)}")
if len(slot_value) <= 2:
dispatcher.utter_message(text=f"That's a very short name. I'm assuming you mis-spelled.")
return {"first_name": None}
else:
return {"first_name": slot_value}
def validate_last_name(
self,
slot_value: Any,
dispatcher: CollectingDispatcher,
tracker: Tracker,
domain: DomainDict,
) -> Dict[Text, Any]:
"""Validate `last_name` value."""
# If the user is typing a super short name, it might be misspelled.
# Note that this is an assumption and it might not hold true depending
# on where your users live.
print(f"Last name given = {slot_value} length = {len(slot_value)}")
if len(slot_value) <= 2:
dispatcher.utter_message(text=f"That's a very short name. I'm assuming you mis-spelled.")
return {"last_name": None}
else:
return {"last_name": slot_value}

The ValidateNameForm class implements the validation methods for the slots in the name_form. Note the naming conventions that are used in the class.

  • The name-method returns the name of the validator and it uses the

validate_<formname> naming convention.

  • There are two methods that check for slot values and they also adhere

to a naming convention validate_<slotname>. These methods will only check the slotnames for the name_form-form because these methods are part of a FormValidationAction.

If you want to invalidate a slot you need to return a dictionary that sets a name of a slot to None. It's usually a good idea to attach a user message when this happen so you can let the user know that something went wrong.

if len(slot_value) <= 2:
dispatcher.utter_message(text=f"That's a very short name. I'm assuming you mis-spelled.")
return {"first_name": None}
else:
return {"first_name": slot_value}

Protip

You may have noticed that our validator code contains a print statement. This is added to help us debug our code. In production you'll want to likely remove the print statement but it's highly recommended when you're just starting out.

Links

Exercises

Try to answer the following questions to test your knowledge.

  1. What is the naming convention used to name the method that will a slot in a FormValidationAction?
  2. What do you need to return if you want to invalidate a slot?
  3. Can you invalidate multiple slots at once in a validator?

2016-2022 © Rasa.