Exemple #1
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)
Exemple #2
0
 def add_event(self, event_name, parameters):
     parsed = Event.from_story_string(event_name, parameters, self.domain,
                                      default=ActionExecuted)
     if parsed is None:
         raise StoryParseError("Unknown event '{}'. It is Neither an event "
                               "nor an action).".format(event_name))
     self.current_step_builder.add_event(parsed)
Exemple #3
0
 def add_user_messages(self, messages, line_num):
     if not self.current_step_builder:
         raise StoryParseError("User message '{}' at invalid location. "
                               "Expected story start.".format(messages))
     parsed_messages = []
     for m in messages:
         parse_data = self.interpreter.parse(m)
         # a user uttered event's format is a bit different to the one of
         # other events, so we need to take a shortcut here
         parameters = {"text": m, "parse_data": parse_data}
         utterance = Event.from_story_string(UserUttered.type_name,
                                             parameters)
         if m.startswith("_"):
             c = utterance.as_story_string()
             logger.warning("Stating user intents with a leading '_' is "
                            "deprecated. The new format is "
                            "'* {}'. Please update "
                            "your example '{}' to the new format."
                            "".format(c, m))
         intent_name = utterance.intent.get("name")
         if intent_name not in self.domain.intents:
             logger.warning("Found unknown intent '{}' on line {}. "
                            "Please, make sure that all intents are "
                            "listed in your domain yaml."
                            "".format(intent_name, line_num))
         parsed_messages.append(utterance)
     self.current_step_builder.add_user_messages(parsed_messages)
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
Exemple #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": []
                                                     })
Exemple #6
0
 def add_user_messages(self, messages, line_num):
     if not self.current_step_builder:
         raise StoryParseError("User message '{}' at invalid location. "
                               "Expected story start.".format(messages))
     parsed_messages = []
     for m in messages:
         parse_data = self.interpreter.parse(m)
         # a user uttered event's format is a bit different to the one of
         # other events, so we need to take a shortcut here
         parameters = {"text": m, "parse_data": parse_data}
         utterance = Event.from_story_string(UserUttered.type_name,
                                             parameters)
         if m.startswith("_"):
             c = utterance.as_story_string()
             logger.warning("Stating user intents with a leading '_' is "
                            "deprecated. The new format is "
                            "'* {}'. Please update "
                            "your example '{}' to the new format."
                            "".format(c, m))
         intent_name = utterance.intent.get("name")
         if intent_name not in self.domain.intents:
             logger.warning("Found unknown intent '{}' on line {}. "
                            "Please, make sure that all intents are "
                            "listed in your domain yaml."
                            "".format(intent_name, line_num))
         parsed_messages.append(utterance)
     self.current_step_builder.add_user_messages(parsed_messages)
Exemple #7
0
def test_pushing_events(app, event):
    cid = str(uuid.uuid1())
    conversation = "http://dummy/conversations/{}".format(cid)
    data = json.dumps({"query": "/greet"})
    response = app.post("{}/parse".format(conversation),
                        data=data,
                        content_type='application/json')
    content = response.get_json()
    assert response.status_code == 200

    data = json.dumps({"events": [], "executed_action": "utter_greet"})
    response = app.post("{}/continue".format(conversation),
                        data=data,
                        content_type='application/json')
    content = response.get_json()
    assert response.status_code == 200

    data = json.dumps([event.as_dict()])
    response = app.post("{}/tracker/events".format(conversation),
                        data=data,
                        content_type='application/json')
    content = response.get_json()
    assert response.status_code == 200

    tracker_response = app.get("http://dummy/conversations/{}/tracker"
                               "".format(cid))
    tracker = tracker_response.get_json()
    assert tracker is not None
    assert len(tracker.get("events")) == 5

    evt = tracker.get("events")[4]
    assert Event.from_parameters(evt) == event
Exemple #8
0
def test_json_parse_resume():
    # DOCS MARKER ConversationResumed
    evt = \
        {
            'event': 'resume',
        }
    # DOCS END
    assert Event.from_parameters(evt) == ConversationResumed()
Exemple #9
0
def test_json_parse_pause():
    # DOCS MARKER ConversationPaused
    evt = \
        {
            'event': 'pause',
        }
    # DOCS END
    assert Event.from_parameters(evt) == ConversationPaused()
Exemple #10
0
def test_json_parse_export():
    # DOCS MARKER StoryExported
    evt = \
        {
            'event': 'export',
        }
    # DOCS END
    assert Event.from_parameters(evt) == StoryExported()
Exemple #11
0
def test_json_parse_undo():
    # DOCS MARKER ActionReverted
    evt = \
        {
            'event': 'undo',
        }
    # DOCS END
    assert Event.from_parameters(evt) == ActionReverted()
Exemple #12
0
def test_json_parse_rewind():
    # DOCS MARKER UserUtteranceReverted
    evt = \
        {
            'event': 'rewind'
        }
    # DOCS END
    assert Event.from_parameters(evt) == UserUtteranceReverted()
Exemple #13
0
def test_json_parse_reset():
    # DOCS MARKER AllSlotsReset
    evt = \
        {
            'event': 'reset_slots'
        }
    # DOCS END
    assert Event.from_parameters(evt) == AllSlotsReset()
Exemple #14
0
def test_json_parse_restarted():
    # DOCS MARKER Restarted
    evt = \
        {
            'event': 'restart'
        }
    # DOCS END
    assert Event.from_parameters(evt) == Restarted()
Exemple #15
0
def test_json_parse_restarted():
    # DOCS MARKER Restarted
    evt = \
        {
            'event': 'restart'
        }
    # DOCS END
    assert Event.from_parameters(evt) == Restarted()
Exemple #16
0
def test_json_parse_pause():
    # DOCS MARKER ConversationPaused
    evt = \
        {
            'event': 'pause',
        }
    # DOCS END
    assert Event.from_parameters(evt) == ConversationPaused()
Exemple #17
0
def test_json_parse_reset():
    # DOCS MARKER AllSlotsReset
    evt = \
        {
            'event': 'reset_slots'
        }
    # DOCS END
    assert Event.from_parameters(evt) == AllSlotsReset()
Exemple #18
0
def test_json_parse_export():
    # DOCS MARKER StoryExported
    evt = \
        {
            'event': 'export',
        }
    # DOCS END
    assert Event.from_parameters(evt) == StoryExported()
Exemple #19
0
def test_json_parse_undo():
    # DOCS MARKER ActionReverted
    evt = \
        {
            'event': 'undo',
        }
    # DOCS END
    assert Event.from_parameters(evt) == ActionReverted()
Exemple #20
0
def test_json_parse_resume():
    # DOCS MARKER ConversationResumed
    evt = \
        {
            'event': 'resume',
        }
    # DOCS END
    assert Event.from_parameters(evt) == ConversationResumed()
Exemple #21
0
def test_json_parse_rewind():
    # DOCS MARKER UserUtteranceReverted
    evt = \
        {
            'event': 'rewind'
        }
    # DOCS END
    assert Event.from_parameters(evt) == UserUtteranceReverted()
Exemple #22
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")
Exemple #23
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")
Exemple #24
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")
Exemple #25
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?")
Exemple #26
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?")
Exemple #27
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")
Exemple #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!", {})
Exemple #29
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!", {})
Exemple #30
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")
Exemple #31
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")
Exemple #32
0
    def append_event_to_tracker(self, sender_id: Text, event: Event) -> None:
        """Add some more events to the tracker of a conversation."""

        url = "/conversations/{}/tracker/events".format(sender_id)

        result = self.core_endpoint.request(subpath=url,
                                            method="post",
                                            json=event.as_dict())
        result.raise_for_status()
        return result.json()
Exemple #33
0
def convert_obj_2_tracker_events(serialized_events, domain):
    # Example format: {"event": "set_slot", "value": 5, "name": "my_slot"}

    deserialized = []
    for e in serialized_events:
        etype = e.get("event")
        if etype is not None:
            del e["event"]
            deserialized.append(Event.from_parameters(etype, e, domain))
    return deserialized
Exemple #34
0
    def append_event(sender_id):
        """Append a list of events to the state of a conversation"""

        request_params = request.get_json(force=True)
        evt = Event.from_parameters(request_params)
        tracker = agent.tracker_store.get_or_create_tracker(sender_id)
        if evt:
            tracker.update(evt)
            agent.tracker_store.save(tracker)
        else:
            logger.warning(
                "Append event called, but could not extract a "
                "valid event. Request JSON: {}".format(request_params))
        return jsonify(tracker.current_state(EventVerbosity.AFTER_RESTART))
Exemple #35
0
    def append_event(sender_id):
        """Append a list of events to the state of a conversation"""

        request_params = request.get_json(force=True)
        evt = Event.from_parameters(request_params)
        tracker = agent.tracker_store.get_or_create_tracker(sender_id)
        if evt:
            tracker.update(evt)
            agent.tracker_store.save(tracker)
        else:
            logger.warning(
                    "Append event called, but could not extract a "
                    "valid event. Request JSON: {}".format(request_params))
        return jsonify(tracker.current_state(should_include_events=True))
Exemple #36
0
def test_json_parse_reminder():
    # DOCS MARKER ReminderScheduled
    evt = \
        {
            'event': 'reminder',
            'action': 'my_action',
            'date_time': '2018-09-03T11:41:10.128172',
            'name': 'my_reminder',
            'kill_on_user_msg': True
        }
    # DOCS END
    assert Event.from_parameters(evt) == ReminderScheduled(
            "my_action",
            parser.parse('2018-09-03T11:41:10.128172'),
            name='my_reminder',
            kill_on_user_message=True)
Exemple #37
0
def test_json_parse_reminder():
    # DOCS MARKER ReminderScheduled
    evt = \
        {
            'event': 'reminder',
            'action': 'my_action',
            'date_time': '2018-09-03T11:41:10.128172',
            'name': 'my_reminder',
            'kill_on_user_msg': True
        }
    # DOCS END
    assert Event.from_parameters(evt) == ReminderScheduled(
        "my_action",
        parser.parse('2018-09-03T11:41:10.128172'),
        name='my_reminder',
        kill_on_user_message=True)
Exemple #38
0
    def add_event(self, event_name, parameters):

        # add 'name' only if event is not a SlotSet,
        # because there might be a slot with slot_key='name'
        if "name" not in parameters and event_name != SlotSet.type_name:
            parameters["name"] = event_name

        parsed = Event.from_story_string(event_name, parameters,
                                         default=ActionExecuted)
        if parsed is None:
            raise StoryParseError("Unknown event '{}'. It is Neither an event "
                                  "nor an action).".format(event_name))
        if isinstance(parsed, list):
            for p in parsed:
                self.current_step_builder.add_event(p)
        else:
            self.current_step_builder.add_event(parsed)
Exemple #39
0
    def add_event(self, event_name, parameters):

        # add 'name' only if event is not a SlotSet,
        # because there might be a slot with slot_key='name'
        if "name" not in parameters and event_name != SlotSet.type_name:
            parameters["name"] = event_name

        parsed = Event.from_story_string(event_name,
                                         parameters,
                                         default=ActionExecuted)
        if parsed is None:
            raise StoryParseError("Unknown event '{}'. It is Neither an event "
                                  "nor an action).".format(event_name))
        if isinstance(parsed, list):
            for p in parsed:
                self.current_step_builder.add_event(p)
        else:
            self.current_step_builder.add_event(parsed)
Exemple #40
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
Exemple #41
0
    def add_event(self, event_name, parameters):

        # add 'name' only if event is not a SlotSet,
        # because there might be a slot with slot_key='name'
        if "name" not in parameters and event_name != SlotSet.type_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))
        if self.current_step_builder is None:
            raise StoryParseError("Failed to handle event '{}'. There is no "
                                  "started story block available. "
                                  "".format(event_name))

        for p in parsed_events:
            self.current_step_builder.add_event(p)
Exemple #42
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]
Exemple #43
0
    def append_event(sender_id):
        """Append a list of events to the state of a conversation"""

        request_params = request.get_json(force=True)
        evt = Event.from_parameters(request_params)
        tracker = agent.tracker_store.get_or_create_tracker(sender_id)
        verbosity = event_verbosity_parameter(EventVerbosity.AFTER_RESTART)

        if evt:
            tracker.update(evt)
            agent.tracker_store.save(tracker)
            return jsonify(tracker.current_state(verbosity))
        else:
            logger.warning(
                "Append event called, but could not extract a "
                "valid event. Request JSON: {}".format(request_params))
            return error(400, "InvalidParameter",
                         "Couldn't extract a proper event from the request "
                         "body.",
                         {"parameter": "", "in": "body"})
Exemple #44
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": []
            })
Exemple #45
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"})
Exemple #46
0
def test_pushing_event(app, event):
    cid = str(uuid.uuid1())
    conversation = "http://dummy/conversations/{}".format(cid)
    data = json.dumps({"query": "/greet"})
    response = app.post("{}/respond".format(conversation),
                        data=data, content_type='application/json')
    content = response.get_json()
    assert response.status_code == 200

    data = json.dumps(event.as_dict())
    response = app.post("{}/tracker/events".format(conversation),
                        data=data, content_type='application/json')
    content = response.get_json()
    assert response.status_code == 200

    tracker_response = app.get("http://dummy/conversations/{}/tracker"
                               "".format(cid))
    tracker = tracker_response.get_json()
    assert tracker is not None
    assert len(tracker.get("events")) == 6

    evt = tracker.get("events")[5]
    assert Event.from_parameters(evt) == event
Exemple #47
0
from rasa_core.events import (UserUttered, BotUttered, SlotSet, Event,
                              ActionExecuted)
from rasa_core.interpreter import RegexInterpreter
from rasa_core.policies.memoization import AugmentedMemoizationPolicy
from rasa_core.remote import RasaCoreClient, RemoteAgent
from rasa_core.utils import EndpointConfig
from tests.conftest import DEFAULT_STORIES_FILE

# 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(scope="module")
def http_app(request, core_server):
def _chat_history_table(evts):
    # type: (List[Dict[Text, Any]]) -> Text
    """Create a table containing bot and user messages.

    Also includes additional information, like any events and
    prediction probabilities."""
    def wrap(txt, max_width):
        return "\n".join(
            textwrap.wrap(txt, max_width, replace_whitespace=False))

    def colored(txt, color):
        return "{" + color + "}" + txt + "{/" + color + "}"

    def format_user_msg(user_evt, max_width):
        _parsed = user_evt.get('parse_data', {})
        _intent = _parsed.get('intent', {}).get("name")
        _confidence = _parsed.get('intent', {}).get("confidence", 1.0)
        _md = _as_md_message(_parsed)

        _lines = [
            colored(wrap(_md, max_width), "hired"),
            "intent: {} {:03.2f}".format(_intent, _confidence)
        ]
        return "\n".join(_lines)

    def bot_width(_table):
        # type: (AsciiTable) -> int
        return _table.column_max_width(1)

    def user_width(_table):
        # type: (AsciiTable) -> int
        return _table.column_max_width(3)

    def add_bot_cell(data, cell):
        data.append([len(data), Color(cell), "", ""])

    def add_user_cell(data, cell):
        data.append([len(data), "", "", Color(cell)])

    # prints the historical interactions between the bot and the user,
    # to help with correctly identifying the action
    table_data = [
        [
            "#  ",
            Color(colored('Bot      ', 'autoblue')), "  ",
            Color(colored('You       ', 'hired'))
        ],
    ]

    table = SingleTable(table_data, 'Chat History')

    bot_column = []
    for idx, evt in enumerate(evts):
        if evt.get("event") == "action":
            bot_column.append(colored(evt['name'], 'autocyan'))
            if evt['confidence'] is not None:
                bot_column[-1] += (colored(
                    " {:03.2f}".format(evt['confidence']), 'autowhite'))

        elif evt.get("event") == 'user':
            if bot_column:
                text = "\n".join(bot_column)
                add_bot_cell(table_data, text)
                bot_column = []

            msg = format_user_msg(evt, user_width(table))
            add_user_cell(table_data, msg)

        elif evt.get("event") == "bot":
            wrapped = wrap(format_bot_output(evt), bot_width(table))
            bot_column.append(colored(wrapped, 'autoblue'))

        elif evt.get("event") != "bot":
            e = Event.from_parameters(evt)
            bot_column.append(wrap(e.as_story_string(), bot_width(table)))

    if bot_column:
        text = "\n".join(bot_column)
        add_bot_cell(table_data, text)

    table.inner_heading_row_border = False
    table.inner_row_border = True
    table.inner_column_border = False
    table.outer_border = False
    table.justify_columns = {0: 'left', 1: 'left', 2: 'center', 3: 'right'}

    return table.table
Exemple #49
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)
Exemple #50
0
from rasa_core.channels import CollectingOutputChannel
from rasa_core.domain import Domain
from rasa_core.events import (
    UserUttered, BotUttered, SlotSet, Event, ActionExecuted)
from rasa_core.interpreter import RegexInterpreter
from rasa_core.policies.memoization import AugmentedMemoizationPolicy
from rasa_core.remote import RasaCoreClient
from rasa_core.utils import EndpointConfig
from tests.conftest import DEFAULT_STORIES_FILE

# 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(scope="module")
def app(core_server):
    return core_server.test_client()