Skip to content

Commit

Permalink
Docstring and mypy fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
koenvervloesem committed Jun 14, 2020
1 parent 0f8d258 commit 47d7bcc
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 35 deletions.
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.0.1
0.1.0
88 changes: 57 additions & 31 deletions rhasspyhermes_app/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,16 +69,11 @@ def __init__(
] = []

self._callbacks_intent: typing.Dict[
str,
typing.List[
typing.Callable[[NluIntent], typing.Union[ContinueSession, EndSession]]
],
str, typing.List[typing.Callable[[NluIntent], None]],
] = {}

self._callbacks_intent_not_recognized: typing.List[
typing.Callable[
[NluIntentNotRecognized], typing.Union[ContinueSession, EndSession]
]
typing.Callable[[NluIntentNotRecognized], None]
] = []

self._callbacks_topic: typing.Dict[
Expand All @@ -91,10 +86,10 @@ def __init__(

self._additional_topic: typing.List[str] = []

def _subscribe_callbacks(self):
def _subscribe_callbacks(self) -> None:
# Remove duplicate intent names
intent_names = list(set(self._callbacks_intent.keys()))
topics = [
intent_names: typing.List[str] = list(set(self._callbacks_intent.keys()))
topics: typing.List[str] = [
NluIntent.topic(intent_name=intent_name) for intent_name in intent_names
]

Expand All @@ -104,7 +99,7 @@ def _subscribe_callbacks(self):
if self._callbacks_intent_not_recognized:
topics.append(NluIntentNotRecognized.topic())

topic_names = list(set(self._callbacks_topic.keys()))
topic_names: typing.List[str] = list(set(self._callbacks_topic.keys()))
topics.extend(topic_names)
topics.extend(self._additional_topic)

Expand Down Expand Up @@ -182,35 +177,47 @@ async def on_raw_message(self, topic: str, payload: bytes):
except Exception:
_LOGGER.exception("on_raw_message")

def on_hotword(self, function):
def on_hotword(
self, function: typing.Callable[[HotwordDetected], None]
) -> typing.Callable[[HotwordDetected], None]:
"""Apply this decorator to a function that you want to act on a detected hotword.
The function needs to have the following signature:
function(hotword: :class:`rhasspyhermes.wake.HotwordDetected`)
The decorated function has a :class:`rhasspyhermes.wake.HotwordDetected` object as an argument
and doesn't have a return value.
Example:
.. code-block:: python
@app.on_hotword
def wake(hotword):
def wake(hotword: HotwordDetected):
print(f"Hotword {hotword.model_id} detected on site {hotword.site_id}")
If a hotword has been detected, the ``wake`` function is called with the ``hotword`` argument.
This object holds information about the detected hotword.
"""

self._callbacks_hotword.append(function)

return function

def on_intent(self, *intent_names: str):
def on_intent(
self, *intent_names: str
) -> typing.Callable[
[typing.Callable[[NluIntent], typing.Union["ContinueSession", "EndSession"]]],
typing.Callable[[NluIntent], None],
]:
"""Apply this decorator to a function that you want to act on a received intent.
Arguments:
intent_names: Names of the intents you want the function to act on.
The function needs to have the following signature:
The decorated function has a :class:`rhasspyhermes.nlu.NluIntent` object as an argument
and needs to return a :class:`ContinueSession` or :class:`EndSession` object.
function(intent: :class:`rhasspyhermes.nlu.NluIntent`)
If the function returns a :class:`ContinueSession` object, the intent's session is continued after
saying the supplied text. If the function returns a a :class:`EndSession` object, the intent's session
is ended after saying the supplied text, or immediately when no text is supplied.
Example:
Expand All @@ -219,10 +226,17 @@ def on_intent(self, *intent_names: str):
@app.on_intent("GetTime")
def get_time(intent: NluIntent):
return EndSession("It's too late.")
If the intent with name GetTime has been detected, the ``get_time`` function is called
with the ``intent`` argument. This object holds information about the detected intent.
"""

def wrapper(function):
def wrapped(intent: NluIntent):
def wrapper(
function: typing.Callable[
[NluIntent], typing.Union[ContinueSession, EndSession]
]
) -> typing.Callable[[NluIntent], None]:
def wrapped(intent: NluIntent) -> None:
message = function(intent)
if isinstance(message, EndSession):
if intent.session_id is not None:
Expand Down Expand Up @@ -265,24 +279,37 @@ def wrapped(intent: NluIntent):

return wrapper

def on_intent_not_recognized(self, function):
def on_intent_not_recognized(
self,
function: typing.Callable[
[NluIntentNotRecognized],
typing.Union["ContinueSession", "EndSession", None],
],
) -> typing.Callable[[NluIntentNotRecognized], None]:
"""Apply this decorator to a function that you want to act when the NLU system
hasn't recognized an intent.
The function needs to have the following signature:
The decorated function has a :class:`rhasspyhermes.nlu.NluIntentNotRecognized` object as an argument
and can return a :class:`ContinueSession` or :class:`EndSession` object or have no return value.
function(intent_not_recognized: :class:`rhasspyhermes.nlu.NluIntentNotRecognized`)
If the function returns a :class:`ContinueSession` object, the current session is continued after
saying the supplied text. If the function returns a a :class:`EndSession` object, the current session
is ended after saying the supplied text, or immediately when no text is supplied. If the function doesn't
have a return value, nothing is changed to the session.
Example:
.. code-block:: python
@app.on_intent_not_recognized
def notunderstood(intent_not_recognized):
def not_understood(intent_not_recognized: NluIntentNotRecognized):
print(f"Didn't understand \"{intent_not_recognized.input}\" on site {intent_not_recognized.site_id}")
If an intent hasn't been recognized, the ``not_understood`` function is called
with the ``intent_not_recognized`` argument. This object holds information about the not recognized intent.
"""

def wrapped(inr: NluIntentNotRecognized):
def wrapped(inr: NluIntentNotRecognized) -> None:
message = function(inr)
if isinstance(message, EndSession):
if inr.session_id is not None:
Expand Down Expand Up @@ -325,9 +352,8 @@ def on_topic(self, *topic_names: str):
Arguments:
topic_names: The MQTT topics you want the function to act on.
The function needs to have the following signature:
function(data: :class:`TopicData`, payload: bytes)
The decorated function has a :class:`TopicData` and a :class:`bytes` object as its arguments.
The former holds data about the topic and the latter about the payload of the MQTT message.
Example:
Expand All @@ -338,8 +364,8 @@ def test_topic1(data: TopicData, payload: bytes):
_LOGGER.debug("topic: %s, site_id: %s", data.topic, data.data.get("site_id"))
.. note:: The topic names can contain MQTT wildcards (`+` and `#`) or templates (`{foobar}`).
In the latter case the value of the named template is available in the decorated function
as part of the ``data`` argument.
In the latter case, the value of the named template is available in the decorated function
as part of the :class:`TopicData` argument.
"""

def wrapper(function):
Expand Down
9 changes: 6 additions & 3 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import setuptools

this_dir = os.path.abspath(os.path.dirname(__file__))
with open(os.path.join(this_dir, "README.md"), "r") as readme_file:
with open(os.path.join(this_dir, "README.rst"), "r") as readme_file:
long_description = readme_file.read()

with open(os.path.join(this_dir, "requirements.txt"), "r") as requirements_file:
Expand All @@ -23,12 +23,15 @@
package_data={"rhasspyhermes_app": ["py.typed"]},
install_requires=requirements,
classifiers=[
"Development Status :: 3 - Alpha",
"Intended Audience :: Developers",
"License :: OSI Approved :: MIT License",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.7",
"Programming Language :: Python :: 3.8",
"License :: OSI Approved :: MIT License",
"Topic :: Software Development :: Libraries",
],
long_description=long_description,
long_description_content_type="text/markdown",
long_description_content_type="text/x-rst",
python_requires=">=3.7",
)

0 comments on commit 47d7bcc

Please sign in to comment.