From 197df156052b1c12e10ddfa443f2b47e26d660ef Mon Sep 17 00:00:00 2001 From: Jacob Logas Date: Thu, 20 Feb 2020 18:43:55 -0500 Subject: [PATCH 1/7] add intent listener --- rhasspyclient/__init__.py | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/rhasspyclient/__init__.py b/rhasspyclient/__init__.py index 8e11856..5ed0171 100644 --- a/rhasspyclient/__init__.py +++ b/rhasspyclient/__init__.py @@ -25,10 +25,9 @@ class RhasspyClient: """Client object for remote Rhasspy server.""" - def __init__(self, api_url: str, session: aiohttp.ClientSession): - self.api_url = api_url - if not self.api_url.endswith("/"): - self.api_url += "/" + def __init__(self, HOST: str, PORT: str, session: aiohttp.ClientSession): + self.api_url = "http://{}:{}/api/".format(HOST, PORT) + self.events_url = "ws://{}:{}/api/events/".format(HOST, PORT) # Construct URLs for end-points self.sentences_url = urljoin(self.api_url, "sentences") @@ -44,6 +43,10 @@ def __init__(self, api_url: str, session: aiohttp.ClientSession): self.lookup_url = urljoin(self.api_url, "lookup") self.version_url = urljoin(self.api_url, "version") + self.intent_listen_url = urljoin(self.events_url, 'intent') + self.wake_listen_url = urljoin(self.events_url, 'wake') + self.speech_listen_url = urljoin(self.events_url, 'text') + self.session = session assert self.session is not None, "ClientSession is required" @@ -296,3 +299,15 @@ async def stream_to_text(self, raw_stream: aiohttp.StreamReader) -> str: ) as response: response.raise_for_status() return await response.text() + + + # ------------------------------------------------------------------------- + async def listen_for_intent(self, handler, **handlerargs) -> None: + """Given a handler function at startup handles the intents as they arrive""" + async with self.session.ws_connect(self.intent_listen_url) as ws: + async for msg in ws: + if msg.type in (aiohttp.WSMsgType.CLOSED, + aiohttp.WSMsgType.ERROR): + break + + handler(msg, handlerargs) \ No newline at end of file From d9d08d12646dde2227b079f3d77b235324b636a3 Mon Sep 17 00:00:00 2001 From: Jacob Logas Date: Thu, 20 Feb 2020 18:46:43 -0500 Subject: [PATCH 2/7] Update for security --- rhasspyclient/__init__.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/rhasspyclient/__init__.py b/rhasspyclient/__init__.py index 5ed0171..646355f 100644 --- a/rhasspyclient/__init__.py +++ b/rhasspyclient/__init__.py @@ -25,9 +25,13 @@ class RhasspyClient: """Client object for remote Rhasspy server.""" - def __init__(self, HOST: str, PORT: str, session: aiohttp.ClientSession): - self.api_url = "http://{}:{}/api/".format(HOST, PORT) - self.events_url = "ws://{}:{}/api/events/".format(HOST, PORT) + def __init__(self, HOST: str, PORT: str, session: aiohttp.ClientSession, secure: bool = False): + if secure: + self.api_url = "https://{}:{}/api/".format(HOST, PORT) + self.events_url = "wss://{}:{}/api/events/".format(HOST, PORT) + else: + self.api_url = "http://{}:{}/api/".format(HOST, PORT) + self.events_url = "ws://{}:{}/api/events/".format(HOST, PORT) # Construct URLs for end-points self.sentences_url = urljoin(self.api_url, "sentences") From 0aefaf4c81f7e46052edd46b64773f7e6629aa87 Mon Sep 17 00:00:00 2001 From: Jacob Logas Date: Fri, 21 Feb 2020 20:47:02 -0500 Subject: [PATCH 3/7] Add listener api endpoints --- rhasspyclient/__init__.py | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/rhasspyclient/__init__.py b/rhasspyclient/__init__.py index 646355f..e3b1f42 100644 --- a/rhasspyclient/__init__.py +++ b/rhasspyclient/__init__.py @@ -314,4 +314,24 @@ async def listen_for_intent(self, handler, **handlerargs) -> None: aiohttp.WSMsgType.ERROR): break + handler(msg, handlerargs) + + async def listen_for_speech(self, handler, **handlerargs) -> None: + """Given a handler function at startup handles the transcribed text as it arrives""" + async with self.session.ws_connect(self.speech_listen_url) as ws: + async for msg in ws: + if msg.type in (aiohttp.WSMsgType.CLOSED, + aiohttp.WSMsgType.ERROR): + break + + handler(msg, handlerargs) + + async def listen_for_wake(self, handler, **handlerargs) -> None: + """Given a handler function at startup, handles when a wakeword is heard""" + async with self.session.ws_connect(self.wake_listen_url) as ws: + async for msg in ws: + if msg.type in (aiohttp.WSMsgType.CLOSED, + aiohttp.WSMsgType.ERROR): + break + handler(msg, handlerargs) \ No newline at end of file From c47aff2baf558fdb913bf209042f4f1dc2681c6b Mon Sep 17 00:00:00 2001 From: Jacob Logas Date: Fri, 21 Feb 2020 21:04:02 -0500 Subject: [PATCH 4/7] Working websocket interface --- rhasspyclient/__init__.py | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/rhasspyclient/__init__.py b/rhasspyclient/__init__.py index 646355f..82bbf9f 100644 --- a/rhasspyclient/__init__.py +++ b/rhasspyclient/__init__.py @@ -314,4 +314,33 @@ async def listen_for_intent(self, handler, **handlerargs) -> None: aiohttp.WSMsgType.ERROR): break - handler(msg, handlerargs) \ No newline at end of file + if (handlerargs): + handler(msg, handlerargs) + else: + handler(msg) + + async def listen_for_speech(self, handler, **handlerargs) -> None: + """Given a handler function at startup handles the transcribed text as it arrives""" + async with self.session.ws_connect(self.speech_listen_url) as ws: + async for msg in ws: + if msg.type in (aiohttp.WSMsgType.CLOSED, + aiohttp.WSMsgType.ERROR): + break + + if (handlerargs): + handler(msg, handlerargs) + else: + handler(msg) + + async def listen_for_wake(self, handler, **handlerargs) -> None: + """Given a handler function at startup, handles when a wakeword is heard""" + async with self.session.ws_connect(self.wake_listen_url) as ws: + async for msg in ws: + if msg.type in (aiohttp.WSMsgType.CLOSED, + aiohttp.WSMsgType.ERROR): + break + + if (handlerargs): + handler(msg, handlerargs) + else: + handler(msg) From e0e75b7c4e613cc4687d8c42b89946f5654e6006 Mon Sep 17 00:00:00 2001 From: Jacob Logas Date: Fri, 21 Feb 2020 21:05:37 -0500 Subject: [PATCH 5/7] remove testing script --- test.py | 18 ------------------ 1 file changed, 18 deletions(-) delete mode 100644 test.py diff --git a/test.py b/test.py deleted file mode 100644 index 3aa05ca..0000000 --- a/test.py +++ /dev/null @@ -1,18 +0,0 @@ -import asyncio - -import aiohttp -from rhasspyclient import RhasspyClient - -def prob(msg): - print(msg) - -async def main(): - async with aiohttp.ClientSession() as session: - client = RhasspyClient('localhost', '8000', session) - result = await client.text_to_intent("what time is it") - print(result) - await client.listen_for_intent(prob) - - -loop = asyncio.get_event_loop() -loop.run_until_complete(main()) From fa6e53ad80902326f5cf285227cd3430485d48f8 Mon Sep 17 00:00:00 2001 From: Jacob Logas Date: Sun, 18 Oct 2020 11:49:13 -0400 Subject: [PATCH 6/7] Fix build errors --- rhasspyclient/__init__.py | 28 +++++++++++++--------------- rhasspyclient/__main__.py | 11 +++++++---- 2 files changed, 20 insertions(+), 19 deletions(-) diff --git a/rhasspyclient/__init__.py b/rhasspyclient/__init__.py index 82bbf9f..6ecd09b 100644 --- a/rhasspyclient/__init__.py +++ b/rhasspyclient/__init__.py @@ -25,7 +25,9 @@ class RhasspyClient: """Client object for remote Rhasspy server.""" - def __init__(self, HOST: str, PORT: str, session: aiohttp.ClientSession, secure: bool = False): + def __init__( + self, HOST: str, PORT: str, session: aiohttp.ClientSession, secure: bool = False + ): if secure: self.api_url = "https://{}:{}/api/".format(HOST, PORT) self.events_url = "wss://{}:{}/api/events/".format(HOST, PORT) @@ -47,9 +49,9 @@ def __init__(self, HOST: str, PORT: str, session: aiohttp.ClientSession, secure: self.lookup_url = urljoin(self.api_url, "lookup") self.version_url = urljoin(self.api_url, "version") - self.intent_listen_url = urljoin(self.events_url, 'intent') - self.wake_listen_url = urljoin(self.events_url, 'wake') - self.speech_listen_url = urljoin(self.events_url, 'text') + self.intent_listen_url = urljoin(self.events_url, "intent") + self.wake_listen_url = urljoin(self.events_url, "wake") + self.speech_listen_url = urljoin(self.events_url, "text") self.session = session assert self.session is not None, "ClientSession is required" @@ -304,17 +306,15 @@ async def stream_to_text(self, raw_stream: aiohttp.StreamReader) -> str: response.raise_for_status() return await response.text() - # ------------------------------------------------------------------------- async def listen_for_intent(self, handler, **handlerargs) -> None: """Given a handler function at startup handles the intents as they arrive""" async with self.session.ws_connect(self.intent_listen_url) as ws: async for msg in ws: - if msg.type in (aiohttp.WSMsgType.CLOSED, - aiohttp.WSMsgType.ERROR): + if msg.type in (aiohttp.WSMsgType.CLOSED, aiohttp.WSMsgType.ERROR): break - - if (handlerargs): + + if handlerargs: handler(msg, handlerargs) else: handler(msg) @@ -323,11 +323,10 @@ async def listen_for_speech(self, handler, **handlerargs) -> None: """Given a handler function at startup handles the transcribed text as it arrives""" async with self.session.ws_connect(self.speech_listen_url) as ws: async for msg in ws: - if msg.type in (aiohttp.WSMsgType.CLOSED, - aiohttp.WSMsgType.ERROR): + if msg.type in (aiohttp.WSMsgType.CLOSED, aiohttp.WSMsgType.ERROR): break - if (handlerargs): + if handlerargs: handler(msg, handlerargs) else: handler(msg) @@ -336,11 +335,10 @@ async def listen_for_wake(self, handler, **handlerargs) -> None: """Given a handler function at startup, handles when a wakeword is heard""" async with self.session.ws_connect(self.wake_listen_url) as ws: async for msg in ws: - if msg.type in (aiohttp.WSMsgType.CLOSED, - aiohttp.WSMsgType.ERROR): + if msg.type in (aiohttp.WSMsgType.CLOSED, aiohttp.WSMsgType.ERROR): break - if (handlerargs): + if handlerargs: handler(msg, handlerargs) else: handler(msg) diff --git a/rhasspyclient/__main__.py b/rhasspyclient/__main__.py index 88a4e12..146e129 100644 --- a/rhasspyclient/__main__.py +++ b/rhasspyclient/__main__.py @@ -29,9 +29,12 @@ async def main(): "--debug", action="store_true", help="Print DEBUG messages to console" ) parser.add_argument( - "--api-url", - default="http://localhost:12101/api", - help="URL of Rhasspy server (with /api)", + "--api-host", + default="localhost", + help="Host where the Rhasspy API can be found", + ) + parser.add_argument( + "--api-port", default="12101", help="Port where Rhasspy is exposed" ) sub_parsers = parser.add_subparsers() @@ -105,7 +108,7 @@ async def main(): # Begin client session async with aiohttp.ClientSession() as session: - client = RhasspyClient(args.api_url, session) + client = RhasspyClient(args.api_host, args.api_port, session) # Call sub-commmand await args.func(args, client) From 6e3fa90ff2fbadda6323116443ebf838432c4851 Mon Sep 17 00:00:00 2001 From: Jacob Logas Date: Sun, 18 Oct 2020 12:34:59 -0400 Subject: [PATCH 7/7] Update variables to be lowercase --- rhasspyclient/__init__.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/rhasspyclient/__init__.py b/rhasspyclient/__init__.py index 6ecd09b..1d96320 100644 --- a/rhasspyclient/__init__.py +++ b/rhasspyclient/__init__.py @@ -26,14 +26,14 @@ class RhasspyClient: """Client object for remote Rhasspy server.""" def __init__( - self, HOST: str, PORT: str, session: aiohttp.ClientSession, secure: bool = False + self, host: str, port: str, session: aiohttp.ClientSession, secure: bool = False ): if secure: - self.api_url = "https://{}:{}/api/".format(HOST, PORT) - self.events_url = "wss://{}:{}/api/events/".format(HOST, PORT) + self.api_url = "https://{}:{}/api/".format(host, port) + self.events_url = "wss://{}:{}/api/events/".format(host, port) else: - self.api_url = "http://{}:{}/api/".format(HOST, PORT) - self.events_url = "ws://{}:{}/api/events/".format(HOST, PORT) + self.api_url = "http://{}:{}/api/".format(host, port) + self.events_url = "ws://{}:{}/api/events/".format(host, port) # Construct URLs for end-points self.sentences_url = urljoin(self.api_url, "sentences")