-
Notifications
You must be signed in to change notification settings - Fork 145
Initial commit for move to flask-ask. #85
Conversation
You have been busy :) Could this also be a good time refactor the code into smaller modules? The language issue is definitely something that we need to make sure is able to be addressed and if possible get it working for the initial release. I will have a test and make some suggestions (I had a look at a flask-ask conversion a little while ago also). How does the new .env file work in regards to timezones? |
Timezones shouldn't be needed anymore since we're not verifiying the timestamp. According to this https://alexatutorial.com/flask-ask/configuration.html we shouldn't be at least. I guess if you want to enable it, it'd still figure it out without the timezone data.
I actually don't mind how it is now that the WSGI and Lambda still is ripped out of alexa.py. It's just intents in there now which is how it should be.
Yeah, it's been something I keep getting emails about and I'm excited to get some good stuff going for our German speaking friends. |
Time zone is used to determine the local end time of the currently playing item. |
Okay, that's my bad. We can add that back in no problem then. |
Trying to check this out, but.. how do you call a Flask-Ask app from mod_wsgi? The Flask documentation says to just import it as application:
But that is giving me nothing at all. I tried importing the Ask object, but it says that object is not callable. |
Digging a bit further, it seems it's kind of working.. but I'm getting this odd routing exception:
I don't really understand Flask well enough yet to know why, though. |
Ok, that pisses me off and leaves a bad taste in my mouth, frankly.. apparently, it needed the final slash in the URL.... several hours later and it's something stupid, of course.. but still, their 'routing system' is clearly not very smart.. |
Went through every Intent systematically and things are mostly working. Only encountered a failure on the WhatNewAlbums intent:
Haven't looked into it really, but it seems we might need to sanitize the responses some. |
Sorry to hear that. I'm hoping the switch will ultimately be worth the initial hassle though. The lambda process is a bit different too.
Thanks for doing that. I haven't made it through every single one myself.
That doesn't surprise me that much. This is as good of a time to do it as ever. |
Yeah, it's a positive change. The Flask documentation's just not the greatest to be honest and am a bit worried about debugging issues when they arise for others. Mostly it'd be nice if it provided output for at least errors by default without having to enable debug mode. I might have missed that in the documentation, though. As for the responses, it seems something just got converted to ASCII along the way that should have remained unicode. If you don't spot it within the week, I'll have a look. Have to go back to the real job tomorrow though and am likely to be kept busy there for a little while. |
I think I fixed this in my last commit. |
On my list of things to check when I get off work. |
I think we may have hit a limit with regard to how big the Intent model can be. I can't be sure, of course, but I think every time you reference a slot in the Intent model, it creates a copy of it and there's some overall limit that (at least to my knowledge) Amazon hasn't exposed. Probably because they thought no one would hit it :) If I try to save the current Intent model, it appears to succeed, though it takes a really long time to do so. However, when using the simulator, I get:
If I remove my songs from the MUSICSONGS slot (simply because it's the largest list, sitting at 26000 entries), everything works again. Not really sure what to do about this, since users' libraries are lopsided in different ways; i.e., mine has many more songs, but others might have a crazy number of shows, or movies, etc. |
The WhatNewAlbums Intent still produces the same encoding error as before. I suspect any other Intent with non-ASCII characters in the response will too.
|
Might just need to limit the Slot Generator to 10k or something and see if that works. It's not ideal, but it'll give us a decent idea about how many they allow.
Try it again after the commit I just made. I think it's a special case on this intent. |
Okay, I added German translations for card and voice responses (just used Google Translate, so I'm sure it's awful), but it's working and automatically translates if it's configured as a German skill. Also, last night I pushed up some new intents that handle streaming party mode and all music by an artist to your Echo/Dot/Tap. This requires a bit of setup. You have to configure a mongoDB server and add information about it to the .env file as well as accept a warning I put in there about passwords being sent over the wire in plaintext. One of the biggest hassles with steaming music is that Amazon won't allow non HTTPS urls, and if it has an SSL cert, it can't be self-signed. For a lot of people this is too complex, so I wrote a little HTTPS proxy that'll work (again, if they accept the warning message). It's configured so that you can run your own proxy (mine is just here on Github), or you can just have a Let's Encrypt cert on your local machine if you are running an reverse-proxy for Kodi already. |
The problem is that I don't believe it's a limit on any given slot, or even the total of all slots. I think it's the cumulative number of entries in the slot references by the Intent model. That is, I think simply referencing slots increases some counter (or maybe it's just an overflow, who knows) that has a ceiling on it that Amazon has not disclosed. I think this because I tested it pretty thoroughly a little while ago while I was writing the generic search/play code. The 50k items in slots limit is published by Amazon, but I don't have 50k items in my slots in total. However, adding a new Intent that referenced existing slots caused it to fail, just as what you added makes it fail in the same manor on my installation. Basically, I think the Intent model has some undisclosed maximum size, and Amazon isn't referencing the slots, but instead copying them into the model each time they're referenced. |
It is indeed fixed, though it adds 'and' in between every item:
|
I saw that. It's just a logic issue. Should be a pretty easy fix. |
Give it a shot now. |
Yup, that's good now. |
It'd be good to factor out the generic code for this so we don't duplicate all of the existing music playback methods. But it'd probably be better to close out the Flask-Ask changes before doing so, because I've already got code ready for more generic playback that refactors some of it. I was holding off on releasing the generic search/play code because of the Intent model size issue though. I think before we can merge this branch we need to figure out how to properly solve that. |
KODI_PASSWORD= | ||
|
||
SKILL_APPID= | ||
SKILL_VERIFY_CERT= |
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 see that Flask-Ask enables cert verification by default, but do we want to provide a way to disable it?
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.
If you don't provide a SKILL_APPID, I don't turn on verification.
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.
They are two separate things though. SKILL_APPID is to verify that the application ID matches what we expect, whereas SKILL_VERIFY_CERT is for verifying the certificate.
I personally want them both enabled at all times, but others might just want one or the other.
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 also don't see where you explicitly enable cert verification? From the documentation (and I've verified it in execution too), Flask-Ask enables it by default.
Wasn't sure if we wanted a way to disable it, though. Personally I'd never turn it off, so it's no big deal to me if you'd rather just let Flask-Ask handle it.
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.
Well you know more than I do about the verification stuff. I haven't done anything with it. I would have to assume though that flask-ask takes care of the cert verification. Although I wasn't aware of it until you mentioned it.
I'm manually adding the APPID verification if the env variable exists though.
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.
Ahh.. but Amazon still verifies the cert before executing the Lambda function, right?
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.
Nope, Amazon isn't doing anything with it now. Everything is routed through API Gateway and it's treated the same as if it wasn't a real lambda as far as I can tell.
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.
Using this now: https://github.com/Miserlou/Zappa
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 ok. So we probably want the cert verification enabled in Flask-Ask at all times anyway.
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 can't think of any reason not to have it enabled now.
|
||
SKILL_APPID= | ||
SKILL_VERIFY_CERT= | ||
# SKILL_APPID= |
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.
Just so I understand, was there a reason for commenting this out rather than just leaving it empty in the example?
NewShowInquiry if we have {Show} | ||
OpenRemote open controller | ||
OpenRemote open controls | ||
OpenRemote open remote |
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.
Bear in mind that I had used "open" as the command to execute addons, so this means any addon with the name of controller, controls, and remote won't open via voice command.
edit: it appears "open menu" would have the same issue.
music.py
Outdated
import os | ||
import collections | ||
|
||
from pymongo import MongoClient |
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.
You'll probably have some users complain that pymongo isn't an optional dependency, just FYI.
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.
Yeah, I'll work this into the if check to see if they've agreed to the warnings.
@ausweider provided some initial effort for German here: danielmasur@03e1313 Could have a look at how he/she chose to translate the strings since he/she is a native speaker. It's a bit outdated, but could provide some direction. |
Re Slots and dealing with 20k of them. The ASK documentation is vague, I might have the wrong end of the stick completely, I would be interested to discuss... From what I have read it is my understanding that the purpose of a slot is to help identify and extract particular parts from the entire sentence. A number as a number, a name as a name, a song as a song etc. And to help identify what you are looking for you provide examples for what each slot might contain. Alexa uses the examples to "intelligently" match similar patterns. It is then up to the Skill to deal with the contents of the heard slot. All Alexa does is identify the song was a song and not a town name. Forgetting all the different complicated ways Alexa analyses the data she is trying to pattern match, instead lets assume that she is only looking at word count. A simple example is you have a slot of 10 song titles that were all exactly five words long, and a slot of 10 artists that were all exactly two words long. When you tell the Skill to "play radio gaga", chances are it will identify "radio gaga" as an artist and send the "search artists" request to Kodi and end up playing Lady Gaga. If you swapped one of the five word song titles with a two word title (so 1x two-word and 9x five-word), then it would (I assume) still identify "radio gaga" as an artist. Alexa could see that there is a small percentage of two word songs but based on what she knows (100% of artists contain two words, 90% of song titles five words and only 10% of song titles are two words) she would have to treat it as an artist. This is not the best example as the problem (as I am sure you know) with songs, artists and films as they are all super varied and you could easily swap a list of songs with a list of films and not spot the differences. @jingai have you tried (can you try?) using a curated slot list of 200 songs/artists/albums that covered a broad spectrum of each and then tested it with examples that were not in the slot lists? |
The problem is I wouldn't really know how to curate it without fully understanding how Amazon uses them. Their descriptions of how it matches things to slots is vague at best. I was thinking of modifying the slot generator to choose N (200, 1000, 5000, whatever works; bigger is better in my experience, so it'd be matter of choosing N where the skill doesn't break) random items for each slot. But I need to set aside a decent chunk of time to test it. If string length is also a factor, we could distribute the random choices so we get a roughly equal distribution of samples at varying lengths too. |
The other thing to think about is if a user doesn't have enough of a given media type in their library for the Slot to turn "generic". Might need the Slot generator to spit out some canned entries in that case. |
Hopefully the new built-in intents will help when they arrive. When the UK didn't have IFTTT integration with our Echos, we used a workaround where we could send any phrase to the Maker Channel (webhooks) on IFTTT. I used to use a list of phrases for the sample utterances which would allow me to pass any phrase to the channel. hello |
Yes, but we need to do something in the meantime so those with large libraries aren't faced with an odd failure case like this (Amazon telling the user the Intent model was built just fine, then failing at runtime). Simply choosing, say, 2500 random items from the library for each slot would probably work for now. Just need to test it. |
Rebased onto current master in preparation for merge. If you have a local copy of this branch, you'll need to delete and re-pull. |
All that's left is testing now -- touched a lot recently by stripping out streaming music. |
Unfortunately I won't be available till after April 24th. @sveni-lee |
This is a big update and the precursor to v2.5!
I have moved to flask-ask to help make the skill as clean as possible. This move allows the skill easier compatibility, and I believe it will make translation work very trivial since everything is in a template file now. Using something like babel should allow easy translation going forward (German first. We'll see what other languages Amazon will expand to soon).
I have moved the necessary code from
wsgi.py
toalexa.py
and the mainapplication
method is now justapp
. So there will be some changes needed to upgrade current versions.This is not ready for a merge into
master
yet due to documentation needing to be updated. However it is ready for testing.Please let me know if you have any questions.