Пример #1
0
def test_incorrect_access_fn() -> None:
    """
    This test shows that the plugin needs `access` function to be a `PluginFn`,
    or else it throws a `TypeError`.
    """
    rules = {"basic": {"slot_name": "basic_slot", "entity_type": "basic"}}
    access = 5

    slot_filler = RuleBasedSlotFillerPlugin(rules=rules, access=access)()
    workflow = Workflow(preprocessors=[], postprocessors=[slot_filler])
    intent = Intent(name="intent", score=0.8)

    body = "12th december"
    entity = BaseEntity(
        range={
            "from": 0,
            "to": len(body)
        },
        body=body,
        dim="default",
        type="basic",
        values=[{
            "key": "value"
        }],
        slot_names=["basic_slot"],
    )

    workflow.output = (intent, [entity])

    with pytest.raises(TypeError):
        workflow.run("")
def test_get_list_entities(payload):
    input_ = payload.get("input")
    lang_ = payload.get("lang")
    expected = payload.get("expected")
    exception = payload.get("exception")
    config = payload.get("config")
    transcripts = [expectation["text"] for expectation in input_]

    if expected:
        list_entity_plugin = ListSearchPlugin(dest="output.entities", **config)

        workflow = Workflow([list_entity_plugin])
        _, output = workflow.run(Input(utterances=transcripts, lang=lang_))
        entities = output["entities"]

        if not entities and expected:
            pytest.fail("No entities found!")

        for i, entity in enumerate(entities):
            assert entity["value"] == expected[i]["value"]
            assert entity["type"] == expected[i]["type"]
            if "score" in expected[i]:
                assert entity["score"] == expected[i]["score"]
    else:
        with pytest.raises(EXCEPTIONS.get(exception)):
            list_entity_plugin = ListSearchPlugin(dest="output.entities",
                                                  **config)

            workflow = Workflow([list_entity_plugin])
            workflow.run(Input(utterances=transcripts, lang=lang_))
def test_slot_invalid_intent() -> None:
    """
    Here, we will see that an entity will not fill an intent unless the intent has a slot for it.
    `intent_1` doesn't have a slot for an entity of type `entity_2`.
    """
    intent_name = "intent_1"
    # ... a mock `Intent`
    intent = Intent(name=intent_name, score=0.8)

    # Setting up the slot-filler, both instantiation and plugin is created. (notice two calls).
    slot_filler = RuleBasedSlotFillerPlugin(rules=rules, dest="output.intents")

    # Create a mock `workflow`
    workflow = Workflow([slot_filler])

    # and a mock `Entity`.
    body = "12th december"
    entity = BaseEntity(
        range={
            "from": 0,
            "to": len(body)
        },
        body=body,
        dim="default",
        entity_type="entity_1",
        values=[{
            "key": "value"
        }],
    )

    # The RuleBasedSlotFillerPlugin specifies that it expects `Tuple[Intent, List[Entity])` on `access(workflow)`.
    workflow.set("output.intents", [1]).set("output.entities", [entity])

    with pytest.raises(AttributeError):
        workflow.run(Input(utterances=body))
Пример #4
0
def test_entity_type(payload) -> None:
    """
    Evaluate a set of cases from a file.
    """
    body = payload["input"]
    mock_entity_json = payload["mock_entity_json"]
    expected = payload.get("expected")
    exception = payload.get("exception")

    duckling_plugin = DucklingPlugin(
        dest="output.entities",
        dimensions=["people", "time", "date", "duration"],
        locale="en_IN",
        timezone="Asia/Kolkata",
    )

    request_callback = request_builder(mock_entity_json)
    httpretty.register_uri(httpretty.POST,
                           "http://0.0.0.0:8000/parse",
                           body=request_callback)

    workflow = Workflow([duckling_plugin])

    if expected:
        _, output = workflow.run(Input(utterances=body))
        entities = output["entities"]
        for i, entity in enumerate(entities):
            assert entity["entity_type"] == expected[i]["entity_type"]
    elif exception:
        with pytest.raises(EXCEPTIONS[exception]):
            workflow.run(Input(utterances=body))
Пример #5
0
def test_max_workers_greater_than_zero() -> None:
    """Checks that "ValueError: max_workers must be greater than 0" is not raised when there are no transcriptions

    When we get an empty transcription from ASR in a production setup, FSM does not send the empty transcription to the SLU service.

    Whereas in a development setup, when one tries to run `slu test` with atleast one data point that does not have any transcriptions(`[]`)
    it will raise a `ValueError: max_workers must be greater than 0` exception.

    The corresponding fix has been done and this test ensures that the exception is not raised when there are no transcriptions even in development setup

    :return: None
    :rtype: None
    """
    locale = "en_IN"

    duckling_plugin = DucklingPlugin(
        dest="output.entities",
        dimensions=["time"],
        timezone="Asia/Kolkata",
        url="https://duckling/parse",
    )

    workflow = Workflow([duckling_plugin])
    alternatives = []  # When ASR returns empty transcriptions.
    try:
        workflow.run(Input(utterances=alternatives, locale=locale))
    except ValueError as exc:
        pytest.fail(f"{exc}")
Пример #6
0
def test_plugin_no_entities() -> None:
    """
    An end-to-end example showing how `DucklingParser` works in case
    the input has no entities.
    """
    body = "i need it"
    expected = []

    def access(workflow):
        return workflow.input, None

    def mutate(workflow, entities):
        workflow.output = {"entities": entities}

    parser = DucklingParser(access=access,
                            mutate=mutate,
                            dimensions=["people"],
                            locale="en_IN")

    request_callback = request_builder(expected)
    httpretty.register_uri(httpretty.POST,
                           "http://0.0.0.0:8000/parse",
                           body=request_callback)

    workflow = Workflow(preprocessors=[parser()], postprocessors=[])
    workflow.run(body)
    assert workflow.output["entities"] == []
Пример #7
0
def test_missing_access_fn() -> None:
    """
    This test shows that the plugin needs an `access` provided or else it raises a type error.
    """
    slot_filler = RuleBasedSlotFillerPlugin(rules=rules)()
    workflow = Workflow(preprocessors=[], postprocessors=[slot_filler])
    intent = Intent(name="intent", score=0.8)

    body = "12th december"
    entity = BaseEntity(
        range={
            "from": 0,
            "to": len(body)
        },
        body=body,
        dim="default",
        type="basic",
        values=[{
            "key": "value"
        }],
        slot_names=["basic_slot"],
    )

    workflow.output = (intent, [entity])

    with pytest.raises(TypeError):
        workflow.run("")
Пример #8
0
def test_slot_filling_multiple() -> None:
    """
    Let's try filling both the slots this time with fill_multiple=True!
    `intent_2` supports both `entity_1` and `entity_2`.
    """
    def access(workflow: Workflow) -> Any:
        return workflow.output

    intent_name = "intent_2"

    # Setting up the slot-filler, both instantiation and plugin is created. (notice two calls).
    slot_filler = RuleBasedSlotFillerPlugin(rules=rules,
                                            access=access,
                                            fill_multiple=True)()

    # Create a mock `workflow`
    workflow = Workflow(preprocessors=[], postprocessors=[slot_filler])

    # ... a mock `Intent`
    intent = Intent(name=intent_name, score=0.8)

    # and mock `Entity`-ies.
    body = "12th december"
    entity_1 = BaseEntity(
        range={
            "from": 0,
            "to": len(body)
        },
        body=body,
        dim="default",
        type="entity_1",
        values=[{
            "key": "value"
        }],
        slot_names=["entity_1_slot"],
    )

    entity_2 = BaseEntity(
        range={
            "from": 0,
            "to": len(body)
        },
        body=body,
        dim="default",
        type="entity_2",
        values=[{
            "key": "value"
        }],
        slot_names=["entity_2_slot"],
    )

    # The RuleBasedSlotFillerPlugin specifies that it expects `Tuple[Intent, List[Entity])` on `access(workflow)`.
    workflow.output = (intent, [entity_1, entity_2])
    workflow.run(body)

    # `workflow.output[0]` is the `Intent` we created.
    # The `entity_1_slot` and `entity_2_slot` are filled.
    assert workflow.output[0].slots["entity_1_slot"].values == [entity_1]
    assert workflow.output[0].slots["entity_2_slot"].values == [entity_2]
Пример #9
0
def test_slot_competition() -> None:
    """
    What happens when we have two entities of the same type but different value?
    """
    def access(workflow: Workflow) -> Any:
        return workflow.output

    intent_name = "intent_1"

    # Setting up the slot-filler, both instantiation and plugin is created. (notice two calls).
    slot_filler = RuleBasedSlotFillerPlugin(rules=rules, access=access)()

    # Create a mock `workflow`
    workflow = Workflow(preprocessors=[], postprocessors=[slot_filler])

    # ... a mock `Intent`
    intent = Intent(name=intent_name, score=0.8)

    # Here we have two entities which compete for the same slot but have different values.
    body = "12th december"
    entity_1 = BaseEntity(
        range={
            "from": 0,
            "to": len(body)
        },
        body=body,
        dim="default",
        type="entity_1",
        values=[{
            "key": "value_1"
        }],
        slot_names=["entity_1_slot"],
    )

    entity_2 = BaseEntity(
        range={
            "from": 0,
            "to": len(body)
        },
        body=body,
        dim="default",
        type="entity_1",
        values=[{
            "key": "value_2"
        }],
        slot_names=["entity_1_slot"],
    )

    # The RuleBasedSlotFillerPlugin specifies that it expects `Tuple[Intent, List[Entity])` on `access(workflow)`.
    workflow.output = (intent, [entity_1, entity_2])
    workflow.run(body)

    # `workflow.output[0]` is the `Intent` we created.
    # The `entity_1_slot` and `entity_2_slot` are filled.
    assert "entity_1_slot" not in workflow.output[0].slots
Пример #10
0
def test_merge_asr_output() -> None:
    """
    This case shows the merge in case there is only one option.
    """

    workflow = Workflow(
        preprocessors=[merge_asr_output_plugin(access, mutate)], postprocessors=[]
    )

    workflow.run([[{"transcript": "hello world", "confidence": None}]])
    assert workflow.input == "<s> hello world </s>"
Пример #11
0
def test_plugin_io_type_mismatch(access, mutate) -> None:
    """
    Here we are chcking if the plugin has access to workflow.
    Since we have provided `access`, `mutate` of incorrect types to `DucklingParser`
    we will receive a `TypeError`.
    """
    parser = DucklingParser(access=access, mutate=mutate, locale="en_IN")
    plugin = parser()

    workflow = Workflow(preprocessors=[plugin], postprocessors=[])
    with pytest.raises(TypeError):
        workflow.run("")
Пример #12
0
def test_merge_keyerror_on_missing_transcript() -> None:
    """
    This test, shows that `transcript` is an important key. If the asr has a different key, than `transcript`
    then this plugin would not work for you.
    """

    workflow = Workflow(
        preprocessors=[merge_asr_output_plugin(access, mutate)], postprocessors=[]
    )

    with pytest.raises(TypeError):
        workflow.run([[{"not_transcript": "hello world", "confidence": None}]])
Пример #13
0
def test_tokenizer_plugin() -> None:
    """
    We will test the tokenizer plugin.
    """
    # create an instance of a `Workflow`.
    # we are calling the `arbitrary_plugin` to get the `plugin` de method.
    workflow = Workflow(
        preprocessors=[tokenizer_plugin(access=access, mutate=mutate)],
        postprocessors=[],
    )
    workflow.run("Mary had a little lambda")

    assert workflow.output == ["Mary", "had", "a", "little", "lambda"]
Пример #14
0
def test_plugin_working_cases(payload) -> None:
    """
    An end-to-end example showing how to use `DucklingPlugin` with a `Workflow`.
    """
    body = payload["input"]
    mock_entity_json = payload["mock_entity_json"]
    expected_types = payload.get("expected")
    exception = payload.get("exception")
    duckling_args = payload.get("duckling")
    response_code = payload.get("response_code", 200)
    locale = payload.get("locale")
    reference_time = payload.get("reference_time")
    use_latent = payload.get("use_latent")

    duckling_plugin = DucklingPlugin(dest="output.entities", **duckling_args)

    request_callback = request_builder(mock_entity_json,
                                       response_code=response_code)
    httpretty.register_uri(httpretty.POST,
                           "http://0.0.0.0:8000/parse",
                           body=request_callback)

    workflow = Workflow([duckling_plugin])
    if isinstance(reference_time, str):
        reference_time = make_unix_ts("Asia/Kolkata")(reference_time)

    if expected_types is not None:
        input_ = Input(
            utterances=body,
            locale=locale,
            reference_time=reference_time,
            latent_entities=use_latent,
        )
        _, output = workflow.run(input_)

        if not output["entities"]:
            assert output["entities"] == []

        for i, entity in enumerate(output["entities"]):
            expected_entity_type = expected_types[i]["entity_type"]
            assert entity["entity_type"] == expected_entity_type
    else:
        with pytest.raises(EXCEPTIONS[exception]):
            input_ = Input(
                utterances=body,
                locale=locale,
                reference_time=reference_time,
                latent_entities=use_latent,
            )
            workflow.run(input_)
Пример #15
0
def test_duckling_timeout() -> None:
    """
    [summary]

    :return: [description]
    :rtype: [type]
    """
    locale = "en_IN"
    wait_time = 0.1

    def raise_timeout(_, __, headers):
        time.sleep(wait_time)
        return 200, headers, "received"

    httpretty.register_uri(httpretty.POST,
                           "http://0.0.0.0:8000/parse",
                           body=raise_timeout)

    duckling_plugin = DucklingPlugin(
        locale=locale,
        dimensions=["time"],
        timezone="Asia/Kolkata",
        threshold=0.2,
        timeout=0.01,
        dest="output.entities",
    )

    workflow = Workflow([duckling_plugin])
    _, output = workflow.run(Input(utterances="test"))
    assert output["entities"] == []
def test_plugin_cases(payload) -> None:
    """
    Test cases where the plugin should work.
    """
    entities = payload.get("inputs", {}).get("entities", [])
    tracker = payload.get("inputs", {}).get("tracker", [])
    expected = payload.get("expected", {})
    duckling_plugin = DucklingPlugin(dimensions=["date", "time"],
                                     timezone="Asia/Kolkata",
                                     dest="output.entities")

    for i, entity in enumerate(entities):
        current_turn_entities = duckling_plugin._reshape(entity, i)

    combine_date_time_plugin = CombineDateTimeOverSlots(
        trigger_intents=["_callback_"],
        dest="output.entities",
    )

    workflow = Workflow(plugins=[combine_date_time_plugin])
    workflow.output = Output(entities=current_turn_entities)
    _, output = workflow.run(Input(utterances=[""], slot_tracker=tracker))
    entity_values = [entity["value"] for entity in output[const.ENTITIES]]

    if len(entity_values) != len(expected):
        pytest.fail("Expected {} entities but got {}".format(
            len(expected), len(entity_values)))

    for entity_value, expected_value in zip(entity_values, expected):
        try:
            expected = datetime.fromisoformat(expected_value)
            generated = datetime.fromisoformat(entity_value)
            assert generated == expected, f"Expected {expected} but got {generated}"
        except (ValueError, TypeError):
            assert entity_value == expected_value
def test_plugin_exit_at_missing_tracker():
    combine_date_time_plugin = CombineDateTimeOverSlots(
        trigger_intents=["_callback_"], dest="output.entities")

    workflow = Workflow(plugins=[combine_date_time_plugin])
    _, output = workflow.run(Input(utterances=[""]))
    assert output[const.ENTITIES] == []
Пример #18
0
def test_slot_filling_multiple() -> None:
    """
    Let's try filling both the slots this time with fill_multiple=True!
    `intent_2` supports both `entity_1` and `entity_2`.
    """
    intent_name = "intent_2"

    # Setting up the slot-filler, both instantiation and plugin is created. (notice two calls).
    slot_filler = RuleBasedSlotFillerPlugin(rules=rules,
                                            dest="output.intents",
                                            fill_multiple=True)

    # Create a mock `workflow`
    workflow = Workflow([slot_filler])

    # ... a mock `Intent`
    intent = Intent(name=intent_name, score=0.8)

    # and mock `Entity`-ies.
    body = "12th december"
    entity_1 = BaseEntity(
        range={
            "from": 0,
            "to": len(body)
        },
        body=body,
        dim="default",
        entity_type="entity_1",
        values=[{
            "key": "value"
        }],
    )

    entity_2 = BaseEntity(
        range={
            "from": 0,
            "to": len(body)
        },
        body=body,
        dim="default",
        entity_type="entity_2",
        values=[{
            "key": "value"
        }],
    )

    # The RuleBasedSlotFillerPlugin specifies that it expects `Tuple[Intent, List[Entity])` on `access(workflow)`.
    workflow.set("output.intents", [intent]).set("output.entities",
                                                 [entity_1, entity_2])
    _, output = workflow.run(Input(utterances=body))

    # `workflow.output[0]` is the `Intent` we created.
    # The `entity_1_slot` and `entity_2_slot` are filled.
    assert output[const.INTENTS][0]["slots"]["entity_1_slot"]["values"] == [
        entity_1.json()
    ]
    assert output[const.INTENTS][0]["slots"]["entity_2_slot"]["values"] == [
        entity_2.json()
    ]
Пример #19
0
def test_workflow_run_debug_mode() -> None:
    """
    This test is just to get coverage.
    """
    def mock_postproc(w):
        w.output = 10

    def mock_preproc(w):
        w.input = 20

    workflow = Workflow(preprocessors=[mock_preproc],
                        postprocessors=[mock_postproc],
                        debug=True)

    workflow.run(2)

    assert workflow.input == 20, "workflow.get_input() should be 2."
    assert workflow.output == 10, "workflow.get_output() should be 10."
Пример #20
0
def test_slot_competition_fill_multiple() -> None:
    """
    What happens when we have two entities of the same type but different value?
    """
    intent_name = "intent_1"

    # Setting up the slot-filler, both instantiation and plugin is created. (notice two calls).
    slot_filler = RuleBasedSlotFillerPlugin(rules=rules,
                                            dest="output.intents",
                                            fill_multiple=True)

    # Create a mock `workflow`
    workflow = Workflow([slot_filler])

    # ... a mock `Intent`
    intent = Intent(name=intent_name, score=0.8)

    # Here we have two entities which compete for the same slot but have different values.
    body = "12th december"
    entity_1 = BaseEntity(
        range={
            "from": 0,
            "to": len(body)
        },
        body=body,
        dim="default",
        entity_type="entity_1",
        values=[{
            "key": "value_1"
        }],
    )

    entity_2 = BaseEntity(
        range={
            "from": 0,
            "to": len(body)
        },
        body=body,
        dim="default",
        entity_type="entity_1",
        values=[{
            "key": "value_2"
        }],
    )

    workflow.set("output.intents", [intent]).set("output.entities",
                                                 [entity_1, entity_2])
    _, output = workflow.run(Input(utterances=body))

    # `workflow.output[0]` is the `Intent` we created.
    # The `entity_1_slot` and `entity_2_slot` are filled.

    assert output[const.INTENTS][0]["slots"]["entity_1_slot"]["values"] == [
        entity_1.json(),
        entity_2.json(),
    ]
Пример #21
0
def test_slot_no_fill() -> None:
    """
    Here, we will see that an entity will not fill an intent unless the intent has a slot for it.
    `intent_1` doesn't have a slot for an entity of type `entity_2`.
    """
    def access(workflow: Workflow) -> Any:
        return workflow.output

    intent_name = "intent_1"

    # Setting up the slot-filler, both instantiation and plugin is created. (notice two calls).
    slot_filler = RuleBasedSlotFillerPlugin(rules=rules, access=access)()

    # Create a mock `workflow`
    workflow = Workflow(preprocessors=[], postprocessors=[slot_filler])

    # ... a mock `Intent`
    intent = Intent(name=intent_name, score=0.8)

    # and a mock `Entity`.
    body = "12th december"
    entity = BaseEntity(
        range={
            "from": 0,
            "to": len(body)
        },
        body=body,
        dim="default",
        type="entity_2",
        values=[{
            "key": "value"
        }],
        slot_names=["entity_2_slot"],
    )

    # The RuleBasedSlotFillerPlugin specifies that it expects `Tuple[Intent, List[Entity])` on `access(workflow)`.
    workflow.output = (intent, [entity])
    workflow.run(body)

    # `workflow.output[0]` is the `Intent` we created.
    # we can see that the `entity_2_slot` is not filled by our mock entity.
    assert "entity_1_slot" not in workflow.output[0].slots
Пример #22
0
def test_slot_filling() -> None:
    """
    This test case covers a trivial usage of a slot-filler.
    We have `rules` that demonstrate association of intents with entities and their respective slot-configuration.
    """
    def access(workflow: Workflow) -> Any:
        return workflow.output

    intent_name = "intent_1"

    # Setting up the slot-filler, both instantiation and plugin is created. (notice two calls).
    slot_filler = RuleBasedSlotFillerPlugin(rules=rules, access=access)()

    # Create a mock `workflow`
    workflow = Workflow(preprocessors=[], postprocessors=[slot_filler])

    # ... a mock `Intent`
    intent = Intent(name=intent_name, score=0.8)

    # and a mock `Entity`.
    body = "12th december"
    entity = BaseEntity(
        range={
            "from": 0,
            "to": len(body)
        },
        body=body,
        dim="default",
        type="entity_1",
        values=[{
            "key": "value"
        }],
        slot_names=["entity_1_slot"],
    )

    # The RuleBasedSlotFillerPlugin specifies that it expects `Tuple[Intent, List[Entity])` on `access(workflow)`.
    workflow.output = (intent, [entity])
    workflow.run(body)

    # `workflow.output[0]` is the `Intent` we created.
    # so we are checking if the `entity_1_slot` is filled by our mock entity.
    assert workflow.output[0].slots["entity_1_slot"].values[0] == entity
Пример #23
0
def test_voting_0_intents():
    """
    The code uses division. So its always good to
    have a test to see if it takes care of division 0.
    """
    intents: List[Intent] = []
    vote_plugin = VotePlugin(dest="output.intents")
    workflow = Workflow([vote_plugin])
    workflow.output = Output(intents=intents)
    _, output = workflow.run(Input(utterances=["some text"]))
    assert output["intents"][0]["name"] == const.S_INTENT_OOS
Пример #24
0
def test_arbitrary_plugin() -> None:
    """
    We will test how an arbitrary-class-based plugin works with a workflow.
    """
    # create an instance of `ArbitraryPlugin`.
    arbitrary_plugin = ArbitraryPlugin(access=access, mutate=mutate)

    # create an instance of a `Workflow`.
    # we are calling the `arbitrary_plugin` to get the `plugin` de method.
    workflow = Workflow(preprocessors=[arbitrary_plugin()], postprocessors=[])

    # This runs all the `preprocessors` and `postprocessors` provided previously.
    # we can expect our `arbitrary_plugin` will also be used.
    workflow.run(([2, 5], ["hello", "hi"]))

    numbers, words = workflow.output  # pylint: disable=unpacking-non-sequence

    # This test would pass only if our plugin works correctly!
    assert numbers == [4, 7]
    assert words == ["hello world", "hi world"]
Пример #25
0
def test_voting_0_intents():
    """
    The code uses division. So its always good to
    have a test to see if it takes care of division 0.
    """
    intents: List[Intent] = []
    vote_plugin = VotePlugin(access=lambda w: (w.output[0], 0), mutate=update_intent)()
    workflow = Workflow(preprocessors=[], postprocessors=[vote_plugin])
    workflow.output = intents, []
    intent, _ = workflow.run(input_="")
    assert intent.name == const.S_INTENT_OOS
Пример #26
0
def test_workflow_run() -> None:
    """
    Trivial setup.
    """
    def mock_postproc(w) -> None:
        w.output = 10

    def mock_preproc(w) -> None:
        w.input = 20

    workflow = Workflow(preprocessors=[mock_preproc],
                        postprocessors=[mock_postproc])

    # initially the value of workflow.input is = 2
    workflow.run(2)

    # once the run method is complete, the value of input and output is modified by the
    # mock_postproc and mock_preproc functions.
    assert workflow.input == 20, "workflow.get_input() should be 20."
    assert workflow.output == 10, "workflow.get_output() should be 10."
Пример #27
0
def test_merge_longer_asr_output() -> None:
    """
    This case shows the merge in case there are multiple options.
    """
    workflow = Workflow(
        preprocessors=[merge_asr_output_plugin(access, mutate)], postprocessors=[]
    )

    workflow.run(
        [
            [
                {"transcript": "hello world", "confidence": None},
                {"transcript": "hello word", "confidence": None},
                {"transcript": "jello world", "confidence": None},
            ]
        ]
    )
    assert (
        workflow.input
        == "<s> hello world </s> <s> hello word </s> <s> jello world </s>"
    )
Пример #28
0
def test_workflow_history_logs() -> None:
    """
    We can execute the workflow.
    """
    workflow = Workflow(
        [MergeASROutputPlugin(dest="input.clf_feature", debug=True)],
        debug=True,
    )
    input_, _ = workflow.run(Input(utterances=["apples"]))
    assert input_["clf_feature"] == ["<s> apples </s>"]
    assert workflow.input == None
    assert workflow.output == Output()
Пример #29
0
def test_missing_access():
    intents = [
        Intent(name="a", score=0.3),
        Intent(name="a", score=0.2),
        Intent(name="b", score=0.1),
        Intent(name="b", score=0.1),
    ]

    vote_plugin = VotePlugin(mutate=update_intent)()
    workflow = Workflow(preprocessors=[], postprocessors=[vote_plugin])
    workflow.output = intents, []
    with pytest.raises(TypeError):
        intent, _ = workflow.run(input_="")
Пример #30
0
def test_plugin(body, expected) -> None:
    """
    An end-to-end example showing how to use `DucklingParser` with a `Worflow`.
    """
    def access(workflow):
        return workflow.input, None

    def mutate(workflow, entities):
        workflow.output = {"entities": entities}

    parser = DucklingParser(access=access,
                            mutate=mutate,
                            dimensions=["people"],
                            locale="en_IN")

    request_callback = request_builder(expected)
    httpretty.register_uri(httpretty.POST,
                           "http://0.0.0.0:8000/parse",
                           body=request_callback)

    workflow = Workflow(preprocessors=[parser()], postprocessors=[])
    workflow.run(body)
    assert isinstance(workflow.output["entities"][0], PeopleEntity)