Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
think it's OK - but maybe we should think about persisting domains in saved models as yaml as well then rather than converting to json
tests/test_domain.py
Outdated
utter_greet: | ||
- text: hey there!""" | ||
domain = TemplateDomain.load_from_yaml(test_yaml) | ||
assert test_yaml in domain.to_yaml() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why 'in' ? would x.strip() == y.strip()
also work?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yep, that works fine!
rasa_core/utils.py
Outdated
@@ -17,6 +17,10 @@ | |||
from builtins import input, range, str | |||
from numpy import all, array | |||
from typing import Text, Any, List, Optional, Tuple, Dict, Set | |||
try: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is this a py2 / py3 thing? can we use six
instead?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it is, use six how?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
saw your other comment, ignore me!
rasa_core/server.py
Outdated
@requires_auth(auth_token) | ||
@ensure_loaded_agent(agent) | ||
def get_domain_yaml(): | ||
"""Use a list of events to set a conversations tracker to a state.""" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
description needs updated
rasa_core/domain.py
Outdated
action_factory = data.get("action_factory", None) | ||
slots = cls.collect_slots(data.get("slots", {})) | ||
additional_arguments = data.get("config", {}) | ||
return TemplateDomain( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why do we have both cls
and TemplateDomain
in this method? surely they are the same? if we are allowing for subclassing then probably stick with cls
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oh yes, good call
rasa_core/utils.py
Outdated
@@ -319,6 +323,21 @@ def read_yaml_file(filename): | |||
|
|||
return yaml_parser.load(read_file(filename)) | |||
|
|||
def read_yaml_string(string): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can we then rewrite read_yaml_file
to just be read_yaml_string(read_file(filename))
?
rasa_core/utils.py
Outdated
@@ -319,6 +323,21 @@ def read_yaml_file(filename): | |||
|
|||
return yaml_parser.load(read_file(filename)) | |||
|
|||
def read_yaml_string(string): | |||
|
|||
if six.PY2: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
here an example of using six
rasa_core/domain.py
Outdated
@@ -416,7 +416,27 @@ def load(cls, filename, action_factory=None): | |||
) | |||
|
|||
@classmethod | |||
def validate_domain_yaml(cls, filename): | |||
def load_from_yaml(cls, yaml, action_factory=None): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can load
use load_from_yaml
once it read the yaml from the file as well? want to avoid the duplication
rasa_core/utils.py
Outdated
def dump_obj_as_yaml_to_string(obj): | ||
"""Writes data (python dict) to a yaml string.""" | ||
|
||
if six.PY2: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
these two functions should share the code, eg:
def _dump_yaml(obj, output):
#...
yaml_writer.dump(obj, output)
#...
def dump_obj_as_yaml_to_file(filename, obj):
with io.open(filename, 'w', encoding="utf-8") as yaml_file:
_dump_yaml(obj, yaml_file)
def dump_obj_as_yaml(obj):
str_io = StringIO()
_dump_yaml(obj, str_io)
return str_io.getvalue()
rasa_core/server.py
Outdated
@ensure_loaded_agent(agent) | ||
def get_domain_yaml(): | ||
"""Get current domain in yaml format.""" | ||
domain_yaml = agent().domain.to_yaml() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why are we sending the domain as yaml instead of json?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I mean its the way that the domain is stored in the model folder so why not?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is a REST api, so usually the responses are in json format. I mean I don't have a strong opinion on this, but if yaml is used, content negotiation should be used: e.g.
accepts = request.headers.get("Accept", default="application/json")
if accepts.endswith("json"):
domain = agent().domain.as_dict()
return jsonify(domain)
elif accepts.endswith("yml"):
domain = agent().domain.as_yaml()
return Response(domain_yaml, status=200, content_type="application/x-yml")
else:
return Response("""Invalid accept header. Domain can be provided as json ("Accept: application/json") or yml ("Accept: application/x-yml"). Make sure you've set the appropriate Accept header.""", status=406)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok cool!
rasa_core/domain.py
Outdated
) | ||
|
||
@classmethod | ||
def validate_domain_yaml(cls, filename): | ||
def validate_domain_yaml(cls, input, string_input=False): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
input
needs to be renamed (shadows build in function)
do we need string_input
? I think it is always True
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it wasnt in tests but i changed tests :)
rasa_core/domain.py
Outdated
@@ -496,7 +504,7 @@ def instantiate_actions(factory_name, action_classes, action_names, | |||
def _slot_definitions(self): | |||
return {slot.name: slot.persistence_info() for slot in self.slots} | |||
|
|||
def persist(self, filename): | |||
def _make_domain_data(self): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
def as_dict(self)
(for consistency across classes)
rasa_core/domain.py
Outdated
utils.dump_obj_as_yaml_to_file(filename, domain_data) | ||
|
||
def to_yaml(self): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
as_yaml
for consistency
rasa_core/server.py
Outdated
@ensure_loaded_agent(agent) | ||
def get_domain_yaml(): | ||
"""Get current domain in yaml format.""" | ||
domain_yaml = agent().domain.to_yaml() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is a REST api, so usually the responses are in json format. I mean I don't have a strong opinion on this, but if yaml is used, content negotiation should be used: e.g.
accepts = request.headers.get("Accept", default="application/json")
if accepts.endswith("json"):
domain = agent().domain.as_dict()
return jsonify(domain)
elif accepts.endswith("yml"):
domain = agent().domain.as_yaml()
return Response(domain_yaml, status=200, content_type="application/x-yml")
else:
return Response("""Invalid accept header. Domain can be provided as json ("Accept: application/json") or yml ("Accept: application/x-yml"). Make sure you've set the appropriate Accept header.""", status=406)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
small change left that needs to be done. also, please make sure to add your change to CHANGELOG.rst
rasa_core/domain.py
Outdated
) | ||
|
||
@classmethod | ||
def validate_domain_yaml(cls, filename): | ||
def validate_domain_yaml(cls, input): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
still needs to be renamed to something that is not input
(shadows built in)
Proposed changes:
Status (please check what you already did):