Anvil: Web Apps with Nothing but Python Transcripts
Chapter: Consuming the API with Fitnessd Local app
Lecture: A GUI version of Fitnessd Local
Login or
purchase this course
to watch this video and the rest of the course contents.
0:00
We're the grand finale for application. We're going to convert this command line app into a GUI app that will run on Mac, Windows and Linux.
0:09
How cool is that? We're going to use a library called Gooey. Not this, this. But we can just have PyCharm install it.
0:18
You'll see it'll spin down here at the bottom for a sec. Again, just hit install dashboard requirements. You're not doing it through PyCharm.
0:25
All right, well that worked well. Let's go over here and we're going to do some more imports.
0:29
We're going to import this thing called Gooey and GooeyParser. And the way this Gooey thing works is
0:34
we go over here and we say this is a Gooey application. We say program name is going to be Fitnessd Local. That's what we're going to call it.
0:46
And we'll say show this doesn't have auto complete for some reason. It's kind of annoying. Anyway, show_success_modal=False.
0:55
So when things succeed, don't show me a dialog that says Hey this worked. Like you know what, I know it worked. Tell PyCharm that's not misspelled.
1:01
Okay so this is going to trigger an interesting UI. The next thing we need to do is come down here and say parser = GooeyParser.
1:12
Want to give it a description of the app. Let's just put it in like this, Fitnessd Local. Local edition, record your health on the go.
1:23
Now, what we're going to do is the way Gooey works is we go to the parser and we add an argument. These arguments show up as UI form elements.
1:33
But we first want to check this part here. And if it's not authorized what we're going to do is we're going to add an argument
1:42
for the email and we're going to set the default equals auth.email if for some reason that happened to exist.
1:53
We'll say widget though equals password field. And that will put the little dots instead of showing the password.
2:03
Now let's go ahead and just configure. That's going to take care of a whole bunch of stuff here. Let's go ahead and configure some more arguments.
2:09
And I'm just going to drop them in there. So regardless of whether they're logged in we want these things to be added.
2:17
So we're always going to ask for a rate a weight, and a date. Here's some description, the types are integers
2:22
and we even have a calendar picker type thing. So that's all good. And then the next thing that we want to do is we want to show the UIs.
2:30
The way we do that is parse args, like that. This is where it gets interesting. So we should be able to come down here
2:38
not do a whole bunch of this stuff. Before we were getting user data and that's kind of gone now because the Gooey itself is actually doing that.
2:47
But something like this we could actually drop this whole thing here or we could move maybe this into it.
2:55
And the way this works, whoops I need to store this here. This data that comes back from parser it's basically like a dynamic object.
3:04
It has the values, rate, weight, and date, in it. So super easy. data.Weight and I'm using capitals because this is the title in the UI.
3:16
We have data.Date but the way this comes back is kind of crummy. So I'm going to bring in one more library for parsing it. Python dateutil.
3:26
Just refer it to this code. Here you have to put the Python in front and that's not misspelled which is what I was actually trying to do.
3:34
So that got installed. Up here, we can import dateutil and say dateutil.parser.parse. A lot of parsing going on here, isn't there? Okay, super.
3:47
Now, we kind of have to ask the same question again. Did they already log in and get authorized? So if they're not authorized, is authorize again
3:57
we want to get email over here. data.Email, password equals data.Password and we want to save it. But we need the API key. Let's put API key.
4:10
So over here, we're just going to go to the service.authenticate email and password once again. So we're going to save that.
4:20
And then finally, we should be okay. We'll say for some reason they couldn't log in. We'll print their authenticating and return.
4:34
Otherwise, we'll put login successful. And we're down to this. Now the final thing we need to do is just save the measurement.
4:42
And here, this is going to be auth.apikey and auth.email. And then we have our data and I guess it probably is a little bit nicer
4:53
to pass those as values. Let's go ahead and change these. Rate int, weight int, recorded is a str and let's just change this
5:04
to data, weight is weight, and so on. Whoo, all right. Final thing, we have to pass different values here so we can pass the, let's see where are we.
5:16
We're at rate, weight, and recorded. Get those in the right order. All right, well this reworks is to use this parser idea.
5:27
What does this parser even look like? Let's go ahead and run it and see well first if I got it working and didn't make any stupid mistakes
5:33
while talking and coding. And second, what it looks like. If it works, you'll be impressed. Here goes. Oh check that out! How awesome is that?
5:43
So we have our rate in pounds. Look, we built a GUI! This is so amazing! So let's go over here and put this as 77 and 177. Just so we recognize it.
5:54
We even have a cool little date picker thing and that's not incredible but whatever, it still works. Actually, I do want to pick today.
6:02
I guess we should probably default it to today. Wouldn't that make sense? Put that as 25 or something in the future.
6:09
So this is going to gather the data and then we're going to run it and it'll call save that into the API. Let's see how that works.
6:16
Oh, oh there's a problem. I need to import this, sorry. Parser, date util doesn't seem to import it's sub packages. That's fine. Oh here we go.
6:33
For some reason, that's so weird that that didn't work before. Anyway, we were setting the default but whatever. All right, let's go 77, 199
6:43
again, just to get it a unique value there. Boom. datetime is not serializable. I forgot to call isoformat. Where are we doing that down here?
6:56
Put isoformat. Remember I told you this is a datetime.date. There we go. JSON doesn't deal with dates, annoying. All right, last time. 77, 199, go.
7:16
Could not save the measurement. What did I pass in wrong this time. Oh we're so close! But nope, it didn't work. Let's see what our app log says.
7:27
Oh it passed in the wrong date time format there. So let's go back to our code. Dates are always super annoying here.
7:37
Let's print this out real quick, just see what this is. Didn't really matter what I put there because it's not going to work.
7:47
Yeah, I think it might be getting a time zone or something funky in there. So let's split on T and just get the last one.
7:53
So that's sort of annoying but this should work. 77, 198, and that date. Off it goes. Yes! Success!
8:04
This is probably not the message we want to show to them but let's go check it out and make sure our Gooey app worked.
8:10
That 198, there it is. It just went in. So super, super cool. We were able to go and build these cool APIs. We authorized our users.
8:20
And most importantly, we can now add our measurement. Once we have the API, we're able to call it externally
8:26
from pretty much any client, as we saw with Postman here. And then we said Let's build something super nice like a Python app.
8:34
Started out as a just throw it together command line app and then we actually converted it using the GUI library over here.
8:43
GUI library and the GUI parser to be a full fledged GUI application. The grand finale, I guess, which we're not going to do
8:52
would be to use PyInstaller or PyOxidizer to bundle this up as an EXE or a .app You could just ship to your user
8:59
they double click it, they run it, they see that UI. Everybody's happy. All right well, there it is.
9:05
There's consuming our Anvil API with our Python app.