Example #1
0
def test_pushing_event(rasa_app: SanicTestClient, event: Event):
    sender_id = str(uuid.uuid1())
    conversation = f"/conversations/{sender_id}"

    serialized_event = event.as_dict()
    # Remove timestamp so that a new one is assigned on the server
    serialized_event.pop("timestamp")

    time_before_adding_events = time.time()
    _, response = rasa_app.post(
        f"{conversation}/tracker/events",
        json=serialized_event,
        headers={"Content-Type": "application/json"},
    )
    assert response.json is not None
    assert response.status == 200

    _, tracker_response = rasa_app.get(f"/conversations/{sender_id}/tracker")
    tracker = tracker_response.json
    assert tracker is not None

    assert len(tracker.get("events")) == 1

    evt = tracker.get("events")[0]
    deserialised_event = Event.from_parameters(evt)
    assert deserialised_event == event
    assert deserialised_event.timestamp > time_before_adding_events
Example #2
0
    def update(self, event: Event) -> None:
        """Modify the state of the tracker according to an ``Event``. """
        if not isinstance(event, Event):  # pragma: no cover
            raise ValueError(
                "event to log must be an instance of a subclass of Event.")

        self.events.append(event)
        event.apply_to(self)
Example #3
0
    def update(self, event: Event, domain: Optional[Domain] = None) -> None:
        """Modify the state of the tracker according to an ``Event``. """
        if not isinstance(event, Event):  # pragma: no cover
            raise ValueError("event to log must be an instance of a subclass of Event.")

        self.events.append(event)
        event.apply_to(self)

        if domain and isinstance(event, UserUttered):
            # store all entities as slots
            for e in domain.slots_for_entities(event.parse_data["entities"]):
                self.update(e)
Example #4
0
    def update(self, event: Event, domain: Optional[Domain] = None) -> None:
        """Modify the state of the tracker according to an ``Event``. """
        if not isinstance(event, Event):  # pragma: no cover
            raise ValueError(
                "event to log must be an instance of a subclass of Event.")

        self.events.append(event)
        event.apply_to(self)

        if domain and isinstance(event, UserUttered):
            logger.debug("UserUttered event!")
            self.trigger_followup_action(ACTION_CHANGE_FRAME_NAME)
Example #5
0
def test_json_parse_user():
    # DOCS MARKER UserUttered
    evt = \
        {
            'event': 'user',
            'text': 'Hey',
            'parse_data': {
                'intent': {'name': 'greet', 'confidence': 0.9},
                'entities': []
            }
        }
    # DOCS END
    assert Event.from_parameters(evt) == UserUttered("Hey",
                                                     intent={
                                                         "name": "greet",
                                                         "confidence": 0.9
                                                     },
                                                     entities=[],
                                                     parse_data={
                                                         "intent": {
                                                             "name": "greet",
                                                             "confidence": 0.9
                                                         },
                                                         "entities": []
                                                     })
Example #6
0
def test_json_parse_user():
    # fmt: off
    # DOCS MARKER UserUttered
    evt = {
        "event": "user",
        "text": "Hey",
        "parse_data": {
            "intent": {
                "name": "greet",
                "confidence": 0.9
            },
            "entities": []
        },
        "metadata": {},
    }
    # DOCS END
    # fmt: on
    assert Event.from_parameters(evt) == UserUttered(
        "Hey",
        intent={
            "name": "greet",
            "confidence": 0.9
        },
        entities=[],
        parse_data={
            "intent": {
                "name": "greet",
                "confidence": 0.9
            },
            "entities": []
        },
        metadata={},
    )
Example #7
0
    async def append_event(request: Request, sender_id: Text):
        """Append a list of events to the state of a conversation"""

        request_params = request.json
        evt = Event.from_parameters(request_params)
        tracker = app.agent.tracker_store.get_or_create_tracker(sender_id)
        verbosity = event_verbosity_parameter(request,
                                              EventVerbosity.AFTER_RESTART)

        if evt:
            tracker.update(evt)
            app.agent.tracker_store.save(tracker)
            return response.json(tracker.current_state(verbosity))
        else:
            logger.warning(
                "Append event called, but could not extract a "
                "valid event. Request JSON: {}".format(request_params))
            raise ErrorResponse(
                400,
                "InvalidParameter",
                "Couldn't extract a proper event from the request body.",
                {
                    "parameter": "",
                    "in": "body"
                },
            )
Example #8
0
def test_pushing_event(app, event):
    cid = str(uuid.uuid1())
    conversation = "/conversations/{}".format(cid)
    data = json.dumps({"query": "/greet"})
    _, response = app.post("{}/respond".format(conversation),
                           data=data,
                           headers={"Content-Type": "application/json"})
    assert response.json is not None
    assert response.status == 200

    data = json.dumps(event.as_dict())
    _, response = app.post("{}/tracker/events".format(conversation),
                           data=data,
                           headers={"Content-Type": "application/json"})
    assert (response.json is not None)
    assert response.status == 200

    _, tracker_response = app.get("/conversations/{}/tracker"
                                  "".format(cid))
    tracker = tracker_response.json
    assert tracker is not None
    assert len(tracker.get("events")) == 6

    evt = tracker.get("events")[5]
    assert Event.from_parameters(evt) == event
Example #9
0
    async def add_chitchat_to_story(self,
                                    story,
                                    domain: Domain,
                                    indexes: List,
                                    interpreter: "NaturalLanguageInterpreter" = RegexInterpreter()):
        # Delete Indexes, if they greater then the length of the story or lower 0
        indexes = sorted(set(indexes))
        indexes = [i for i in indexes if i >= 0 and i < len(story.events)]
        to_add = 0
        for index in indexes:
            index += to_add
            # get last Utter
            last_utter = None
            if index - 1 >= 0:
                last_utter = story.events[index - 1]

            # Intent
            intent = 'asdfwe'
            parse_data = await interpreter.parse(intent)
            utterance = UserUttered(
                intent, parse_data.get("intent"), parse_data.get("entities"), parse_data
            )
            intent_name = utterance.intent.get("name")
            if domain and intent_name not in domain.intents:
                raise_warning(
                    f"Found unknown intent '{intent_name}'. "
                    "Please, make sure that all intents are "
                    "listed in your domain yaml.",
                    UserWarning,
                )
            # Utter
            # Copyied at dsl.py
            # def add_event(self, event_name, parameters):
            parameters = {}
            event_name = "utter_asdfwe"
            # add 'name' only if event is not a SlotSet,
            # because there might be a slot with slot_key='name'
            parameters["name"] = event_name

            parsed_events = Event.from_story_string(
                event_name, parameters, default=ActionExecuted
            )
            if parsed_events is None:
                raise StoryParseError(
                    "Unknown event '{}'. It is Neither an event "
                    "nor an action).".format(event_name)
                )

            # Add to Story
            story.events.insert(index, utterance)
            index += 1
            to_add += 1
            for parsed_event in parsed_events:
                story.events.insert(index, parsed_event)
                index += 1
                to_add += 1

            if last_utter and self.helper.get_param('consultation', False):
                story.events.insert(index, last_utter)
        return story
Example #10
0
def test_json_parse_reset():
    # DOCS MARKER AllSlotsReset
    evt = \
        {
            'event': 'reset_slots'
        }
    # DOCS END
    assert Event.from_parameters(evt) == AllSlotsReset()
Example #11
0
def test_json_parse_rewind():
    # DOCS MARKER UserUtteranceReverted
    evt = \
        {
            'event': 'rewind'
        }
    # DOCS END
    assert Event.from_parameters(evt) == UserUtteranceReverted()
Example #12
0
def test_json_parse_restarted():
    # DOCS MARKER Restarted
    evt = \
        {
            'event': 'restart'
        }
    # DOCS END
    assert Event.from_parameters(evt) == Restarted()
Example #13
0
def test_json_parse_resume():
    # DOCS MARKER ConversationResumed
    evt = \
        {
            'event': 'resume',
        }
    # DOCS END
    assert Event.from_parameters(evt) == ConversationResumed()
Example #14
0
def test_json_parse_pause():
    # DOCS MARKER ConversationPaused
    evt = \
        {
            'event': 'pause',
        }
    # DOCS END
    assert Event.from_parameters(evt) == ConversationPaused()
Example #15
0
def test_json_parse_export():
    # DOCS MARKER StoryExported
    evt = \
        {
            'event': 'export',
        }
    # DOCS END
    assert Event.from_parameters(evt) == StoryExported()
Example #16
0
def test_json_parse_undo():
    # DOCS MARKER ActionReverted
    evt = \
        {
            'event': 'undo',
        }
    # DOCS END
    assert Event.from_parameters(evt) == ActionReverted()
Example #17
0
def test_json_parse_action():
    # DOCS MARKER ActionExecuted
    evt = \
        {
            'event': 'action',
            'name': 'my_action'
        }
    # DOCS END
    assert Event.from_parameters(evt) == ActionExecuted("my_action")
Example #18
0
def test_json_parse_agent():
    # DOCS MARKER AgentUttered
    evt = \
        {
            'event': 'agent',
            'text': 'Hey, how are you?'
        }
    # DOCS END
    assert Event.from_parameters(evt) == AgentUttered("Hey, how are you?")
Example #19
0
def test_json_parse_followup():
    # DOCS MARKER FollowupAction
    evt = \
        {
            'event': 'followup',
            'name': 'my_action'
        }
    # DOCS END
    assert Event.from_parameters(evt) == FollowupAction("my_action")
Example #20
0
def test_json_parse_bot():
    # DOCS MARKER BotUttered
    evt = \
        {
            'event': 'bot',
            'text': 'Hey there!',
            'data': {}
        }
    # DOCS END
    assert Event.from_parameters(evt) == BotUttered("Hey there!", {})
def _save_nlu_log(logs_service: LogsService, event_data: Dict,
                  event_id: int) -> None:
    try:
        event = Event.from_parameters(event_data)
        if isinstance(event, UserUttered):
            log = logs_service.create_log_from_parse_data(
                event.parse_data, created_from_model=False, event_id=event_id)
    except Exception as e:
        logger.exception("Could not persist event '{}' to NLU logs:\n"
                         "{}".format(event_data, e))
Example #22
0
def test_json_parse_setslot():
    # DOCS MARKER SetSlot
    evt = \
        {
            'event': 'slot',
            'name': 'departure_airport',
            'value': 'BER',
        }
    # DOCS END
    assert Event.from_parameters(evt) == SlotSet("departure_airport", "BER")
Example #23
0
    async def append_events(request: Request, conversation_id: Text):
        """Append a list of events to the state of a conversation"""
        validate_request_body(
            request,
            "You must provide events in the request body in order to append them"
            "to the state of a conversation.",
        )

        request_id = request.args.get("request_id",
                                      UserMessage.DEFAULT_REQUEST_ID)
        user_id = request.args.get("user_id", UserMessage.DEFAULT_USER_ID)

        events = request.json
        if not isinstance(events, list):
            events = [events]

        events = [Event.from_parameters(event) for event in events]
        events = [event for event in events if event]

        if not events:
            logger.warning(
                "Append event called, but could not extract a valid event. "
                "Request JSON: {}".format(request.json))
            raise ErrorResponse(
                400,
                "BadRequest",
                "Couldn't extract a proper event from the request body.",
                {
                    "parameter": "",
                    "in": "body"
                },
            )

        verbosity = event_verbosity_parameter(request,
                                              EventVerbosity.AFTER_RESTART)
        tracker = obtain_tracker_store(app.agent, conversation_id, request_id,
                                       user_id)

        try:
            for event in events:
                tracker.update(event, app.agent.domain)

            app.agent.tracker_store.save(tracker)

            return response.json(tracker.current_state(verbosity))
        except Exception as e:
            logger.debug(traceback.format_exc())
            raise ErrorResponse(
                500,
                "ConversationError",
                "An unexpected error occurred. Error: {}".format(e),
            )
Example #24
0
def test_event_metadata_dict(event_class: Type[Event]):
    metadata = {"foo": "bar", "quux": 42}

    # Create the event from a `dict` that will be accepted by the
    # `_from_parameters` method of any `Event` subclass (the values themselves
    # are not important).
    event = Event.from_parameters({
        "metadata": metadata,
        "event": event_class.type_name,
        "parse_data": {},
        "date_time": "2019-11-20T16:09:16Z",
    })
    assert event.as_dict()["metadata"] == metadata
Example #25
0
    def save_nlu_logs_from_event(
            self,
            event_data: Union[Text, bytes],
            event_id: Optional[int] = None) -> Optional[int]:
        try:
            event = Event.from_parameters(json.loads(event_data))
            if isinstance(event, UserUttered):
                log = self.create_log_from_parse_data(event.parse_data,
                                                      event_id=event_id)
                return log["id"]

        except ValueError as e:
            logger.exception(
                f"Could not persist event '{e}' to NLU logs:\n {e}")
Example #26
0
def test_json_parse_reminder():
    evt = {
        "event": "reminder",
        "intent": "my_intent",
        "entities": {"entity1": "value1", "entity2": "value2"},
        "date_time": "2018-09-03T11:41:10.128172",
        "name": "my_reminder",
        "kill_on_user_msg": True,
    }
    assert Event.from_parameters(evt) == ReminderScheduled(
        "my_intent",
        parser.parse("2018-09-03T11:41:10.128172"),
        name="my_reminder",
        kill_on_user_message=True,
    )
Example #27
0
def test_file_broker_logs_to_file(tmpdir):
    fname = tmpdir.join("events.log").strpath

    actual = EventBroker.create(EndpointConfig(**{"type": "file", "path": fname}))

    for e in TEST_EVENTS:
        actual.publish(e.as_dict())

    # reading the events from the file one event per line
    recovered = []
    with open(fname, "r") as f:
        for l in f:
            recovered.append(Event.from_parameters(json.loads(l)))

    assert recovered == TEST_EVENTS
Example #28
0
def test_event_default_metadata(event_class: Type[Event]):
    # Create an event without metadata. When converting the `Event` to a
    # `dict`, it should not include a `metadata` property - unless it's a
    # `UserUttered` or a `BotUttered` event (or subclasses of them), in which
    # case the metadata should be included with a default value of {}.
    event = Event.from_parameters({
        "event": event_class.type_name,
        "parse_data": {},
        "date_time": "2019-11-20T16:09:16Z",
    })

    if isinstance(event, BotUttered) or isinstance(event, UserUttered):
        assert event.as_dict()["metadata"] == {}
    else:
        assert "metadata" not in event.as_dict()
Example #29
0
    def from_parameters(cls, parameters: Dict[Text, Any]) -> "Dialogue":
        """Create `Dialogue` from parameters.

        Args:
            parameters: Serialised dialogue, should contain keys 'name' and 'events'.

        Returns:
            Deserialised `Dialogue`.

        """

        return cls(
            parameters.get("name"),
            [Event.from_parameters(evt) for evt in parameters.get("events")],
        )
Example #30
0
def test_file_broker_properly_logs_newlines(tmpdir):
    fname = tmpdir.join("events.log").strpath

    actual = EventBroker.create(EndpointConfig(**{"type": "file", "path": fname}))

    event_with_newline = UserUttered("hello \n there")

    actual.publish(event_with_newline.as_dict())

    # reading the events from the file one event per line
    recovered = []
    with open(fname, "r") as f:
        for l in f:
            recovered.append(Event.from_parameters(json.loads(l)))

    assert recovered == [event_with_newline]