Rock Solid Python with Python Typing Transcripts
Chapter: Frameworks Built on Typing
Lecture: Parsing Basic Data with Pydantic
Login or
purchase this course
to watch this video and the rest of the course contents.
0:00
Now that we have Pydantic installed and everything it needs to run, we're going to go over here and create a new thing.
0:07
I'll call this D1 for demo or example one here. Let's just call this parsing with Pydantic. Of course, we need the main method if dunder name is main.
0:24
I'll hit it with this little alias I got here. And the first thing we've got to do is say import Pydantic. Okay, so let's start with some data.
0:36
I'm going to go over to the weather.talkpython.fm website. And this thing is actually using Pydantic behind the scenes.
0:43
So it's kind of pretty meta there, which is awesome. And I'll pull up some data that we can parse.
0:49
And let's just take a real simple piece like, let's say this. And I'll just go here and say data equals that. And Python and JSON are so similar
1:05
that I can just copy from one to the other, at least from JSON to Python. The other way, if you've got single quotes for strings,
1:11
JSON is, I don't know, doesn't like that. It should, but it doesn't. So here we have this data and let's put, let's change this feels like to location.
1:21
So this can be some other data type. Let's say this is Portland, Oregon, and let's just change this to be temp range. And I'm gonna put this in,
1:34
I wouldn't really normally do, but just so we can show some stuff off, I'm gonna put this in as a list.
1:40
So lowest and then highest, not a great data model, but let's say we don't get a choice. This is what we're given, right?
1:46
So imagine we have this data and we want to model it, right? We want to model with strong typing, because right now the way I work with it
1:53
I say get location and it's like, well, I don't know what you're going to get. We're not real sure. It looks like that might be a string.
2:03
If PyCharm is guessing that, I will be blown away now. Not really. It could be a string, it could be an and. We don't really know.
2:12
What we want to do is work with this in a structured way and we're going to use Pydantic to do so. So over the top, let's just call this a class.
2:19
We'll call it weather, forecast, whatever. like that. And it's going to have things that are the names here. So we'll have like a temp
2:28
location, these types of things. Now, you can see Python doesn't love this, we could make it work
2:36
by setting them to be none or something. But let's not do that. Right? What we're going to do instead
2:41
is we're going to say each one of these has a type. So what is this type here? It could be a float or
2:47
presumably an int. Remember your number tower or numeric tower we discussed. So this would be a
2:52
float here. And as soon as we specify the type, the warning goes away. So that's pretty awesome.
2:59
This is going to be a string. This is going to be an int. Let's say it has to be an int,
3:05
it can't be a float. This will also be an int. And this is going to be a list of int. All right.
3:13
So this is a perfect classroom modeling this data structure. The types expressed here match this exactly. But how do I go from this to that?
3:24
Do I go w equals weather, w dot temp equals, what do you want? Float of data get of temp, like that. You know, do the same for location and so on.
3:41
Nope. No, we're going to use Pydantic. So Pydantic says you're going to create a base class here, or derive from a base class, called BaseModel.
3:51
And by doing so, our weather-- notice there's a little warning or an error here. It says humidity unfilled, location unfilled, pressure,
4:01
all of those things. Your editor may not have that. Mine does, and I recommend that yours does as well, because I added Pydantic support to it.
4:13
So it understands what goes in here. So one thing that we could do is we could specify temp equals whatever we get from the dictionary.
4:21
Location equals whatever we get from the dictionary. But dictionaries have this cool way to explode them into keyword values.
4:28
So I could say temp, if I could spell it, equals data dot get of temp comma location equals data dot get of location, etc. You
4:43
don't want to type that that sucks, the bigger it gets, the worse it is. So all you do is
4:47
you say star star data, and that expands out to be temp equals value, location equals value
4:52
pressure equals value, okay? So if you see this, that means turn everything into keyword arguments that were top-level values in the dictionary.
5:01
Now watch this. We print w and we run this. Bam! Look at that! How awesome is that? So, we said, ""Hey, Pydantic, figure out what goes here.
5:13
So the fact that we already got this, really cool. It parses it, really cool. But that's just the start.
5:19
Like, what if I said the location was a string and what if it was a instead?
5:26
Let's imagine instead that location was a tuple, yes indeed, a tuple of city state like that and we run it again.
5:37
Not only do we get the parsing, we get really good error checking.
5:41
It says, okay look, the problem, there's a problem with the location field when you tried to parse it. In your class, you said it's a string, right?
5:51
be a string string type. But we actually got was a tuple with this particular value. It's
5:57
not supposed to be like that. So it parses it over and says, No, but this is it will
6:07
put that back. It also would say that this one that's supposed to be an int. What's going
6:14
happen if I put a one here, it got a number with a fractional part a float instead of an int.
6:22
But if I put point zero, if it actually is a float, fine, but it says, you know what, no data will be lost converting from 1019.0 to 1019.
6:33
Because they're basically the same number. That's pretty cool. So there's some flexibility in this, right? The other thing is, what about this?
6:42
But if this was 60, I run it again, it says the temp range in the index one field. So that is actually the second element in the list has a problem.
6:55
What is the problem? We tried to make it an integer, but it got a string instead, and its value is 60.
7:02
But look, if it was like 64, as a string, it's still going to run and notice there's no quotes, that's not a string, that's an integer.
7:11
So it's tries to look at the data and go, well, it's not perfect, but could it be converted over? If yes, it'll just do it. If no, then it won't.
7:20
The final thing is it'll have data that's supposed to be there. So like this crash, the required field of war, missing the location.
7:31
We could say that might be allowed. Remember, to have something set to none or null, you have to have it explicitly stated as nullable.
7:41
So over here I could say, remember the way to do that is typing optional. So optional, import that, and this is a string.
7:50
So it's either there or it's optional. And in this case in Pydantic 2, not in 1, but in 2, you have to set this explicitly here.
7:59
Showing it again, now notice location is none, but that's not an error because it's not required, it's optional.
8:09
reason that I really, really, really like this and not string pipe none. Yes, they mean the same thing. This one says it's optional.
8:22
It doesn't have to be in the data. This one, well, it could be these two values, which the implication is such and such, right?
8:28
Anyway, I've gone on and on about that. You can make your own decisions, but I really love optional. It's optional in the data. It's not required.
8:35
So this is Pydantic. The final thing is that we can have nested things like this could be a pressure reading
8:43
if we had a class called pressure reading that had multiple values that was itself a Pydantic model. So these can nest in a hierarchy in that way.
8:52
Pydantic is awesome. Look how cool it is working with all of this data here. Excellent.