Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixing Example and Adding Keyword Arguments as option for parameters #37

Merged
merged 12 commits into from
Aug 28, 2020
5 changes: 4 additions & 1 deletion docs/usage.rst
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ Try the example app `time_app.py`_ with the ``--help`` flag to see what settings

.. _`time_app.py`: https://github.com/rhasspy/rhasspy-hermes-app/blob/master/examples/time_app.py

You can pass all the settings as keyword arguments inside the constructor aswell:
:meth:`HermesApp("ExampleApp", host = "192.168.178.123", port = 12183)`

*******
Asyncio
*******
Expand Down Expand Up @@ -65,7 +68,7 @@ If the API of this library changes, your app possibly stops working when it upda

.. code-block::

rhasspy-hermes-app==0.2.0
rhasspy-hermes-app==1.0.0

This way your app keeps working when the Rhasspy Hermes App adds incompatible changes in a new version.

Expand Down
2 changes: 1 addition & 1 deletion examples/async_advice_app.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
None of the authors, contributors, administrators, or anyone else connected with Rhasspy_Hermes_App,
in any way whatsoever, can be responsible for your use of the api endpoint.
"""
URL = 'https://api.advicslip.com/advice'
URL = 'https://api.adviceslip.com/advice'

@app.on_intent("GetAdvice")
async def get_advice(intent: NluIntent):
Expand Down
18 changes: 16 additions & 2 deletions rhasspyhermes_app/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import asyncio
import logging
import re
from copy import deepcopy
from dataclasses import dataclass
from typing import Awaitable, Callable, Dict, List, Optional, Union

Expand Down Expand Up @@ -85,6 +86,7 @@ def __init__(
name: str,
parser: Optional[argparse.ArgumentParser] = None,
mqtt_client: Optional[mqtt.Client] = None,
**kwargs
):
"""Initialize the Rhasspy Hermes app.

Expand All @@ -103,8 +105,18 @@ def __init__(
# Add default arguments
hermes_cli.add_hermes_args(parser)

# Parse command-line arguments
self.args = parser.parse_args()
# overwrite argument defaults inside parser with argparse.SUPPRESS
# so arguments that are not provided get ignored
suppress_parser = deepcopy(parser)
for action in suppress_parser._actions:
action.default = argparse.SUPPRESS
koenvervloesem marked this conversation as resolved.
Show resolved Hide resolved

supplied_args = vars(suppress_parser.parse_args())
default_args = vars(parser.parse_args([]))

# Command-line arguments take precedence over the arguments of the HermesApp.__init__
args = {**default_args, **kwargs, **supplied_args}
self.args = argparse.Namespace(**args)

# Set up logging
hermes_cli.setup_logging(self.args)
Expand All @@ -115,6 +127,7 @@ def __init__(
mqtt_client = mqtt.Client()

# Initialize HermesClient
# pylint: disable=no-member
super().__init__(name, mqtt_client, site_ids=self.args.site_id)

self._callbacks_hotword: List[Callable[[HotwordDetected], Awaitable[None]]] = []
Expand Down Expand Up @@ -593,6 +606,7 @@ def run(self):
self._subscribe_callbacks()

# Try to connect
# pylint: disable=no-member
_LOGGER.debug("Connecting to %s:%s", self.args.host, self.args.port)
hermes_cli.connect(self.mqtt_client, self.args)
self.mqtt_client.loop_start()
Expand Down
136 changes: 136 additions & 0 deletions tests/test_arguments.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
"""Tests for HermesApp arguments."""
import argparse
import pytest
import sys

from rhasspyhermes_app import HermesApp


def test_default_arguments(mocker):
"""Test whether default arguments are set up correctly in a HermesApp object."""
app = HermesApp("Test default arguments", mqtt_client=mocker.MagicMock())

assert app.args.host == "localhost"
assert app.args.port == 1883
assert app.args.tls == False
assert app.args.username is None
assert app.args.password is None


def test_arguments_from_cli(mocker):
"""Test whether arguments from the command line are set up correctly in a HermesApp object."""
mocker.patch(
"sys.argv",
[
"rhasspy-hermes-app-test",
"--host",
"rhasspy.home",
"--port",
"8883",
"--tls",
"--username",
"rhasspy-hermes-app",
"--password",
"test",
],
)
app = HermesApp("Test arguments in init", mqtt_client=mocker.MagicMock())

assert app.args.host == "rhasspy.home"
assert app.args.port == 8883
assert app.args.tls == True
assert app.args.username == "rhasspy-hermes-app"
assert app.args.password == "test"


def test_arguments_in_init(mocker):
"""Test whether arguments are set up correctly while initializing a HermesApp object."""
app = HermesApp(
"Test arguments in init",
mqtt_client=mocker.MagicMock(),
host="rhasspy.home",
port=8883,
tls=True,
username="rhasspy-hermes-app",
password="test",
)

assert app.args.host == "rhasspy.home"
assert app.args.port == 8883
assert app.args.tls == True
assert app.args.username == "rhasspy-hermes-app"
assert app.args.password == "test"


def test_if_cli_arguments_overwrite_init_arguments(mocker):
"""Test whether arguments from the command line overwrite arguments to a HermesApp object."""
mocker.patch(
"sys.argv",
[
"rhasspy-hermes-app-test",
"--host",
"rhasspy.home",
"--port",
"1883",
"--username",
"rhasspy-hermes-app",
"--password",
"test",
],
)
app = HermesApp(
"Test arguments in init",
mqtt_client=mocker.MagicMock(),
host="rhasspy.local",
port=8883,
username="rhasspy-hermes-app-test",
password="covfefe",
)

assert app.args.host == "rhasspy.home"
assert app.args.port == 1883
assert app.args.username == "rhasspy-hermes-app"
assert app.args.password == "test"


def test_if_cli_arguments_overwrite_init_arguments_with_argument_parser(mocker):
"""Test whether arguments from the command line overwrite arguments to a HermesApp object
if the user supplies their own ArgumentParser object."""
mocker.patch(
"sys.argv",
[
"rhasspy-hermes-app-test",
"--host",
"rhasspy.home",
"--port",
"1883",
"--username",
"rhasspy-hermes-app",
"--password",
"test",
"--test-argument",
"foobar",
"--test-flag",
],
)
parser = argparse.ArgumentParser(prog="rhasspy-hermes-app-test")
parser.add_argument("--test-argument", default="foo")
parser.add_argument("--test-flag", action="store_true")

app = HermesApp(
"Test arguments in init",
parser=parser,
mqtt_client=mocker.MagicMock(),
host="rhasspy.local",
port=8883,
username="rhasspy-hermes-app-test",
password="covfefe",
test_argument="bar",
)

assert app.args.host == "rhasspy.home"
assert app.args.port == 1883
assert app.args.username == "rhasspy-hermes-app"
assert app.args.password == "test"
assert app.args.test_argument == "foobar"
assert app.args.test_flag == True