diff --git a/changelog/6487.removal.md b/changelog/6487.removal.md new file mode 100644 index 000000000000..6e12da5f72c4 --- /dev/null +++ b/changelog/6487.removal.md @@ -0,0 +1,3 @@ +Remove backwards compatibility code with Rasa Open Source 1.x, Rasa Enterprise 0.35, and other outdated +backwards compatibility code in `rasa.cli.x`, `rasa.core.utils`, `rasa.model_testing`, `rasa.model_training` +and `rasa.shared.core.events`. diff --git a/data/test_dialogues/default.json b/data/test_dialogues/default.json deleted file mode 100644 index e915b2c05cc3..000000000000 --- a/data/test_dialogues/default.json +++ /dev/null @@ -1,79 +0,0 @@ -{ - "py/object": "rasa.shared.core.conversation.Dialogue", - "name": "default", - "events": [ - { - "py/object": "rasa.shared.core.events.ActionExecuted", - "action_name": "action_listen", - "action_text": null, - "confidence": null, - "policy": null, - "timestamp": 1551952977.4850519, - "unpredictable": false, - "hide_rule_turn": false - }, - { - "py/object": "rasa.shared.core.events.UserUttered", - "entities": [ - { - "end": 19, - "entity": "name", - "start": 14, - "value": "Peter" - } - ], - "input_channel": null, - "intent": { - "confidence": 0.0, - "name": "greet" - }, - "message_id": null, - "parse_data": { - "entities": [ - { - "end": 19, - "entity": "name", - "start": 14, - "value": "Peter" - } - ], - "intent": { - "confidence": 0.0, - "name": "greet" - }, - "message_id": null, - "metadata": {}, - "text": "Hi my name is Peter" - }, - "text": "Hi my name is Peter", - "timestamp": 1551953035.076376, - "use_text_for_featurization": false - }, - { - "py/object": "rasa.shared.core.events.SlotSet", - "key": "name", - "timestamp": 1551953035.076385, - "value": "Peter" - }, - { - "py/object": "rasa.shared.core.events.ActionExecuted", - "action_name": "utter_greet", - "action_text": null, - "confidence": null, - "policy": null, - "timestamp": 1551953040.607782, - "unpredictable": false, - "hide_rule_turn": false - }, - { - "py/object": "rasa.shared.core.events.BotUttered", - "data": { - "attachment": null, - "buttons": null, - "elements": null - }, - "text": "hey there Peter!", - "timestamp": 1551953040.60779 - } - ] -} diff --git a/data/test_dialogues/formbot.json b/data/test_dialogues/formbot.json deleted file mode 100644 index 5a84c1b3c829..000000000000 --- a/data/test_dialogues/formbot.json +++ /dev/null @@ -1,214 +0,0 @@ -{ - "py/object":"rasa.shared.core.conversation.Dialogue", - "name":"formbot", - "events":[ - { - "py/object":"rasa.shared.core.events.ActionExecuted", - "action_name":"action_listen", - "action_text": null, - "confidence":null, - "policy":null, - "timestamp":1551884035.892855, - "unpredictable":false, - "hide_rule_turn": false - }, - { - "py/object":"rasa.shared.core.events.UserUttered", - "entities":[ - - ], - "input_channel":null, - "intent":{ - "confidence":0.3748943507671356, - "name":"greet" - }, - "message_id":null, - "parse_data":{ - "entities":[ - - ], - "intent":{ - "confidence":0.3748943507671356, - "name":"greet" - }, - "text":"Hi I'm desperate to talk to you" - }, - "text":"Hi I'm desperate to talk to you", - "timestamp":1551884050.259948, - "use_text_for_featurization": false - }, - { - "py/object":"rasa.shared.core.events.ActionExecuted", - "action_name":"utter_greet", - "action_text": null, - "confidence":1.0, - "policy":"policy_2_MemoizationPolicy", - "timestamp":1551884060.466681, - "unpredictable":false, - "hide_rule_turn": false - }, - { - "py/object":"rasa.shared.core.events.BotUttered", - "data":{ - "attachment":null, - "buttons":null, - "elements":null - }, - "text":"Hello! I am restaurant search assistant! How can I help?", - "timestamp":1551884060.46669 - }, - { - "py/object":"rasa.shared.core.events.ActionExecuted", - "action_name":"action_listen", - "action_text": null, - "confidence":1.0, - "policy":"policy_2_MemoizationPolicy", - "timestamp":1551884061.9350882, - "unpredictable":false, - "hide_rule_turn": false - }, - { - "py/object":"rasa.shared.core.events.UserUttered", - "entities":[ - { - "end":18, - "entity":"cuisine", - "start":16, - "value":"an" - }, - { - "end":48, - "entity":"location", - "start":42, - "value":"Bombay" - } - ], - "input_channel":null, - "intent":{ - "confidence":0.9414282441139221, - "name":"request_restaurant" - }, - "message_id":null, - "parse_data":{ - "entities":[ - { - "end":18, - "entity":"cuisine", - "start":16, - "value":"an" - }, - { - "end":48, - "entity":"location", - "start":42, - "value":"Bombay" - } - ], - "intent":{ - "confidence":0.9414282441139221, - "name":"request_restaurant" - }, - "text":"I'm looking for an indian restaurant...in Bombay" - }, - "text":"I'm looking for an indian restaurant...in Bombay", - "timestamp":1551884090.9653602, - "use_text_for_featurization": false - }, - { - "py/object":"rasa.shared.core.events.ActionExecuted", - "action_name":"restaurant_form", - "action_text": null, - "confidence":1.0, - "policy":"policy_2_MemoizationPolicy", - "timestamp":1551884095.542748, - "unpredictable":false, - "hide_rule_turn": false - }, - { - "py/object":"rasa.shared.core.events.ActionExecuted", - "action_name":"utter_slots_values", - "action_text": null, - "confidence":1.0, - "policy":"policy_2_MemoizationPolicy", - "timestamp":1551884097.570883, - "unpredictable":false, - "hide_rule_turn": false - }, - { - "py/object":"rasa.shared.core.events.BotUttered", - "data":{ - "attachment":null, - "buttons":null, - "elements":null - }, - "text":"I am going to run a restaurant search using the following parameters:\n - cuisine: None\n - num_people: None\n - outdoor_seating: None\n - preferences: None\n - feedback: None", - "timestamp":1551884097.57089 - }, - { - "py/object":"rasa.shared.core.events.ActionExecuted", - "action_name":"action_listen", - "action_text": null, - "confidence":1.0, - "policy":"policy_2_MemoizationPolicy", - "timestamp":1551884098.8006358, - "unpredictable":false, - "hide_rule_turn": false - }, - { - "py/object":"rasa.shared.core.events.UserUttered", - "entities":[ - - ], - "input_channel":null, - "intent":{ - "confidence":0.2287036031484604, - "name":"affirm" - }, - "message_id":null, - "parse_data":{ - "entities":[ - - ], - "intent":{ - "confidence":0.2287036031484604, - "name":"affirm" - }, - "text":"Let's just pretend everything went correctly" - }, - "text":"Let's just pretend everything went correctly", - "timestamp":1551884208.092693, - "use_text_for_featurization": false - }, - { - "py/object":"rasa.shared.core.events.ActionExecuted", - "action_name":"action_deactivate_loop", - "action_text": null, - "confidence":null, - "policy":null, - "timestamp":1551884214.951055, - "unpredictable":false, - "hide_rule_turn": false - }, - { - "py/object":"rasa.shared.core.events.ActiveLoop", - "name":null, - "timestamp":1551884214.9510589 - }, - { - "py/object":"rasa.shared.core.events.SlotSet", - "key":"requested_slot", - "timestamp":1551884214.951062, - "value":null - }, - { - "py/object":"rasa.shared.core.events.ActionExecuted", - "action_name":"action_listen", - "action_text": null, - "confidence":0.7680902069097734, - "policy":"policy_0_TEDPolicy", - "timestamp":1551884216.705635, - "unpredictable":false, - "hide_rule_turn": false - } - ] -} \ No newline at end of file diff --git a/data/test_dialogues/moodbot.json b/data/test_dialogues/moodbot.json deleted file mode 100644 index e134a07535d1..000000000000 --- a/data/test_dialogues/moodbot.json +++ /dev/null @@ -1,278 +0,0 @@ -{ - "py/object":"rasa.shared.core.conversation.Dialogue", - "name":"moodbot", - "events":[ - { - "py/object":"rasa.shared.core.events.ActionExecuted", - "action_name":"action_listen", - "action_text": null, - "confidence":null, - "policy":null, - "timestamp":1551883958.346432, - "unpredictable":false, - "hide_rule_turn": false - }, - { - "py/object":"rasa.shared.core.events.UserUttered", - "entities":[ - - ], - "input_channel":null, - "intent":{ - "confidence":0.44488201660555066, - "name":"greet" - }, - "message_id":null, - "parse_data":{ - "entities":[ - - ], - "intent":{ - "confidence":0.44488201660555066, - "name":"greet" - }, - "intent_ranking":[ - { - "confidence":0.44488201660555066, - "name":"greet" - }, - { - "confidence":0.29023286595689257, - "name":"goodbye" - }, - { - "confidence":0.10501227521380094, - "name":"mood_great" - }, - { - "confidence":0.06879303900502878, - "name":"mood_unhappy" - }, - { - "confidence":0.04903582960375451, - "name":"deny" - }, - { - "confidence":0.04204397361497238, - "name":"affirm" - } - ], - "text":"Hi talk to me" - }, - "text":"Hi talk to me", - "timestamp":1551883971.410778, - "use_text_for_featurization": false - }, - { - "py/object":"rasa.shared.core.events.ActionExecuted", - "action_name":"utter_greet", - "action_text": null, - "confidence":1.0, - "policy":"policy_2_MemoizationPolicy", - "timestamp":1551883975.6456478, - "unpredictable":false, - "hide_rule_turn": false - }, - { - "py/object":"rasa.shared.core.events.BotUttered", - "data":{ - "attachment":null, - "buttons":[ - { - "payload":"great", - "title":"great" - }, - { - "payload":"super sad", - "title":"super sad" - } - ], - "elements":null - }, - "text":"Hey! How are you?", - "timestamp":1551883975.645656 - }, - { - "py/object":"rasa.shared.core.events.ActionExecuted", - "action_name":"action_listen", - "action_text": null, - "confidence":1.0, - "policy":"policy_2_MemoizationPolicy", - "timestamp":1551883979.098331, - "unpredictable":false, - "hide_rule_turn": false - }, - { - "py/object":"rasa.shared.core.events.UserUttered", - "entities":[ - - ], - "input_channel":null, - "intent":{ - "confidence":0.7417646502470048, - "name":"mood_unhappy" - }, - "message_id":null, - "parse_data":{ - "entities":[ - - ], - "intent":{ - "confidence":0.7417646502470048, - "name":"mood_unhappy" - }, - "intent_ranking":[ - { - "confidence":0.7417646502470048, - "name":"mood_unhappy" - }, - { - "confidence":0.1439688162980615, - "name":"mood_great" - }, - { - "confidence":0.04577343822867981, - "name":"goodbye" - }, - { - "confidence":0.037760394267609965, - "name":"greet" - }, - { - "confidence":0.017715563733253295, - "name":"affirm" - }, - { - "confidence":0.013017137225390567, - "name":"deny" - } - ], - "text":"Super sad" - }, - "text":"Super sad", - "timestamp":1551883982.540276, - "use_text_for_featurization": false - }, - { - "py/object":"rasa.shared.core.events.ActionExecuted", - "action_name":"utter_cheer_up", - "action_text": null, - "confidence":1.0, - "policy":"policy_2_MemoizationPolicy", - "timestamp":1551883985.031668, - "unpredictable":false, - "hide_rule_turn": false - }, - { - "py/object":"rasa.shared.core.events.BotUttered", - "data":{ - "attachment":"https://i.imgur.com/nGF1K8f.jpg", - "buttons":null, - "elements":null - }, - "text":"Here is something to cheer you up:", - "timestamp":1551883985.0316749 - }, - { - "py/object":"rasa.shared.core.events.ActionExecuted", - "action_name":"utter_did_that_help", - "action_text": null, - "confidence":1.0, - "policy":"policy_2_MemoizationPolicy", - "timestamp":1551883985.940413, - "unpredictable":false, - "hide_rule_turn": false - }, - { - "py/object":"rasa.shared.core.events.BotUttered", - "data":{ - "attachment":null, - "buttons":null, - "elements":null - }, - "text":"Did that help you?", - "timestamp":1551883985.940421 - }, - { - "py/object":"rasa.shared.core.events.ActionExecuted", - "action_name":"action_listen", - "action_text": null, - "confidence":1.0, - "policy":"policy_2_MemoizationPolicy", - "timestamp":1551883986.958556, - "unpredictable":false, - "hide_rule_turn": false - }, - { - "py/object":"rasa.shared.core.events.UserUttered", - "entities":[ - - ], - "input_channel":null, - "intent":{ - "confidence":0.8162296627642036, - "name":"deny" - }, - "message_id":null, - "parse_data":{ - "entities":[ - - ], - "intent":{ - "confidence":0.8162296627642036, - "name":"deny" - }, - "intent_ranking":[ - { - "confidence":0.8162296627642036, - "name":"deny" - }, - { - "confidence":0.07152463661481759, - "name":"mood_unhappy" - }, - { - "confidence":0.05028159510181415, - "name":"greet" - }, - { - "confidence":0.02662414324721426, - "name":"affirm" - }, - { - "confidence":0.024343883584915963, - "name":"goodbye" - }, - { - "confidence":0.010996078687034375, - "name":"mood_great" - } - ], - "text":"No" - }, - "text":"No", - "timestamp":1551883989.0720608, - "use_text_for_featurization": false - }, - { - "py/object":"rasa.shared.core.events.ActionExecuted", - "action_name":"utter_goodbye", - "action_text": null, - "confidence":1.0, - "policy":"policy_2_MemoizationPolicy", - "timestamp":1551883991.061463, - "unpredictable":false, - "hide_rule_turn": false - }, - { - "py/object":"rasa.shared.core.events.BotUttered", - "data":{ - "attachment":null, - "buttons":null, - "elements":null - }, - "text":"Bye", - "timestamp":1551883991.061471 - } - ] -} \ No newline at end of file diff --git a/rasa/cli/x.py b/rasa/cli/x.py index 60fdb139ecf2..a284b91142d4 100644 --- a/rasa/cli/x.py +++ b/rasa/cli/x.py @@ -493,28 +493,14 @@ def run_locally(args: argparse.Namespace) -> None: # noinspection PyBroadException try: - try: - local.main( - args, - project_path, - args.data, - token=rasa_x_token, - config_path=config_path, - domain_path=domain_path, - ) - except TypeError as e: - if "domain_path" in str(e): - # backwards compatibility with Rasa X versions < 0.35.0 - # fixes regression https://github.com/RasaHQ/rasa/issues/7592 - local.main( - args, - project_path, - args.data, - token=rasa_x_token, - config_path=config_path, - ) - else: - raise + local.main( + args, + project_path, + args.data, + token=rasa_x_token, + config_path=config_path, + domain_path=domain_path, + ) except RasaXTermsError: # User didn't accept the Rasa X terms. pass diff --git a/rasa/core/utils.py b/rasa/core/utils.py index 3b94f849a20c..95a940b4dcca 100644 --- a/rasa/core/utils.py +++ b/rasa/core/utils.py @@ -19,8 +19,6 @@ from rasa.constants import DEFAULT_SANIC_WORKERS, ENV_SANIC_WORKERS from rasa.shared.constants import DEFAULT_ENDPOINTS_PATH -# backwards compatibility 1.0.x -# noinspection PyUnresolvedReferences from rasa.core.lock_store import LockStore, RedisLockStore, InMemoryLockStore from rasa.utils.endpoints import EndpointConfig, read_endpoint_config from sanic import Sanic diff --git a/rasa/model_testing.py b/rasa/model_testing.py index 584c03363181..ee60ed25cfc8 100644 --- a/rasa/model_testing.py +++ b/rasa/model_testing.py @@ -127,10 +127,6 @@ def test_core_models( ) -# backwards compatibility -test = rasa.test - - def test_core( model: Optional[Text] = None, stories: Optional[Text] = None, diff --git a/rasa/model_training.py b/rasa/model_training.py index 3acabed1089f..2c9930f2150f 100644 --- a/rasa/model_training.py +++ b/rasa/model_training.py @@ -51,10 +51,6 @@ class TrainingResult(NamedTuple): code: int = 0 -# backwards compatibility -train = rasa.train - - async def train_async( domain: Union[Domain, Text], config: Text, diff --git a/rasa/shared/core/events.py b/rasa/shared/core/events.py index 7d5213e3ff9b..a546dc06614d 100644 --- a/rasa/shared/core/events.py +++ b/rasa/shared/core/events.py @@ -247,19 +247,7 @@ def __init__( metadata: Optional[Dict[Text, Any]] = None, ) -> None: self.timestamp = timestamp or time.time() - self._metadata = metadata or {} - - @property - def metadata(self) -> Dict[Text, Any]: - # Needed for compatibility with Rasa versions <1.4.0. Previous versions - # of Rasa serialized trackers using the pickle module. For the moment, - # Rasa still supports loading these serialized trackers with pickle, - # but will use JSON in any subsequent save operations. Versions of - # trackers serialized with pickle won't include the `_metadata` - # attribute in their events, so it is necessary to define this getter - # in case the attribute does not exist. For more information see - # CHANGELOG.rst. - return getattr(self, "_metadata", {}) + self.metadata = metadata or {} def __ne__(self, other: Any) -> bool: # Not strictly necessary, but to avoid having both x==y and x!=y diff --git a/tests/conftest.py b/tests/conftest.py index 4c368522debc..94576159a0cd 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -74,20 +74,6 @@ } -TEST_DIALOGUES = [ - "data/test_dialogues/default.json", - "data/test_dialogues/formbot.json", - "data/test_dialogues/moodbot.json", -] - -EXAMPLE_DOMAINS = [ - "data/test_domains/default_with_mapping.yml", - "data/test_domains/default_with_slots.yml", - "examples/formbot/domain.yml", - "data/test_moodbot/domain.yml", -] - - @pytest.fixture(scope="session") def nlu_as_json_path() -> Text: return "data/examples/rasa/demo-rasa.json" diff --git a/tests/core/conftest.py b/tests/core/conftest.py index 1fd232410137..06495d89aecf 100644 --- a/tests/core/conftest.py +++ b/tests/core/conftest.py @@ -25,7 +25,8 @@ from rasa.shared.core.trackers import DialogueStateTracker from rasa.shared.nlu.training_data.features import Features from rasa.shared.nlu.constants import INTENT, ACTION_NAME, FEATURE_TYPE_SENTENCE -from tests.core.utilities import tracker_from_dialogue_file +from tests.dialogues import TEST_MOODBOT_DIALOGUE +from tests.core.utilities import tracker_from_dialogue class CustomSlot(Slot): @@ -193,6 +194,4 @@ def moodbot_features( @pytest.fixture def moodbot_tracker(moodbot_domain: Domain) -> DialogueStateTracker: - return tracker_from_dialogue_file( - "data/test_dialogues/moodbot.json", moodbot_domain - ) + return tracker_from_dialogue(TEST_MOODBOT_DIALOGUE, moodbot_domain) diff --git a/tests/core/test_policies.py b/tests/core/test_policies.py index cff5fb22954a..118470432ad0 100644 --- a/tests/core/test_policies.py +++ b/tests/core/test_policies.py @@ -31,7 +31,8 @@ from rasa.core.policies.ted_policy import TEDPolicy from rasa.core.policies.memoization import AugmentedMemoizationPolicy, MemoizationPolicy from rasa.shared.core.trackers import DialogueStateTracker -from tests.core.utilities import get_tracker, read_dialogue_file +from tests.dialogues import TEST_DEFAULT_DIALOGUE +from tests.core.utilities import get_tracker, tracker_from_dialogue async def train_trackers( @@ -229,11 +230,7 @@ async def test_memorise( def test_memorise_with_nlu( self, trained_policy: MemoizationPolicy, default_domain: Domain ): - filename = "data/test_dialogues/default.json" - dialogue = read_dialogue_file(filename) - - tracker = DialogueStateTracker(dialogue.name, default_domain.slots) - tracker.recreate_from_dialogue(dialogue) + tracker = tracker_from_dialogue(TEST_DEFAULT_DIALOGUE, default_domain) states = trained_policy._prediction_states(tracker, default_domain) recalled = trained_policy.recall(states, tracker, default_domain) diff --git a/tests/core/utilities.py b/tests/core/utilities.py index c3a81579cae5..64f225effcba 100644 --- a/tests/core/utilities.py +++ b/tests/core/utilities.py @@ -1,14 +1,9 @@ import itertools - import contextlib +import os import typing from typing import List, Optional, Text, Any, Dict -import jsonpickle -import os - -import rasa.shared.utils.io -import rasa.utils.io from rasa.shared.core.domain import Domain from rasa.shared.core.events import UserUttered, Event from rasa.shared.core.trackers import DialogueStateTracker @@ -18,20 +13,12 @@ from rasa.shared.core.conversation import Dialogue -def tracker_from_dialogue_file( - filename: Text, domain: Optional[Domain] = None -) -> DialogueStateTracker: - dialogue = read_dialogue_file(filename) - +def tracker_from_dialogue(dialogue: "Dialogue", domain: Domain) -> DialogueStateTracker: tracker = DialogueStateTracker(dialogue.name, domain.slots) tracker.recreate_from_dialogue(dialogue) return tracker -def read_dialogue_file(filename: Text) -> "Dialogue": - return jsonpickle.loads(rasa.shared.utils.io.read_file(filename)) - - @contextlib.contextmanager def cwd(path: Text): CWD = os.getcwd() diff --git a/tests/dialogues.py b/tests/dialogues.py new file mode 100644 index 000000000000..9bb8326397d2 --- /dev/null +++ b/tests/dialogues.py @@ -0,0 +1,277 @@ +from rasa.shared.core.conversation import Dialogue +from rasa.shared.core.events import ( + SlotSet, + UserUttered, + ActionExecuted, + ActiveLoop, + BotUttered, +) + + +TEST_DEFAULT_DIALOGUE = Dialogue( + name="default", + events=[ + ActionExecuted(action_name="action_listen", timestamp=1551952977.4850519,), + UserUttered( + entities=[{"end": 19, "entity": "name", "start": 14, "value": "Peter"}], + intent={"confidence": 0.0, "name": "greet"}, + message_id=None, + parse_data={ + "entities": [ + {"end": 19, "entity": "name", "start": 14, "value": "Peter"} + ], + "intent": {"confidence": 0.0, "name": "greet"}, + "message_id": None, + "metadata": {}, + "text": "Hi my name is Peter", + }, + text="Hi my name is Peter", + timestamp=1551953035.076376, + ), + SlotSet(key="name", timestamp=1551953035.076385, value="Peter"), + ActionExecuted(action_name="utter_greet", timestamp=1551953040.607782,), + BotUttered( + data={"attachment": None, "buttons": None, "elements": None}, + text="hey there Peter!", + timestamp=1551953040.60779, + ), + ], +) +TEST_FORMBOT_DIALOGUE = Dialogue( + name="formbot", + events=[ + ActionExecuted(action_name="action_listen", timestamp=1551884035.892855,), + UserUttered( + intent={"confidence": 0.3748943507671356, "name": "greet"}, + parse_data={ + "entities": [], + "intent": {"confidence": 0.3748943507671356, "name": "greet"}, + "text": "Hi I'm desperate to talk to you", + }, + text="Hi I'm desperate to talk to you", + timestamp=1551884050.259948, + ), + ActionExecuted( + action_name="utter_greet", + confidence=1.0, + policy="policy_2_MemoizationPolicy", + timestamp=1551884060.466681, + ), + BotUttered( + data={"attachment": None, "buttons": None, "elements": None}, + text="Hello! I am restaurant search assistant! How can I help?", + timestamp=1551884060.46669, + ), + ActionExecuted( + action_name="action_listen", + confidence=1.0, + policy="policy_2_MemoizationPolicy", + timestamp=1551884061.9350882, + ), + UserUttered( + entities=[ + {"end": 18, "entity": "cuisine", "start": 16, "value": "an"}, + {"end": 48, "entity": "location", "start": 42, "value": "Bombay"}, + ], + intent={"confidence": 0.9414282441139221, "name": "request_restaurant"}, + parse_data={ + "entities": [ + {"end": 18, "entity": "cuisine", "start": 16, "value": "an"}, + {"end": 48, "entity": "location", "start": 42, "value": "Bombay"}, + ], + "intent": { + "confidence": 0.9414282441139221, + "name": "request_restaurant", + }, + "text": "I'm looking for an indian restaurant...in Bombay", + }, + text="I'm looking for an indian restaurant...in Bombay", + timestamp=1551884090.9653602, + ), + ActionExecuted( + action_name="restaurant_form", + confidence=1.0, + policy="policy_2_MemoizationPolicy", + timestamp=1551884095.542748, + ), + ActionExecuted( + action_name="utter_slots_values", + confidence=1.0, + policy="policy_2_MemoizationPolicy", + timestamp=1551884097.570883, + ), + BotUttered( + data={"attachment": None, "buttons": None, "elements": None}, + text=( + "I am going to run a restaurant search " + "using the following parameters:\n" + " - cuisine: None\n - num_people: None\n" + " - outdoor_seating: None\n" + " - preferences: None\n - feedback: None" + ), + timestamp=1551884097.57089, + ), + ActionExecuted( + action_name="action_listen", + confidence=1.0, + policy="policy_2_MemoizationPolicy", + timestamp=1551884098.8006358, + ), + UserUttered( + intent={"confidence": 0.2287036031484604, "name": "affirm"}, + parse_data={ + "entities": [], + "intent": {"confidence": 0.2287036031484604, "name": "affirm"}, + "text": "Let's just pretend everything went correctly", + }, + text="Let's just pretend everything went correctly", + timestamp=1551884208.092693, + ), + ActionExecuted( + action_name="action_deactivate_loop", timestamp=1551884214.951055, + ), + ActiveLoop(name=None, timestamp=1551884214.9510589), + SlotSet(key="requested_slot", timestamp=1551884214.951062, value=None), + ActionExecuted( + action_name="action_listen", + confidence=0.7680902069097734, + policy="policy_0_TEDPolicy", + timestamp=1551884216.705635, + ), + ], +) +TEST_MOODBOT_DIALOGUE = Dialogue( + name="moodbot", + events=[ + ActionExecuted(action_name="action_listen", timestamp=1551883958.346432,), + UserUttered( + intent={"confidence": 0.44488201660555066, "name": "greet"}, + parse_data={ + "entities": [], + "intent": {"confidence": 0.44488201660555066, "name": "greet"}, + "intent_ranking": [ + {"confidence": 0.44488201660555066, "name": "greet"}, + {"confidence": 0.29023286595689257, "name": "goodbye"}, + {"confidence": 0.10501227521380094, "name": "mood_great"}, + {"confidence": 0.06879303900502878, "name": "mood_unhappy"}, + {"confidence": 0.04903582960375451, "name": "deny"}, + {"confidence": 0.04204397361497238, "name": "affirm"}, + ], + "text": "Hi talk to me", + }, + text="Hi talk to me", + timestamp=1551883971.410778, + ), + ActionExecuted( + action_name="utter_greet", + confidence=1.0, + policy="policy_2_MemoizationPolicy", + timestamp=1551883975.6456478, + ), + BotUttered( + data={ + "attachment": None, + "buttons": [ + {"payload": "great", "title": "great"}, + {"payload": "super sad", "title": "super sad"}, + ], + "elements": None, + }, + text="Hey! How are you?", + timestamp=1551883975.645656, + ), + ActionExecuted( + action_name="action_listen", + confidence=1.0, + policy="policy_2_MemoizationPolicy", + timestamp=1551883979.098331, + ), + UserUttered( + intent={"confidence": 0.7417646502470048, "name": "mood_unhappy"}, + parse_data={ + "entities": [], + "intent": {"confidence": 0.7417646502470048, "name": "mood_unhappy"}, + "intent_ranking": [ + {"confidence": 0.7417646502470048, "name": "mood_unhappy"}, + {"confidence": 0.1439688162980615, "name": "mood_great"}, + {"confidence": 0.04577343822867981, "name": "goodbye"}, + {"confidence": 0.037760394267609965, "name": "greet"}, + {"confidence": 0.017715563733253295, "name": "affirm"}, + {"confidence": 0.013017137225390567, "name": "deny"}, + ], + "text": "Super sad", + }, + text="Super sad", + timestamp=1551883982.540276, + ), + ActionExecuted( + action_name="utter_cheer_up", + confidence=1.0, + policy="policy_2_MemoizationPolicy", + timestamp=1551883985.031668, + ), + BotUttered( + data={ + "attachment": "https://i.imgur.com/nGF1K8f.jpg", + "buttons": None, + "elements": None, + }, + text="Here is something to cheer you up:", + timestamp=1551883985.0316749, + ), + ActionExecuted( + action_name="utter_did_that_help", + confidence=1.0, + policy="policy_2_MemoizationPolicy", + timestamp=1551883985.940413, + ), + BotUttered( + data={"attachment": None, "buttons": None, "elements": None}, + text="Did that help you?", + timestamp=1551883985.940421, + ), + ActionExecuted( + action_name="action_listen", + confidence=1.0, + policy="policy_2_MemoizationPolicy", + timestamp=1551883986.958556, + ), + UserUttered( + intent={"confidence": 0.8162296627642036, "name": "deny"}, + parse_data={ + "entities": [], + "intent": {"confidence": 0.8162296627642036, "name": "deny"}, + "intent_ranking": [ + {"confidence": 0.8162296627642036, "name": "deny"}, + {"confidence": 0.07152463661481759, "name": "mood_unhappy"}, + {"confidence": 0.05028159510181415, "name": "greet"}, + {"confidence": 0.02662414324721426, "name": "affirm"}, + {"confidence": 0.024343883584915963, "name": "goodbye"}, + {"confidence": 0.010996078687034375, "name": "mood_great"}, + ], + "text": "No", + }, + text="No", + timestamp=1551883989.0720608, + ), + ActionExecuted( + action_name="utter_goodbye", + confidence=1.0, + policy="policy_2_MemoizationPolicy", + timestamp=1551883991.061463, + ), + BotUttered( + data={"attachment": None, "buttons": None, "elements": None}, + text="Bye", + timestamp=1551883991.061471, + ), + ], +) + +TEST_DIALOGUES = [TEST_DEFAULT_DIALOGUE, TEST_FORMBOT_DIALOGUE, TEST_MOODBOT_DIALOGUE] + +TEST_DOMAINS_FOR_DIALOGUES = [ + "data/test_domains/default_with_slots.yml", + "examples/formbot/domain.yml", + "data/test_moodbot/domain.yml", +] diff --git a/tests/shared/core/test_dialogues.py b/tests/shared/core/test_dialogues.py index 0018d9e53c11..9928a9c0703e 100644 --- a/tests/shared/core/test_dialogues.py +++ b/tests/shared/core/test_dialogues.py @@ -1,34 +1,23 @@ import json -import jsonpickle import pytest -import rasa.shared.utils.io -import rasa.utils.io from rasa.shared.core.conversation import Dialogue from rasa.shared.core.domain import Domain from rasa.core.tracker_store import InMemoryTrackerStore -from tests.conftest import ( +from tests.dialogues import ( TEST_DIALOGUES, - EXAMPLE_DOMAINS, + TEST_DEFAULT_DIALOGUE, + TEST_DOMAINS_FOR_DIALOGUES, ) -from tests.core.utilities import tracker_from_dialogue_file +from tests.core.utilities import tracker_from_dialogue -@pytest.mark.parametrize("filename", TEST_DIALOGUES) -def test_dialogue_serialisation(filename, domain: Domain): - dialogue_json = rasa.shared.utils.io.read_file(filename) - restored = json.loads(dialogue_json) - tracker = tracker_from_dialogue_file(filename, domain) - en_de_coded = json.loads(jsonpickle.encode(tracker.as_dialogue())) - assert restored == en_de_coded - - -@pytest.mark.parametrize("pair", zip(TEST_DIALOGUES, EXAMPLE_DOMAINS)) +@pytest.mark.parametrize("pair", zip(TEST_DIALOGUES, TEST_DOMAINS_FOR_DIALOGUES)) def test_inmemory_tracker_store(pair): - filename, domainpath = pair + dialogue, domainpath = pair domain = Domain.load(domainpath) - tracker = tracker_from_dialogue_file(filename, domain) + tracker = tracker_from_dialogue(dialogue, domain) tracker_store = InMemoryTrackerStore(domain) tracker_store.save(tracker) restored = tracker_store.retrieve(tracker.sender_id) @@ -36,15 +25,13 @@ def test_inmemory_tracker_store(pair): def test_tracker_default(domain: Domain): - filename = "data/test_dialogues/default.json" - tracker = tracker_from_dialogue_file(filename, domain) + tracker = tracker_from_dialogue(TEST_DEFAULT_DIALOGUE, domain) assert tracker.get_slot("name") == "Peter" assert tracker.get_slot("price") is None # slot doesn't exist! def test_dialogue_from_parameters(domain: Domain): - filename = "data/test_dialogues/default.json" - tracker = tracker_from_dialogue_file(filename, domain) + tracker = tracker_from_dialogue(TEST_DEFAULT_DIALOGUE, domain) serialised_dialogue = InMemoryTrackerStore.serialise_tracker(tracker) deserialised_dialogue = Dialogue.from_parameters(json.loads(serialised_dialogue)) assert tracker.as_dialogue().as_dict() == deserialised_dialogue.as_dict() diff --git a/tests/shared/core/test_trackers.py b/tests/shared/core/test_trackers.py index 4b3f80b33b97..400dc234c3f9 100644 --- a/tests/shared/core/test_trackers.py +++ b/tests/shared/core/test_trackers.py @@ -58,13 +58,13 @@ from rasa.core.tracker_store import TrackerStore from rasa.shared.core.trackers import DialogueStateTracker, EventVerbosity from tests.core.conftest import MockedMongoTrackerStore -from tests.conftest import ( - EXAMPLE_DOMAINS, +from tests.dialogues import ( TEST_DIALOGUES, + TEST_MOODBOT_DIALOGUE, + TEST_DOMAINS_FOR_DIALOGUES, ) from tests.core.utilities import ( - tracker_from_dialogue_file, - read_dialogue_file, + tracker_from_dialogue, user_uttered, get_tracker, ) @@ -99,13 +99,14 @@ def stores_to_be_tested_ids(): return ["redis-tracker", "in-memory-tracker", "SQL-tracker", "mongo-tracker"] -def test_tracker_duplicate(): - filename = "data/test_dialogues/moodbot.json" - dialogue = read_dialogue_file(filename) - tracker = DialogueStateTracker(dialogue.name, test_domain.slots) - tracker.recreate_from_dialogue(dialogue) +def test_tracker_duplicate(moodbot_domain: Domain): + tracker = tracker_from_dialogue(TEST_MOODBOT_DIALOGUE, moodbot_domain) num_actions = len( - [event for event in dialogue.events if isinstance(event, ActionExecuted)] + [ + event + for event in TEST_MOODBOT_DIALOGUE.events + if isinstance(event, ActionExecuted) + ] ) # There is always one duplicated tracker more than we have actions, @@ -142,20 +143,18 @@ def test_tracker_store_storage_and_retrieval(store: TrackerStore): @pytest.mark.parametrize("store", stores_to_be_tested(), ids=stores_to_be_tested_ids()) -@pytest.mark.parametrize("pair", zip(TEST_DIALOGUES, EXAMPLE_DOMAINS)) +@pytest.mark.parametrize("pair", zip(TEST_DIALOGUES, TEST_DOMAINS_FOR_DIALOGUES)) def test_tracker_store(store, pair): - filename, domainpath = pair + dialogue, domainpath = pair domain = Domain.load(domainpath) - tracker = tracker_from_dialogue_file(filename, domain) + tracker = tracker_from_dialogue(dialogue, domain) store.save(tracker) restored = store.retrieve(tracker.sender_id) assert restored == tracker async def test_tracker_write_to_story(tmp_path: Path, moodbot_domain: Domain): - tracker = tracker_from_dialogue_file( - "data/test_dialogues/moodbot.json", moodbot_domain - ) + tracker = tracker_from_dialogue(TEST_MOODBOT_DIALOGUE, moodbot_domain) p = tmp_path / "export.yml" tracker.export_stories_to_file(str(p)) trackers = await training.load_data( diff --git a/tests/test_model_training.py b/tests/test_model_training.py index a72795dab9b8..a6f3f362e473 100644 --- a/tests/test_model_training.py +++ b/tests/test_model_training.py @@ -11,8 +11,10 @@ from _pytest.logging import LogCaptureFixture from _pytest.monkeypatch import MonkeyPatch +import rasa from rasa.core.policies.ted_policy import TEDPolicy import rasa.model +import rasa.model_training import rasa.core import rasa.core.train import rasa.nlu @@ -22,8 +24,6 @@ from rasa.core.agent import Agent from rasa.core.interpreter import RasaNLUInterpreter from rasa.nlu.model import Interpreter - -from rasa.model_training import train_core, train_nlu, train, dry_run_result from rasa.utils.tensorflow.constants import EPOCHS from tests.conftest import AsyncMock from tests.test_model import _fingerprint @@ -93,7 +93,7 @@ def test_train_temp_files( monkeypatch.setattr(tempfile, "tempdir", tmp_path / "training") output = str(tmp_path / "models") - train( + rasa.train( domain_path, stack_config_path, [stories_path, nlu_data_path], @@ -106,7 +106,7 @@ def test_train_temp_files( # After training the model, try to do it again. This shouldn't try to train # a new model because nothing has been changed. It also shouldn't create # any temp files. - train( + rasa.train( domain_path, stack_config_path, [stories_path, nlu_data_path], output=output, ) @@ -125,7 +125,7 @@ def test_train_core_temp_files( monkeypatch.setattr(tempfile, "tempdir", tmp_path / "training") - train_core( + rasa.model_training.train_core( domain_path, stack_config_path, stories_path, output=str(tmp_path / "models"), ) @@ -143,7 +143,9 @@ def test_train_nlu_temp_files( monkeypatch.setattr(tempfile, "tempdir", tmp_path / "training") - train_nlu(stack_config_path, nlu_data_path, output=str(tmp_path / "models")) + rasa.model_training.train_nlu( + stack_config_path, nlu_data_path, output=str(tmp_path / "models") + ) assert count_temp_rasa_files(tempfile.tempdir) == 0 @@ -160,7 +162,7 @@ def test_train_nlu_wrong_format_error_message( monkeypatch.setattr(tempfile, "tempdir", tmp_path / "training") - train_nlu( + rasa.model_training.train_nlu( stack_config_path, incorrect_nlu_data_path, output=str(tmp_path / "models") ) @@ -172,7 +174,7 @@ def test_train_nlu_with_responses_no_domain_warns(tmp_path: Path): data_path = "data/test_nlu_no_responses/nlu_no_responses.yml" with pytest.warns(UserWarning) as records: - train_nlu( + rasa.model_training.train_nlu( "data/test_config/config_response_selector_minimal.yml", data_path, output=str(tmp_path / "models"), @@ -190,7 +192,7 @@ def test_train_nlu_with_responses_and_domain_no_warns(tmp_path: Path): domain_path = "data/test_nlu_no_responses/domain_with_only_responses.yml" with pytest.warns(None) as records: - train_nlu( + rasa.model_training.train_nlu( "data/test_config/config_response_selector_minimal.yml", data_path, output=str(tmp_path / "models"), @@ -215,7 +217,9 @@ def test_train_nlu_no_nlu_file_error_message( monkeypatch.setattr(tempfile, "tempdir", tmp_path / "training") - train_nlu(stack_config_path, "", output=str(tmp_path / "models")) + rasa.model_training.train_nlu( + stack_config_path, "", output=str(tmp_path / "models") + ) captured = capsys.readouterr() assert "No NLU data given" in captured.out @@ -242,7 +246,7 @@ def test_trained_interpreter_passed_to_core_training( # Mock the actual Core training _train_core = mock_core_training(monkeypatch) - train( + rasa.train( domain_path, config_path, [stories_path, nlu_data_path], str(tmp_path), ) @@ -275,7 +279,7 @@ def test_interpreter_of_old_model_passed_to_core_training( # Mock the actual Core training _train_core = mock_core_training(monkeypatch) - train( + rasa.train( domain_path, config_path, [stories_path, nlu_data_path], str(tmp_path), ) @@ -315,7 +319,7 @@ def test_train_core_autoconfig( ) # do training - train_core( + rasa.model_training.train_core( domain_path, stack_config_path, stories_path, @@ -344,7 +348,7 @@ def test_train_nlu_autoconfig( ) # do training - train_nlu( + rasa.model_training.train_nlu( stack_config_path, nlu_data_path, output="test_train_nlu_temp_files_models", ) @@ -390,7 +394,7 @@ def test_e2e_gives_experimental_warning( mock_core_training(monkeypatch) with caplog.at_level(logging.WARNING): - train( + rasa.train( domain_path, stack_config_path, [e2e_stories_path, nlu_data_path], @@ -416,7 +420,7 @@ def test_models_not_retrained_if_no_new_data( mocked_nlu_training = mock_nlu_training(monkeypatch) mocked_core_training = mock_core_training(monkeypatch) - train( + rasa.train( domain_path, stack_config_path, [e2e_stories_path, nlu_data_path], @@ -445,7 +449,7 @@ def test_retrains_nlu_and_core_if_new_e2e_example( mocked_nlu_training = mock_nlu_training(monkeypatch) mocked_core_training = mock_core_training(monkeypatch) - new_model_path = train( + new_model_path = rasa.train( domain_path, stack_config_path, [new_stories_file, nlu_data_path], @@ -475,7 +479,7 @@ def test_retrains_only_core_if_new_e2e_example_seen_before( mocked_nlu_training = mock_nlu_training(monkeypatch) mocked_core_training = mock_core_training(monkeypatch) - new_model_path = train( + new_model_path = rasa.train( domain_path, stack_config_path, [new_stories_file, nlu_data_path], @@ -498,7 +502,7 @@ def test_nlu_and_core_trained_if_no_nlu_data_but_e2e_stories( mocked_core_training = mock_core_training(monkeypatch) output = self.make_tmp_model_dir(tmp_path) - train( + rasa.train( domain_path, stack_config_path, [e2e_stories_path], output=output, ) @@ -530,7 +534,7 @@ def test_new_nlu_data_retrains_core_if_there_are_e2e_stories( mocked_nlu_training = mock_nlu_training(monkeypatch) mocked_core_training = mock_core_training(monkeypatch) - new_model_path = train( + new_model_path = rasa.train( domain_path, stack_config_path, [e2e_stories_path, new_nlu_file], @@ -560,7 +564,7 @@ def test_new_nlu_data_does_not_retrain_core_if_there_are_no_e2e_stories( mocked_nlu_training = mock_nlu_training(monkeypatch) mocked_core_training = mock_core_training(monkeypatch) - new_model_path = train( + new_model_path = rasa.train( domain_path, stack_config_path, [simple_stories_path, new_nlu_file], @@ -585,7 +589,7 @@ def test_training_core_with_e2e_fails_gracefully( mocked_core_training = mock_core_training(monkeypatch) output = self.make_tmp_model_dir(tmp_path) - train_core( + rasa.model_training.train_core( domain_path, stack_config_path, e2e_stories_path, output=output, ) @@ -620,7 +624,7 @@ def test_model_finetuning( if use_latest_model: trained_rasa_model = str(Path(trained_rasa_model).parent) - train( + rasa.train( domain_path, stack_config_path, [stories_path, nlu_data_path], @@ -674,7 +678,7 @@ def test_model_finetuning_core( new_stories_path = tmp_path / "new_stories.yml" rasa.shared.utils.io.write_yaml(old_stories, new_stories_path) - train_core( + rasa.model_training.train_core( "data/test_moodbot/domain.yml", str(new_config_path), str(new_stories_path), @@ -707,7 +711,7 @@ def test_model_finetuning_core_with_default_epochs( new_config_path = tmp_path / "new_config.yml" rasa.shared.utils.io.write_yaml(old_config, new_config_path) - train_core( + rasa.model_training.train_core( "data/test_moodbot/domain.yml", str(new_config_path), "data/test_moodbot/data/stories.yml", @@ -739,7 +743,7 @@ def test_model_finetuning_core_new_domain_label( rasa.shared.utils.io.write_yaml(old_domain, new_domain_path) with pytest.raises(SystemExit): - train_core( + rasa.model_training.train_core( domain=str(new_domain_path), config="data/test_moodbot/config.yml", stories="data/test_moodbot/data/stories.yml", @@ -765,7 +769,7 @@ def test_model_finetuning_new_domain_label_stops_all_training( rasa.shared.utils.io.write_yaml(old_domain, new_domain_path) with pytest.raises(SystemExit): - train( + rasa.train( domain=str(new_domain_path), config="data/test_moodbot/config.yml", training_files=[ @@ -815,7 +819,7 @@ def test_model_finetuning_nlu( new_nlu_path = tmp_path / "new_nlu.yml" rasa.shared.utils.io.write_yaml(old_nlu, new_nlu_path) - train_nlu( + rasa.model_training.train_nlu( str(new_config_path), str(new_nlu_path), domain="data/test_moodbot/domain.yml", @@ -853,7 +857,7 @@ def test_model_finetuning_nlu_new_label( rasa.shared.utils.io.write_yaml(old_nlu, new_nlu_path) with pytest.raises(SystemExit): - train_nlu( + rasa.model_training.train_nlu( "data/test_moodbot/config.yml", str(new_nlu_path), domain="data/test_moodbot/domain.yml", @@ -878,7 +882,7 @@ def test_model_finetuning_nlu_new_entity( rasa.shared.utils.io.write_yaml(old_nlu, new_nlu_path) with pytest.raises(SystemExit): - train_nlu( + rasa.model_training.train_nlu( "data/test_moodbot/config.yml", str(new_nlu_path), domain="data/test_moodbot/domain.yml", @@ -909,7 +913,7 @@ def test_model_finetuning_nlu_new_label_already_in_domain( rasa.shared.utils.io.write_yaml(old_nlu, new_nlu_path) with pytest.raises(SystemExit): - train_nlu( + rasa.model_training.train_nlu( config_path, str(new_nlu_path), domain=domain_path, @@ -933,7 +937,7 @@ def test_model_finetuning_nlu_new_label_to_domain_only( new_domain_path = tmp_path / "new_domain.yml" rasa.shared.utils.io.write_yaml(old_domain, new_domain_path) - train_nlu( + rasa.model_training.train_nlu( "data/test_moodbot/config.yml", "data/test_moodbot/data/nlu.yml", domain=str(new_domain_path), @@ -960,7 +964,7 @@ def test_model_finetuning_nlu_with_default_epochs( new_config_path = tmp_path / "new_config.yml" rasa.shared.utils.io.write_yaml(old_config, new_config_path) - train_nlu( + rasa.model_training.train_nlu( str(new_config_path), "data/test_moodbot/data/nlu.yml", output=output, @@ -994,7 +998,7 @@ def test_model_finetuning_with_invalid_model( output = str(tmp_path / "models") with pytest.raises(SystemExit): - train( + rasa.train( domain_path, stack_config_path, [stories_path, nlu_data_path], @@ -1025,7 +1029,7 @@ def test_model_finetuning_with_invalid_model_core( output = str(tmp_path / "models") with pytest.raises(SystemExit): - train_core( + rasa.model_training.train_core( domain_path, stack_config_path, stories_path, @@ -1055,7 +1059,7 @@ def test_model_finetuning_with_invalid_model_nlu( output = str(tmp_path / "models") with pytest.raises(SystemExit): - train_nlu( + rasa.model_training.train_nlu( stack_config_path, nlu_data_path, domain=domain_path, @@ -1112,6 +1116,6 @@ def test_model_finetuning_with_invalid_model_nlu( def test_dry_run_result( result: rasa.model.FingerprintComparisonResult, code: int, texts_count: int, ): - result_code, texts = dry_run_result(result) + result_code, texts = rasa.model_training.dry_run_result(result) assert result_code == code assert len(texts) == texts_count