From 13d7ba8d78256d6f5241b88282a963f1249b1e31 Mon Sep 17 00:00:00 2001 From: Kniesel Guido Date: Wed, 6 Feb 2019 10:28:52 +0100 Subject: [PATCH 01/27] added ReminderCancelled event --- rasa_core_sdk/events.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/rasa_core_sdk/events.py b/rasa_core_sdk/events.py index c944cf9bd..c799476db 100644 --- a/rasa_core_sdk/events.py +++ b/rasa_core_sdk/events.py @@ -80,6 +80,15 @@ def ReminderScheduled(action_name, trigger_date_time, name=None, } +# noinspection PyPep8Naming +def ReminderCancelled(name, timestamp=None): + return { + "event": "cancel", + "timestamp": timestamp, + "name": name + } + + # noinspection PyPep8Naming def ActionReverted(timestamp=None): return { From c315d592806d4f0bb6cf42fc73a13d2e93b8cd99 Mon Sep 17 00:00:00 2001 From: Simon Senkl Date: Tue, 15 Jan 2019 21:19:26 +0100 Subject: [PATCH 02/27] added latest_input_channel to tracker --- rasa_core_sdk/__init__.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/rasa_core_sdk/__init__.py b/rasa_core_sdk/__init__.py index 5607486cf..4fa1a1da3 100644 --- a/rasa_core_sdk/__init__.py +++ b/rasa_core_sdk/__init__.py @@ -76,6 +76,7 @@ def current_state(self): "latest_event_time": latest_event_time, "paused": self.is_paused(), "events": self.events, + "latest_input_channel": self.get_latest_input_channel(), "active_form": self.active_form, "latest_action_name": self.latest_action_name } @@ -108,6 +109,14 @@ def get_latest_entity_values(self, entity_type): for x in entities if x.get("entity") == entity_type) + def get_latest_input_channel(self): + # type: () -> Optional[Text] + """Get the name of the input_channel of the latest UserUttered event""" + + for e in reversed(self.events): + if e.get("event") == "user": + return e.get("input_channel") + def is_paused(self): # type: () -> bool """State whether the tracker is currently paused.""" From a6b6c85274be7a9df5432f6944f46c7b7f530501 Mon Sep 17 00:00:00 2001 From: Vladimir Vlasov Date: Thu, 7 Feb 2019 12:21:54 +0100 Subject: [PATCH 03/27] Update rasa_core_sdk/events.py Co-Authored-By: gkniesel --- rasa_core_sdk/events.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rasa_core_sdk/events.py b/rasa_core_sdk/events.py index c799476db..635ce0e7e 100644 --- a/rasa_core_sdk/events.py +++ b/rasa_core_sdk/events.py @@ -83,7 +83,7 @@ def ReminderScheduled(action_name, trigger_date_time, name=None, # noinspection PyPep8Naming def ReminderCancelled(name, timestamp=None): return { - "event": "cancel", + "event": "cancel_reminder", "timestamp": timestamp, "name": name } From cb974a6ca809babd0555392a7d1a157bf0994a0f Mon Sep 17 00:00:00 2001 From: Vladimir Vlasov Date: Thu, 7 Feb 2019 12:22:24 +0100 Subject: [PATCH 04/27] Update rasa_core_sdk/events.py Co-Authored-By: gkniesel --- rasa_core_sdk/events.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rasa_core_sdk/events.py b/rasa_core_sdk/events.py index 635ce0e7e..a4ed325a2 100644 --- a/rasa_core_sdk/events.py +++ b/rasa_core_sdk/events.py @@ -81,7 +81,7 @@ def ReminderScheduled(action_name, trigger_date_time, name=None, # noinspection PyPep8Naming -def ReminderCancelled(name, timestamp=None): +def ReminderCancelled(action_name, name=None, timestamp=None): return { "event": "cancel_reminder", "timestamp": timestamp, From c48d54e2956e6a766a500148f6daff2be3f9ed95 Mon Sep 17 00:00:00 2001 From: Vladimir Vlasov Date: Thu, 7 Feb 2019 12:22:31 +0100 Subject: [PATCH 05/27] Update rasa_core_sdk/events.py Co-Authored-By: gkniesel --- rasa_core_sdk/events.py | 1 + 1 file changed, 1 insertion(+) diff --git a/rasa_core_sdk/events.py b/rasa_core_sdk/events.py index a4ed325a2..f99508d78 100644 --- a/rasa_core_sdk/events.py +++ b/rasa_core_sdk/events.py @@ -85,6 +85,7 @@ def ReminderCancelled(action_name, name=None, timestamp=None): return { "event": "cancel_reminder", "timestamp": timestamp, + "action": action_name, "name": name } From 5cfc3f4ec2a3d829cba04c861fa88e53ad6e670e Mon Sep 17 00:00:00 2001 From: Tobias Wochinger Date: Thu, 14 Feb 2019 17:49:13 +0100 Subject: [PATCH 06/27] prepare for rasa cli --- rasa_core_sdk/__init__.py | 1 + rasa_core_sdk/cli/__init__.py | 0 rasa_core_sdk/cli/arguments.py | 32 +++++++++++++++++++ rasa_core_sdk/constants.py | 1 + rasa_core_sdk/endpoint.py | 56 ++++++++++++---------------------- tests/test_endpoint.py | 6 +--- 6 files changed, 54 insertions(+), 42 deletions(-) create mode 100644 rasa_core_sdk/cli/__init__.py create mode 100644 rasa_core_sdk/cli/arguments.py create mode 100644 rasa_core_sdk/constants.py diff --git a/rasa_core_sdk/__init__.py b/rasa_core_sdk/__init__.py index 5607486cf..d9f7aa7f7 100644 --- a/rasa_core_sdk/__init__.py +++ b/rasa_core_sdk/__init__.py @@ -10,6 +10,7 @@ from typing import Dict, Text, Any, Optional, Iterator, List import rasa_core_sdk.version +import rasa_core_sdk.cli logger = logging.getLogger(__name__) diff --git a/rasa_core_sdk/cli/__init__.py b/rasa_core_sdk/cli/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/rasa_core_sdk/cli/arguments.py b/rasa_core_sdk/cli/arguments.py new file mode 100644 index 000000000..56b75efbb --- /dev/null +++ b/rasa_core_sdk/cli/arguments.py @@ -0,0 +1,32 @@ +import argparse + +from rasa_core_sdk.constants import DEFAULT_SERVER_PORT + + +def action_arg(action): + if "/" in action: + raise argparse.ArgumentTypeError( + 'Invalid actions format. Actions file should be a python module ' + 'and passed with module notation (e.g. directory.actions).') + else: + return action + + +def add_endpoint_arguments(parser): + parser.add_argument( + '-p', '--port', + default=DEFAULT_SERVER_PORT, + type=int, + help="port to run the server at") + parser.add_argument( + '--cors', + nargs='*', + type=str, + help="enable CORS for the passed origin. " + "Use * to whitelist all origins") + parser.add_argument( + '--actions', + type=action_arg, + default=None, + help="name of action package to be loaded" + ) diff --git a/rasa_core_sdk/constants.py b/rasa_core_sdk/constants.py new file mode 100644 index 000000000..706aa6b7b --- /dev/null +++ b/rasa_core_sdk/constants.py @@ -0,0 +1 @@ +DEFAULT_SERVER_PORT = 5055 diff --git a/rasa_core_sdk/endpoint.py b/rasa_core_sdk/endpoint.py index 22e9b5d21..87eea654f 100644 --- a/rasa_core_sdk/endpoint.py +++ b/rasa_core_sdk/endpoint.py @@ -11,48 +11,23 @@ from flask import Flask, jsonify, request from flask_cors import CORS, cross_origin from gevent.pywsgi import WSGIServer + +from rasa_core_sdk.cli.arguments import add_endpoint_arguments from rasa_core_sdk.executor import ActionExecutor from rasa_core_sdk import ActionExecutionRejection import rasa_core_sdk from rasa_core_sdk import utils -DEFAULT_SERVER_PORT = 5055 - logger = logging.getLogger(__name__) -def action_arg(action): - if "/" in action: - raise argparse.ArgumentTypeError( - 'Invalid actions format. Actions file should be a python module ' - 'and passed with module notation (e.g. directory.actions).') - else: - return action - - def create_argument_parser(): """Parse all the command line arguments for the run script.""" parser = argparse.ArgumentParser( description='starts the action endpoint') - parser.add_argument( - '-p', '--port', - default=DEFAULT_SERVER_PORT, - type=int, - help="port to run the server at") - parser.add_argument( - '--cors', - nargs='*', - type=str, - help="enable CORS for the passed origin. " - "Use * to whitelist all origins") - parser.add_argument( - '--actions', - type=action_arg, - default=None, - help="name of action package to be loaded" - ) + add_endpoint_arguments(parser) utils.add_logging_option_arguments(parser) return parser @@ -135,24 +110,31 @@ def check_version_compatibility(core_version): "".format(core_version, rasa_core_sdk.__version__)) -if __name__ == '__main__': - # Running as standalone python application - arg_parser = create_argument_parser() - cmdline_args = arg_parser.parse_args() - +def run(args): logging.basicConfig(level=logging.DEBUG) logging.getLogger('matplotlib').setLevel(logging.WARN) - utils.configure_colored_logging(cmdline_args.loglevel) + utils.configure_colored_logging(args.loglevel) logger.info("Starting action endpoint server...") - edp_app = endpoint_app(cors_origins=cmdline_args.cors, - action_package_name=cmdline_args.actions) + edp_app = endpoint_app(cors_origins=args.cors, + action_package_name=args.actions) - http_server = WSGIServer(('0.0.0.0', cmdline_args.port), edp_app) + http_server = WSGIServer(('0.0.0.0', args.port), edp_app) http_server.start() logger.info("Action endpoint is up and running. on {}" "".format(http_server.address)) http_server.serve_forever() + + +if __name__ == '__main__': + # Running as standalone python application + arg_parser = create_argument_parser() + + cmdline_args = arg_parser.parse_args() + + run(cmdline_args) + + diff --git a/tests/test_endpoint.py b/tests/test_endpoint.py index 36c372346..e55af21da 100644 --- a/tests/test_endpoint.py +++ b/tests/test_endpoint.py @@ -7,16 +7,12 @@ import rasa_core_sdk.endpoint as ep -def test_endpoint(): - pass - - def test_arg_parser_actions_params_folder_style(): parser = ep.create_argument_parser() args = ['--actions', 'actions/act'] with pytest.raises(BaseException) as e: - cmdline_args = parser.parse_args(args) + parser.parse_args(args) if e is not None: assert True else: From 4c7c9fb56329edb430d3b2a22937f6e4ffd8c358 Mon Sep 17 00:00:00 2001 From: Tom Metcalfe Date: Fri, 15 Feb 2019 11:31:56 +0100 Subject: [PATCH 07/27] Wrote test, updated changelog --- CHANGELOG.rst | 2 ++ rasa_core_sdk/events.py | 4 +++- tests/test_tracker.py | 16 ++++++++++++++++ 3 files changed, 21 insertions(+), 1 deletion(-) create mode 100644 tests/test_tracker.py diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 36e86c461..3392a857b 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -14,6 +14,8 @@ This project adheres to `Semantic Versioning`_ starting with version 0.11.0. Added ----- - add optional `validate_{slot}` methods to `FormAction` +- Function to get latest input channel from the tracker with + ``tracker.get_latest_input_channel()`` Removed ------- diff --git a/rasa_core_sdk/events.py b/rasa_core_sdk/events.py index c944cf9bd..53d0a68c5 100644 --- a/rasa_core_sdk/events.py +++ b/rasa_core_sdk/events.py @@ -14,12 +14,14 @@ # noinspection PyPep8Naming def UserUttered(text, parse_data=None, - timestamp=None): + timestamp=None, + input_channel=None): return { "event": "user", "timestamp": timestamp, "text": text, "parse_data": parse_data, + "input_channel": input_channel } diff --git a/tests/test_tracker.py b/tests/test_tracker.py new file mode 100644 index 000000000..1e76e914a --- /dev/null +++ b/tests/test_tracker.py @@ -0,0 +1,16 @@ +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function +from __future__ import unicode_literals + +from rasa_core_sdk import Tracker +from rasa_core_sdk.events import ActionExecuted, UserUttered + + +def test_latest_input_channel(): + tracker = Tracker('default', {}, + {'intent': {'name': 'some_intent', 'confidence': 1.0}}, + [UserUttered("my message text", input_channel="superchat"), + ActionExecuted("action_listen")], False, None, {}, 'action_listen') + + assert tracker.get_latest_input_channel() == "superchat" From 5044dcbad8d5ee3c96ba4b126265c8c12b0c043f Mon Sep 17 00:00:00 2001 From: Tom Metcalfe Date: Fri, 15 Feb 2019 11:42:41 +0100 Subject: [PATCH 08/27] pep8 --- tests/test_tracker.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/test_tracker.py b/tests/test_tracker.py index 1e76e914a..2bd8d7428 100644 --- a/tests/test_tracker.py +++ b/tests/test_tracker.py @@ -10,7 +10,9 @@ def test_latest_input_channel(): tracker = Tracker('default', {}, {'intent': {'name': 'some_intent', 'confidence': 1.0}}, - [UserUttered("my message text", input_channel="superchat"), - ActionExecuted("action_listen")], False, None, {}, 'action_listen') + [UserUttered("my message text", + input_channel="superchat"), + ActionExecuted("action_listen")], + False, None, {}, 'action_listen') assert tracker.get_latest_input_channel() == "superchat" From 66f712dcfb614ee4466bf7614538a7bf3bde0c8f Mon Sep 17 00:00:00 2001 From: Simon Senkl Date: Fri, 15 Feb 2019 14:32:05 +0100 Subject: [PATCH 09/27] fixed pep issues --- tests/test_tracker.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/tests/test_tracker.py b/tests/test_tracker.py index 1e76e914a..4918ed5ad 100644 --- a/tests/test_tracker.py +++ b/tests/test_tracker.py @@ -10,7 +10,10 @@ def test_latest_input_channel(): tracker = Tracker('default', {}, {'intent': {'name': 'some_intent', 'confidence': 1.0}}, - [UserUttered("my message text", input_channel="superchat"), - ActionExecuted("action_listen")], False, None, {}, 'action_listen') + [ + UserUttered( + "my message text", input_channel="superchat" + ), ActionExecuted("action_listen") + ], False, None, {}, 'action_listen') assert tracker.get_latest_input_channel() == "superchat" From 5befe825b54bfcd3aad7b3fe2a28fbed2633dc84 Mon Sep 17 00:00:00 2001 From: Tom Metcalfe Date: Fri, 15 Feb 2019 15:10:20 +0100 Subject: [PATCH 10/27] Update codestyle to be more Rasalike --- tests/test_tracker.py | 8 -------- 1 file changed, 8 deletions(-) diff --git a/tests/test_tracker.py b/tests/test_tracker.py index 7e320c235..2bd8d7428 100644 --- a/tests/test_tracker.py +++ b/tests/test_tracker.py @@ -10,17 +10,9 @@ def test_latest_input_channel(): tracker = Tracker('default', {}, {'intent': {'name': 'some_intent', 'confidence': 1.0}}, -<<<<<<< HEAD [UserUttered("my message text", input_channel="superchat"), ActionExecuted("action_listen")], False, None, {}, 'action_listen') -======= - [ - UserUttered( - "my message text", input_channel="superchat" - ), ActionExecuted("action_listen") - ], False, None, {}, 'action_listen') ->>>>>>> 66f712dcfb614ee4466bf7614538a7bf3bde0c8f assert tracker.get_latest_input_channel() == "superchat" From 493ff48b3d0e7cdd652791f3b379f1f1d2326607 Mon Sep 17 00:00:00 2001 From: Patrick Da Silva Date: Fri, 1 Feb 2019 14:42:29 +0100 Subject: [PATCH 11/27] Added coloredlogs to the SDK - I assume I just had to add it where the __main__ gets called, since all the files are getting their logger from the line logger = logging.getLogger(__name__) so I just imported the utils from rasa and added the same lines that are in the rasa_core library. It worked for me. Duplicated rasa_core utils function to rasa_core_sdk utils - This is to avoid dependency of rasa_core to rasa_core_sdk --- rasa_core_sdk/endpoint.py | 5 +++++ rasa_core_sdk/utils.py | 31 +++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/rasa_core_sdk/endpoint.py b/rasa_core_sdk/endpoint.py index 506f0d6a9..e21554534 100644 --- a/rasa_core_sdk/endpoint.py +++ b/rasa_core_sdk/endpoint.py @@ -14,6 +14,8 @@ from rasa_core_sdk.executor import ActionExecutor from rasa_core_sdk import ActionExecutionRejection +from rasa_core_sdk import utils + DEFAULT_SERVER_PORT = 5055 logger = logging.getLogger(__name__) @@ -50,6 +52,7 @@ def create_argument_parser(): default=None, help="name of action package to be loaded" ) + utils.add_logging_option_arguments(parser) return parser @@ -101,6 +104,8 @@ def webhook(): logging.basicConfig(level=logging.DEBUG) logging.getLogger('matplotlib').setLevel(logging.WARN) + utils.configure_colored_logging(cmdline_args.loglevel) + logger.info("Starting action endpoint server...") edp_app = endpoint_app(cors_origins=cmdline_args.cors, action_package_name=cmdline_args.actions) diff --git a/rasa_core_sdk/utils.py b/rasa_core_sdk/utils.py index a0be3d10e..9126c7ea9 100644 --- a/rasa_core_sdk/utils.py +++ b/rasa_core_sdk/utils.py @@ -7,6 +7,8 @@ from typing import Any, List +import logging + def all_subclasses(cls): # type: (Any) -> List[Any] @@ -16,6 +18,35 @@ def all_subclasses(cls): for g in all_subclasses(s)] +def add_logging_option_arguments(parser): + """Add options to an argument parser to configure logging levels.""" + + # arguments for logging configuration + parser.add_argument( + '-v', '--verbose', + help="Be verbose. Sets logging level to INFO", + action="store_const", + dest="loglevel", + const=logging.INFO, + default=logging.INFO, + ) + parser.add_argument( + '-vv', '--debug', + help="Print lots of debugging statements. " + "Sets logging level to DEBUG", + action="store_const", + dest="loglevel", + const=logging.DEBUG, + ) + parser.add_argument( + '--quiet', + help="Be quiet! Sets logging level to WARNING", + action="store_const", + dest="loglevel", + const=logging.WARNING, + ) + + def configure_colored_logging(loglevel): import coloredlogs field_styles = coloredlogs.DEFAULT_FIELD_STYLES.copy() From bad4be1ba62598cf72523eeb4fa5d4daed3bf1d5 Mon Sep 17 00:00:00 2001 From: Simon Senkl Date: Tue, 15 Jan 2019 21:19:26 +0100 Subject: [PATCH 12/27] added latest_input_channel to tracker --- rasa_core_sdk/__init__.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/rasa_core_sdk/__init__.py b/rasa_core_sdk/__init__.py index 3e938194a..079e5ee4a 100644 --- a/rasa_core_sdk/__init__.py +++ b/rasa_core_sdk/__init__.py @@ -72,6 +72,7 @@ def current_state(self): "latest_event_time": latest_event_time, "paused": self.is_paused(), "events": self.events, + "latest_input_channel": self.get_latest_input_channel(), "active_form": self.active_form, "latest_action_name": self.latest_action_name } @@ -104,6 +105,14 @@ def get_latest_entity_values(self, entity_type): for x in entities if x.get("entity") == entity_type) + def get_latest_input_channel(self): + # type: () -> Optional[Text] + """Get the name of the input_channel of the latest UserUttered event""" + + for e in reversed(self.events): + if e.get("event") == "user": + return e.get("input_channel") + def is_paused(self): # type: () -> bool """State whether the tracker is currently paused.""" From 13e75409d4cf2f0e1d7a41ef53ed455fb9945e11 Mon Sep 17 00:00:00 2001 From: Tom Metcalfe Date: Wed, 6 Feb 2019 16:59:53 +0100 Subject: [PATCH 13/27] Add if clause --- rasa_core_sdk/forms.py | 36 ++++++++++++++++++++---------------- tests/test_forms.py | 1 + 2 files changed, 21 insertions(+), 16 deletions(-) diff --git a/rasa_core_sdk/forms.py b/rasa_core_sdk/forms.py index 39477aa1a..5958e3aa5 100644 --- a/rasa_core_sdk/forms.py +++ b/rasa_core_sdk/forms.py @@ -391,22 +391,26 @@ def run(self, dispatcher, tracker, domain): # validate user input events.extend(self._validate_if_required(dispatcher, tracker, domain)) - # create temp tracker with populated slots from `validate` method - temp_tracker = tracker.copy() - for e in events: - if e['event'] == 'slot': - temp_tracker.slots[e["name"]] = e["value"] - - next_slot_events = self.request_next_slot(dispatcher, temp_tracker, - domain) - if next_slot_events is not None: - # request next slot - events.extend(next_slot_events) - else: - # there is nothing more to request, so we can submit - events.extend(self.submit(dispatcher, temp_tracker, domain)) - # deactivate the form after submission - events.extend(self._deactivate()) + # check that the form wasn't deactivated in validation + if Form(None) not in events: + + # create temp tracker with populated slots from `validate` method + temp_tracker = tracker.copy() + for e in events: + if e['event'] == 'slot': + temp_tracker.slots[e["name"]] = e["value"] + + next_slot_events = self.request_next_slot(dispatcher, temp_tracker, + domain) + + if next_slot_events is not None: + # request next slot + events.extend(next_slot_events) + else: + # there is nothing more to request, so we can submit + events.extend(self.submit(dispatcher, temp_tracker, domain)) + # deactivate the form after submission + events.extend(self._deactivate()) return events diff --git a/tests/test_forms.py b/tests/test_forms.py index 4b2d316de..7246bac34 100644 --- a/tests/test_forms.py +++ b/tests/test_forms.py @@ -472,3 +472,4 @@ def required_slots(_tracker): # check that validation was skipped # because previous action is not action_listen assert events == [] + From 2f98bc0bb08a0d0b62cc1854c59cc64249a28ccf Mon Sep 17 00:00:00 2001 From: Tom Metcalfe Date: Wed, 6 Feb 2019 17:08:15 +0100 Subject: [PATCH 14/27] pycodestyle fix --- tests/test_forms.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/test_forms.py b/tests/test_forms.py index 7246bac34..4b2d316de 100644 --- a/tests/test_forms.py +++ b/tests/test_forms.py @@ -472,4 +472,3 @@ def required_slots(_tracker): # check that validation was skipped # because previous action is not action_listen assert events == [] - From 93ee3b23b539d5a93051fe02df2c7cd0d20d605e Mon Sep 17 00:00:00 2001 From: Tom Metcalfe Date: Wed, 6 Feb 2019 17:12:38 +0100 Subject: [PATCH 15/27] pdate changelog --- CHANGELOG.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 3586fc1d3..c4e198d3f 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -14,6 +14,8 @@ This project adheres to `Semantic Versioning`_ starting with version 0.11.0. Added ----- - add optional `validate_{slot}` methods to `FormAction` +- forms can now be deactivated during the validation function by returning + `self._deactivate()` Removed ------- From 356321dfe6460a9e0c8ea88a79a6dd31d5e89409 Mon Sep 17 00:00:00 2001 From: Tom Metcalfe Date: Thu, 7 Feb 2019 11:16:11 +0100 Subject: [PATCH 16/27] Write test for deactivation --- tests/test_forms.py | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/tests/test_forms.py b/tests/test_forms.py index 4b2d316de..6961bcf42 100644 --- a/tests/test_forms.py +++ b/tests/test_forms.py @@ -472,3 +472,32 @@ def required_slots(_tracker): # check that validation was skipped # because previous action is not action_listen assert events == [] + + +def test_early_deactivation(): + # noinspection PyAbstractClass + class CustomFormAction(FormAction): + def name(self): + return "some_form" + + @staticmethod + def required_slots(_tracker): + return ["some_slot", "some_other_slot"] + + def validate(self, dispatcher, tracker, domain): + return self._deactivate() + + form = CustomFormAction() + + tracker = Tracker('default', {'some_slot': 'some_value'}, + {'intent': 'greet'}, + [], False, None, + {'name': 'some_form', + 'validate': True, 'rejected': False}, + 'action_listen') + + events = form.run(dispatcher=None, tracker=tracker, domain=None) + + # check that form was deactivated before requesting next slot + assert events == [Form(None), SlotSet('requested_slot', None)] + assert SlotSet('requested_slot', "some_other_slot") not in events From 6a5473ccf82d2b050eb1dabe5de6ca91ac0957ca Mon Sep 17 00:00:00 2001 From: Tom Metcalfe Date: Thu, 7 Feb 2019 11:22:05 +0100 Subject: [PATCH 17/27] Remove protection from deactivate function --- CHANGELOG.rst | 3 ++- rasa_core_sdk/forms.py | 4 ++-- tests/test_forms.py | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index c4e198d3f..c25e7eef0 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -15,13 +15,14 @@ Added ----- - add optional `validate_{slot}` methods to `FormAction` - forms can now be deactivated during the validation function by returning - `self._deactivate()` + `self.deactivate()` Removed ------- Changed ------- +- `self._deactivate()` renamed to `self.deactivate()` Fixed ----- diff --git a/rasa_core_sdk/forms.py b/rasa_core_sdk/forms.py index 5958e3aa5..7c727e618 100644 --- a/rasa_core_sdk/forms.py +++ b/rasa_core_sdk/forms.py @@ -369,7 +369,7 @@ def _should_request_slot(tracker, slot_name): return tracker.get_slot(slot_name) is None - def _deactivate(self): + def deactivate(self): # type: () -> List[Dict] """Return `Form` event with `None` as name to deactivate the form and reset the requested slot""" @@ -410,7 +410,7 @@ def run(self, dispatcher, tracker, domain): # there is nothing more to request, so we can submit events.extend(self.submit(dispatcher, temp_tracker, domain)) # deactivate the form after submission - events.extend(self._deactivate()) + events.extend(self.deactivate()) return events diff --git a/tests/test_forms.py b/tests/test_forms.py index 6961bcf42..abad993cc 100644 --- a/tests/test_forms.py +++ b/tests/test_forms.py @@ -485,7 +485,7 @@ def required_slots(_tracker): return ["some_slot", "some_other_slot"] def validate(self, dispatcher, tracker, domain): - return self._deactivate() + return self.deactivate() form = CustomFormAction() From 66455ad69c6a208f6c3d1a611531abe383f30a1f Mon Sep 17 00:00:00 2001 From: Tom Metcalfe Date: Wed, 13 Feb 2019 13:50:17 +0100 Subject: [PATCH 18/27] Update CHANGELOG.rst --- CHANGELOG.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index c25e7eef0..02ef156f2 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -22,7 +22,8 @@ Removed Changed ------- -- `self._deactivate()` renamed to `self.deactivate()` +- ``self._deactivate()`` method from the ``FormAction`` class has been + renamed to ``self.deactivate()`` Fixed ----- From 35b708b8c98b3b70f9c6c55aac519dc1dcdac68e Mon Sep 17 00:00:00 2001 From: Tom Metcalfe Date: Fri, 15 Feb 2019 11:31:56 +0100 Subject: [PATCH 19/27] cherrypick commits update changelog --- CHANGELOG.rst | 2 ++ rasa_core_sdk/events.py | 4 +++- tests/test_tracker.py | 16 ++++++++++++++++ 3 files changed, 21 insertions(+), 1 deletion(-) create mode 100644 tests/test_tracker.py diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 02ef156f2..aa13ea064 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -16,6 +16,8 @@ Added - add optional `validate_{slot}` methods to `FormAction` - forms can now be deactivated during the validation function by returning `self.deactivate()` +- Function to get latest input channel from the tracker with + ``tracker.get_latest_input_channel()`` Removed ------- diff --git a/rasa_core_sdk/events.py b/rasa_core_sdk/events.py index c944cf9bd..53d0a68c5 100644 --- a/rasa_core_sdk/events.py +++ b/rasa_core_sdk/events.py @@ -14,12 +14,14 @@ # noinspection PyPep8Naming def UserUttered(text, parse_data=None, - timestamp=None): + timestamp=None, + input_channel=None): return { "event": "user", "timestamp": timestamp, "text": text, "parse_data": parse_data, + "input_channel": input_channel } diff --git a/tests/test_tracker.py b/tests/test_tracker.py new file mode 100644 index 000000000..1e76e914a --- /dev/null +++ b/tests/test_tracker.py @@ -0,0 +1,16 @@ +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function +from __future__ import unicode_literals + +from rasa_core_sdk import Tracker +from rasa_core_sdk.events import ActionExecuted, UserUttered + + +def test_latest_input_channel(): + tracker = Tracker('default', {}, + {'intent': {'name': 'some_intent', 'confidence': 1.0}}, + [UserUttered("my message text", input_channel="superchat"), + ActionExecuted("action_listen")], False, None, {}, 'action_listen') + + assert tracker.get_latest_input_channel() == "superchat" From bf48c8e60bfbd60424a1009950234d705f42b1ca Mon Sep 17 00:00:00 2001 From: Tom Metcalfe Date: Fri, 15 Feb 2019 11:42:41 +0100 Subject: [PATCH 20/27] pep8 --- tests/test_tracker.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/test_tracker.py b/tests/test_tracker.py index 1e76e914a..2bd8d7428 100644 --- a/tests/test_tracker.py +++ b/tests/test_tracker.py @@ -10,7 +10,9 @@ def test_latest_input_channel(): tracker = Tracker('default', {}, {'intent': {'name': 'some_intent', 'confidence': 1.0}}, - [UserUttered("my message text", input_channel="superchat"), - ActionExecuted("action_listen")], False, None, {}, 'action_listen') + [UserUttered("my message text", + input_channel="superchat"), + ActionExecuted("action_listen")], + False, None, {}, 'action_listen') assert tracker.get_latest_input_channel() == "superchat" From 15341dd33cd9fc5208bd513e2e1cdb25e936d270 Mon Sep 17 00:00:00 2001 From: Tom Metcalfe Date: Fri, 15 Feb 2019 15:10:20 +0100 Subject: [PATCH 21/27] prep next version --- CHANGELOG.rst | 16 +++------------- rasa_core_sdk/version.py | 2 +- 2 files changed, 4 insertions(+), 14 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index aa13ea064..d48b91ab0 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -4,12 +4,8 @@ Change Log All notable changes to this project will be documented in this file. This project adheres to `Semantic Versioning`_ starting with version 0.11.0. -.. _master-release: - -[Unreleased 0.12.0.aX] - `master`_ -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -.. note:: This version is not yet released and is under active development. +[0.12.2] - 2019-02-17 +^^^^^^^^^^^^^^^^^^^^^ Added ----- @@ -19,23 +15,17 @@ Added - Function to get latest input channel from the tracker with ``tracker.get_latest_input_channel()`` -Removed -------- - Changed ------- - ``self._deactivate()`` method from the ``FormAction`` class has been renamed to ``self.deactivate()`` -Fixed ------ - [0.12.1] - 2018-11-11 ^^^^^^^^^^^^^^^^^^^^^ Fixed ----- -- doc formatting preventing successfull rasa core travis build +- doc formatting preventing successful rasa core travis build [0.12.0] - 2018-11-11 ^^^^^^^^^^^^^^^^^^^^^ diff --git a/rasa_core_sdk/version.py b/rasa_core_sdk/version.py index be3598899..1bfcf014a 100644 --- a/rasa_core_sdk/version.py +++ b/rasa_core_sdk/version.py @@ -4,4 +4,4 @@ from __future__ import absolute_import -__version__ = '0.13.0a1' +__version__ = '0.12.2' From d57ebd7c78f46df742d7f9e66397453960adce61 Mon Sep 17 00:00:00 2001 From: Tom Metcalfe Date: Sun, 17 Feb 2019 16:57:03 +0100 Subject: [PATCH 22/27] Update changelog --- CHANGELOG.rst | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index d48b91ab0..f13733fe4 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -4,6 +4,26 @@ Change Log All notable changes to this project will be documented in this file. This project adheres to `Semantic Versioning`_ starting with version 0.11.0. +.. _master-release: + +[Unreleased 0.13.0.aX] - `master`_ +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. note:: This version is not yet released and is under active development. + +Added +----- +- add warning in case of mismatched version of rasa_core and rasa_core_sdk + +Changed +------- + +Fixed +----- + +Removed +------- + [0.12.2] - 2019-02-17 ^^^^^^^^^^^^^^^^^^^^^ From ac78e2b8fca85d0616b5edb263384f817e9d4103 Mon Sep 17 00:00:00 2001 From: Tom Metcalfe Date: Sun, 17 Feb 2019 16:58:00 +0100 Subject: [PATCH 23/27] increment version to alpha --- rasa_core_sdk/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rasa_core_sdk/version.py b/rasa_core_sdk/version.py index 1bfcf014a..be3598899 100644 --- a/rasa_core_sdk/version.py +++ b/rasa_core_sdk/version.py @@ -4,4 +4,4 @@ from __future__ import absolute_import -__version__ = '0.12.2' +__version__ = '0.13.0a1' From 82622bcd20fa94fa83ae498bd66022346709f496 Mon Sep 17 00:00:00 2001 From: Tom Metcalfe Date: Sun, 17 Feb 2019 17:01:54 +0100 Subject: [PATCH 24/27] Remove double import --- rasa_core_sdk/endpoint.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/rasa_core_sdk/endpoint.py b/rasa_core_sdk/endpoint.py index 0a0fc92d9..22e9b5d21 100644 --- a/rasa_core_sdk/endpoint.py +++ b/rasa_core_sdk/endpoint.py @@ -17,8 +17,6 @@ from rasa_core_sdk import utils -from rasa_core_sdk import utils - DEFAULT_SERVER_PORT = 5055 logger = logging.getLogger(__name__) From 20dbcda6f377545ed49cb5fed93fb84d49f96eab Mon Sep 17 00:00:00 2001 From: Tobias Wochinger Date: Fri, 22 Feb 2019 10:48:48 +0100 Subject: [PATCH 25/27] make functions accessible by API and cli --- rasa_core_sdk/endpoint.py | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/rasa_core_sdk/endpoint.py b/rasa_core_sdk/endpoint.py index 87eea654f..4beede7cc 100644 --- a/rasa_core_sdk/endpoint.py +++ b/rasa_core_sdk/endpoint.py @@ -13,6 +13,7 @@ from gevent.pywsgi import WSGIServer from rasa_core_sdk.cli.arguments import add_endpoint_arguments +from rasa_core_sdk.constants import DEFAULT_SERVER_PORT from rasa_core_sdk.executor import ActionExecutor from rasa_core_sdk import ActionExecutionRejection import rasa_core_sdk @@ -110,17 +111,12 @@ def check_version_compatibility(core_version): "".format(core_version, rasa_core_sdk.__version__)) -def run(args): - logging.basicConfig(level=logging.DEBUG) - logging.getLogger('matplotlib').setLevel(logging.WARN) - - utils.configure_colored_logging(args.loglevel) - +def run(actions, port=DEFAULT_SERVER_PORT, cors='*'): logger.info("Starting action endpoint server...") - edp_app = endpoint_app(cors_origins=args.cors, - action_package_name=args.actions) + edp_app = endpoint_app(cors_origins=cors, + action_package_name=actions) - http_server = WSGIServer(('0.0.0.0', args.port), edp_app) + http_server = WSGIServer(('0.0.0.0', port), edp_app) http_server.start() logger.info("Action endpoint is up and running. on {}" @@ -129,12 +125,18 @@ def run(args): http_server.serve_forever() +def main(args): + logging.basicConfig(level=logging.DEBUG) + logging.getLogger('matplotlib').setLevel(logging.WARN) + + utils.configure_colored_logging(args.loglevel) + + run(args.actions, args.port, args.cors,) + + if __name__ == '__main__': # Running as standalone python application arg_parser = create_argument_parser() - cmdline_args = arg_parser.parse_args() - run(cmdline_args) - - + main(cmdline_args) From 2fecd646761d24000d5a1576d5de68aab12e1eca Mon Sep 17 00:00:00 2001 From: Tobias Wochinger Date: Fri, 22 Feb 2019 10:52:03 +0100 Subject: [PATCH 26/27] update changelog --- CHANGELOG.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index d6728b421..978477539 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -24,6 +24,7 @@ Changed ------- - ``self._deactivate()`` method from the ``FormAction`` class has been renamed to ``self.deactivate()`` +- changed endpoint function so that it is now accessible with Python as well Fixed ----- From 7057920af00c09270665420583d3dc8b2d58e04b Mon Sep 17 00:00:00 2001 From: Tom Bocklisch Date: Mon, 25 Feb 2019 09:08:32 +0100 Subject: [PATCH 27/27] Update rasa_core_sdk/endpoint.py Co-Authored-By: wochinge --- rasa_core_sdk/endpoint.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rasa_core_sdk/endpoint.py b/rasa_core_sdk/endpoint.py index 4beede7cc..efd008773 100644 --- a/rasa_core_sdk/endpoint.py +++ b/rasa_core_sdk/endpoint.py @@ -131,7 +131,7 @@ def main(args): utils.configure_colored_logging(args.loglevel) - run(args.actions, args.port, args.cors,) + run(args.actions, args.port, args.cors) if __name__ == '__main__':