Helper library to develop Rhasspy apps in Python

I’m now working on tests (current code coverage: 44%) and there’s autogenerated API documentation. I want to expand both before I create the first release on PyPI.

I just published the first release of Rhasspy Hermes App on PyPI: 0.1.0.

You can install it with:

pip3 install rhasspy-hermes-app

If the API of this library changes, your app possibly stops working when it updates to the newest release of Rhasspy Hermes App. Therefore, it’s best to define a specific version in your requirements.txt file:

rhasspy-hermes-app==0.1.0

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

I have expanded the documentation, including some information for people who want to contribute.

All contributions are welcome! New features, bug fixes, documentation, tests, …

@H3adcra5h I have added a lot of documentation, mypy annotations and tests to the code, but for now I have left your raw topic additions more or less alone because you know that part of the code better. If you could take a look at it, that would be awesome.

4 Likes

I am no real Python developer and don’t really know what is best practice for such things.

One idea would be: add a new parameter “supported_slots” to the decorator.

Could look like this:

@app.on_intent("StartTimer", supported_slots=["minutes", "seconds"])
def handle_start_timer(intent, minutes, seconds):
  or
def handle_start_timer(intent, slot_minutes, slot_seconds):

If the Intent has slot values for minutes or seconds handle_start_timer will get called with that otherwise it will provide “None”. One variant of this would be to also put the expected type into the decorator and let the decorator do the validation.

Another option: Just provide a helper function like mine in your module to get the slot values out of an intent. As you can see in my source (maybe I am doing it wrong) it is not that simple.

Ok, I have created an issue about easier access to slot values to welcome a discussion and follow progress on this.

I have released version 0.2.0 with two additions:

Added

  • Method HermesApp.notify to send a dialogue notification. See #10.
  • Decorator HermesApp.on_dialogue_intent_not_recognized to act when the dialogue manager failed to recognize an intent. See #9.

The latest version can be installed from PyPI:

pip3 install --upgrade rhasspy-hermes-app
1 Like

I have released version 1.0.0 now, with one big change:

Changed

  • All decorators of this library now only work with async functions. Pull request #16 by @JonahKr. Existing code should only add the async keyword before the function definition to keep the code valid. See Usage for some examples.

This is a breaking change, hence the major version bump. It has been contributed by @No_one and makes it easier to integrate Rhasspy apps with asynchronous APIs, improving performance. The latest version can be installed from PyPI.

4 Likes

Just a quick question. I don’t see any mqtt config in any of the examples on github. Am I correct in assuming that it just uses whatever config rhasspy itself uses?

No, it uses localhost:1883 as default, but you can change all MQTT connection settings as command-line options to your app. See the example output of python3 examples/time_app.py --help in the usage section of the documentation.

I’m still thinking about additional ways to pass these parameters, by the way.

Okay, if that is the case, I am definitely someone needing an additional way of setting things.

I am trying to get my complete chaos of weather app to be less of a chaos and have it use this as an optional output. Thing is, I am actually using a config ini to set parameters such as mqtt options (I am using paho mqtt directly right now and it will be an option even after adding support for this) so setting this with command line parameters would circumvent the config file that I need for quite a bit of other stuff.

It seems adding support for this needs to wait until there is a way to feed values from my config file into this app or I have given up on having mqtt settings in my config file.

There’s currently a pull request that adds support for something like this:

app = HermesApp("AdviceApp", host = "192.168.178.123", port = 12183)

This works with all parameters that are recognized on the command line. You could read your MQTT parameters from your configuration file and feed them like this into the app.

I still have to find some time to test it, especially how it interacts with parameters passed on the command line.

I’m cautious about adding direct support for a specific configuration format, because everyone has his own preferences for this, but the Rhasspy profile configuration format could be a sensible addition.

I would definitely prefer that format over the command line parameters, but I think I need to rethink a few things of my library because right now I don’t think my concept fits that well into yours. I need to play around with this a bit before I can figure that out.

It just occurred to me while writing this that reading mqtt settings out of a per library config is definitely not the way to go, so even the current way with command line parameters would work. My brain seems to be fried right now from coding to long and figuring out how to make my chaos less chaotic. Sorry for bothering you with this, I sometimes forget I write a library and not a standalone app.

Now I’m a bit confused: I thought you were talking about your weather app, but now you mention you’re writing a library.

I am talking about my weather app, my limited knowledge of python tells me that something that I can call and it does something is an app, if I need to call it from somewhere else and feed information into it is is a library. I might be wrong about that assumption, the python course at university definitely didn’t teach about things like that, only about what an if is and does.

Basically my weather something is supposed to be called by whatever whoever uses it wants to use, be that a script using rhasspy-hermes-app, a command script or something else. I just take whatever input, parse it with whatever the config tells me to use it as a parser and output to whatever the config tells me to output to. So if rhasspy-hermes-app is used the mqtt settings have to be done there, trying to fit my settings for “just output this to this mqtt server” in there is not the way to go.

Oh right, that way. Well, I’m curious, I’ll follow its development, because it looks like a very interesting app to have.

I have released version 1.1.0 , with one small but interesting change:

Changed

  • Command-line arguments can now also be passed as keyword arguments to the constructor of a HermesApp object. Note that arguments on the command line have precedence. Pull request #37 by @No_one with help from @maxbachmann.

Keep your issues, comments, pull requests coming. And feel free to let us know here how you use or want to use Rhasspy Hermes App or what can be improved.

1 Like

Might be me being stupid but how do I get rhasspy to actually answer via tts? I have set up the GetTime example, I connect to the mqtt server just fine and I do get the EndSession message and it looks right but nothing happens. Do I need to config rhasspy in a specific way for it to work?

EDIT: never mind… it works with a wakeword but not with the wake up button in the web gui. I have no idea why it does that but I am pretty sure that it is something rhasspy does differently with the wakeup button and normal working behaviour.

Yes I bumped into this too a while ago. I don’t remember the exact difference, but I think the wakeup button doesn’t initiate a full session. It’s best to test your app with “real” sessions beginning from a wake word you told yourself.

I normally don’t work with real sessions because I have been unable to actually get a wakeword working in a non annoying way. Best I got so far is raven and even that breaks after a while and activates on silence because my respeaker mic ends up creating random noise on one channel after a while without restart, those driver still don’t work well. It was a pretty big fight until I got the mic to behave good enough to actually record a wakeword.

It would be really nice if the button would actually work the same way rhasspy responds when I use a wakeword because it would testing just that much easier but I can see why that is pretty low on the priority list.

That’s a good point. I opened an issue on GitHub:

1 Like

It has been a while, but I released version 1.1.1, which is a minor release:

Changed

  • Updated dependencies. The most important one is the upgrade to rhasspy-hermes 0.5.0.

This fixes an encoding issue.

I have been busy with some other stuff and so I haven’t been active lately with Rhasspy and Rhasspy Hermes App, but if you have some ideas, requests, issues, just let me know here or on the project’s GitHub page. I’ll be happy to look into it.

1 Like