Example #1
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.",
        )

        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:
            warnings.warn(
                f"Append event called, but could not extract a valid event. "
                f"Request JSON: {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)

        try:
            async with app.agent.lock_store.lock(conversation_id):
                tracker = await get_tracker(
                    app.agent.create_processor(), conversation_id
                )
                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", f"An unexpected error occurred. Error: {e}"
            )
Example #2
0
def test_file_broker_logs_to_file(tmpdir):
    log_file_path = tmpdir.join("events.log").strpath

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

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

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

    assert recovered == TEST_EVENTS
Example #3
0
def test_file_broker_logs_to_file(tmpdir):
    fname = tmpdir.join("events.log").strpath

    actual = broker.from_endpoint_config(
        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 #4
0
def test_event_default_metadata(event_class):

    # 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 #5
0
def test_pushing_event(rasa_app, event):
    cid = str(uuid.uuid1())
    conversation = "/conversations/{}".format(cid)

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

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

    evt = tracker.get("events")[1]
    assert Event.from_parameters(evt) == event
Example #6
0
def test_json_parse_reminder_cancelled():
    evt = {
        "event": "cancel_reminder",
        "name": "my_reminder",
        "intent": "my_intent",
        "entities": [
            {"entity": "entity1", "value": "value1"},
            {"entity": "entity2", "value": "value2"},
        ],
        "date_time": "2018-09-03T11:41:10.128172",
    }
    assert Event.from_parameters(evt) == ReminderCancelled(
        name="my_reminder",
        intent="my_intent",
        entities=[
            {"entity": "entity1", "value": "value1"},
            {"entity": "entity2", "value": "value2"},
        ],
        timestamp=parser.parse("2018-09-03T11:41:10.128172"),
    )
Example #7
0
def test_file_broker_properly_logs_newlines(tmp_path):
    log_file_path = str(tmp_path / "events.log")

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

    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(log_file_path, "r") as log_file:
        for line in log_file:
            recovered.append(Event.from_parameters(json.loads(line)))

    assert recovered == [event_with_newline]
Example #8
0
def test_file_broker_properly_logs_newlines(tmpdir):
    fname = tmpdir.join("events.log").strpath

    actual = broker.from_endpoint_config(
        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]
Example #9
0
    async def append_event(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.",
        )

        evt = Event.from_parameters(request.json)
        verbosity = event_verbosity_parameter(request,
                                              EventVerbosity.AFTER_RESTART)

        tracker = obtain_tracker_store(app.agent, conversation_id)

        if evt:
            try:
                tracker.update(evt)
                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),
                )

        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"
            },
        )
Example #10
0
    def _get_events_from_request_body(request: Request) -> List[Event]:
        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:
            common_utils.raise_warning(
                f"Append event called, but could not extract a valid event. "
                f"Request JSON: {request.json}"
            )
            raise ErrorResponse(
                400,
                "BadRequest",
                "Couldn't extract a proper event from the request body.",
                {"parameter": "", "in": "body"},
            )

        return events
Example #11
0
def test_json_parse_reminder():
    # fmt: off
    # DOCS MARKER ReminderScheduled
    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,
    }
    # DOCS END
    # fmt: on
    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 #12
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 #13
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 #14
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 #15
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 #16
0
def test_dict_serialisation(one_event):
    evt_dict = one_event.as_dict()
    recovered_event = Event.from_parameters(evt_dict)
    assert hash(one_event) == hash(recovered_event)
Example #17
0
def test_bot_output_format():
    message = {
        "event": "bot",
        "text": "Hello!",
        "data": {
            "image":
            "http://example.com/myimage.png",
            "attachment":
            "My Attachment",
            "buttons": [
                {
                    "title": "yes",
                    "payload": "/yes"
                },
                {
                    "title": "no",
                    "payload": "/no",
                    "extra": "extra"
                },
            ],
            "elements": [
                {
                    "title": "element1",
                    "buttons": [{
                        "title": "button1",
                        "payload": "/button1"
                    }],
                },
                {
                    "title": "element2",
                    "buttons": [{
                        "title": "button2",
                        "payload": "/button2"
                    }],
                },
            ],
            "quick_replies": [
                {
                    "title": "quick_reply1",
                    "buttons": [{
                        "title": "button3",
                        "payload": "/button3"
                    }],
                },
                {
                    "title": "quick_reply2",
                    "buttons": [{
                        "title": "button4",
                        "payload": "/button4"
                    }],
                },
            ],
        },
    }
    from rasa.core.events import Event

    bot_event = Event.from_parameters(message)

    assert isinstance(bot_event, BotUttered)

    formatted = interactive.format_bot_output(bot_event)
    assert formatted == ("Hello!\n"
                         "Image: http://example.com/myimage.png\n"
                         "Attachment: My Attachment\n"
                         "Buttons:\n"
                         "1: yes (/yes)\n"
                         '2: no (/no) - {"extra": "extra"}\n'
                         "Type out your own message...\n"
                         "Elements:\n"
                         '1: element1 - {"buttons": '
                         '[{"payload": "/button1", "title": "button1"}]'
                         '}\n2: element2 - {"buttons": '
                         '[{"payload": "/button2", "title": "button2"}]'
                         "}\nQuick replies:\n"
                         '1: quick_reply1 - {"buttons": '
                         '[{"payload": "/button3", "title": "button3"}'
                         ']}\n2: quick_reply2 - {"buttons": '
                         '[{"payload": "/button4", "title": "button4"}'
                         "]}")
Example #18
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 #19
0
def test_json_parse_restarted():
    # DOCS MARKER Restarted
    evt = {"event": "restart"}
    # DOCS END
    assert Event.from_parameters(evt) == Restarted()
Example #20
0
def test_json_parse_session_started():
    # DOCS MARKER SessionStarted
    evt = {"event": "session_started"}
    # DOCS END
    assert Event.from_parameters(evt) == SessionStarted()
Example #21
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 #22
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 #23
0
def test_json_parse_resume():
    # DOCS MARKER ConversationResumed
    evt = {"event": "resume"}
    # DOCS END
    assert Event.from_parameters(evt) == ConversationResumed()
Example #24
0
def test_json_parse_reset():
    # DOCS MARKER AllSlotsReset
    evt = {"event": "reset_slots"}
    # DOCS END
    assert Event.from_parameters(evt) == AllSlotsReset()
Example #25
0
from rasa.core.events import Event, UserUttered, SlotSet, BotUttered
from rasa.core.trackers import DialogueStateTracker
from rasa.model import unpack_model
from rasa.utils.endpoints import EndpointConfig
from sanic import Sanic
from sanic.testing import SanicTestClient
from tests.nlu.utilities import ResponseTest

# a couple of event instances that we can use for testing
test_events = [
    Event.from_parameters({
        "event": UserUttered.type_name,
        "text": "/goodbye",
        "parse_data": {
            "intent": {
                "confidence": 1.0,
                "name": "greet"
            },
            "entities": [],
        },
    }),
    BotUttered("Welcome!", {"test": True}),
    SlotSet("cuisine", 34),
    SlotSet("cuisine", "34"),
    SlotSet("location", None),
    SlotSet("location", [34, "34", None]),
]


@pytest.fixture
def rasa_app_without_api(rasa_server_without_api: Sanic) -> SanicTestClient:
Example #26
0
def test_json_parse_export():
    # DOCS MARKER StoryExported
    evt = {"event": "export"}
    # DOCS END
    assert Event.from_parameters(evt) == StoryExported()
Example #27
0
def test_json_parse_rewind():
    # DOCS MARKER UserUtteranceReverted
    evt = {"event": "rewind"}
    # DOCS END
    assert Event.from_parameters(evt) == UserUtteranceReverted()
Example #28
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!", {})
Example #29
0
def test_json_parse_undo():
    # DOCS MARKER ActionReverted
    evt = {"event": "undo"}
    # DOCS END
    assert Event.from_parameters(evt) == ActionReverted()
Example #30
0
def test_json_parse_pause():
    # DOCS MARKER ConversationPaused
    evt = {"event": "pause"}
    # DOCS END
    assert Event.from_parameters(evt) == ConversationPaused()