 Thank you everybody, and huge applause for me too. Well, today I'm going to be talking about by danting. I'm not going to go too much into technical details, but what I want to explain is why by danting is the most amazing thing ever, that is that made out of sugar, and why should you use it in your code? Yeah, a little bit about me. I've been doing Python for 12 years. I work a lot with fast API and PyDentic, and it's completely game-changer for me, because earlier so much of my code was focused on defensive programming, basically checking if front-end is doing its thingy or not. So having fast API and PyDentic in combination has made my job much, much easier. And that's, first I'm going to explain you why the dynamic tapping is the most awesome thing ever. We have that in Python, and it's super easy to teach people to work in Python. You don't have to set up compiler, you don't have to worry about types. I know when people are starting to explain to them what is a character, what is a string, what is an integer, what is a float, is completely insane. So having the ability to just add two numbers, get an output, or take a string, print it out without having to go in-depth about what is the types and all that stuff is really good. Also, I remember from my old days, I was working in PHP, and there's also no typing. And it's very easy to write horrible code, but that code will work. So dynamic typing is awesome, but it's also very bad. Especially because in Python, we have that belief that our system is super nice and we don't validate it inside the first system, everything is working perfect. However, that is not what's happening in the real world. We are communicating with different applications, working in a bunch of other stuff, and we can't always trust them. Now when I started, I was a Java developer. So my code was pretty horrible for the first six months, let's be humble about that. Basically for every function that was adding two integers, I would write a boilerplate of code checking are these integers actually integers or somebody passing me a list and string, even though I was the only one using that code, I was writing Java code in Python. For those of you who didn't work with Java, I heard more than one version are good, but the old versions, for opening a file in Python, you have open in Java, you have string, you have buffer, and then you have bunch of boilerplate. And even though I was working for two years in Java, every time I wanted to open file, I had to Google it. It's horrible. But you're always safe, you know what's happening. Now I'm going to describe a simple, typical Python application. We can think of it as this little island. It's super safe, cozy, and nice. I wanted to add some palm trees, they didn't fit. But in the middle of our island, we have a small treasure. That's going to be our database, and we are surrounding it completely. Now, database does not trust our code at all. It's going to validate it, everything will send it, it's going to throw errors, it's going to complain, and that's why database are amazing. They're not going to allow you to write horrible data, especially with relational databases. You can put a bunch of constraints on the data, just to make sure that everything is working okay. So we can learn from that stuff. We are going to validate everything we send to database, because we don't want it screaming at us. But at the same time, we are usually using Python for writing backends. So think of this little island as our fast API API. And all this crazy stuff around us, it's going to be JavaScript mostly, some other Python programs and stuff like that, and they're crazy, absolutely crazy. I know a few Java developers, one of them is my brother over there, and JavaScript is good for many things, but you can write some very interesting stuff with it. And usually when something goes bad, it's very difficult, because I'm not a full-stuck developer, I know very little full-stuck developers. So when something goes bad, you have to sit down with your front-end developer and talk with them. Did you send me wrong data, or was I doing something wrong with that? And if you don't trust the data that's coming to you, you're going to have much easier life. So be paranoid about everything that's on your system. Have very strong borders. And everything that's going inside needs to be checked early, like at the customs office. You're going to just let you in the country, unless you have a private jet. That is why we as a back-end developer can write directly to database, but front-end people cannot. So as I mentioned before, a bunch of my discussion with the front-end team is focused on figuring out who made the mistake. Were they doing something horrible, or was I doing something horrible? And when you don't have type checking, I was working with some of the legacy Django code that basically, front-end developer came to me and asked me, okay, what are the input parameters? And I had to go 10 functions deep to figure out, okay, this is an optional parameter. And then basically create a small node and send it to him. That is a very horrible way to spend time with the front-end team. When you have a proper validation in place, if there is an error and you're not returning the error, then you're at fault. If there is an error and you're returning them, they get right away, okay, you didn't provide me this field. And you reduce bunch of talking with front-end people instead. You can talk about them a bunch of other stuff. So since we started working in fast API, which uses Pidentic all over the place, I actually talked to my front-end colleague, learned he knows how to do diving, had some certification, we talk about bunch of other stuff, but we do not talk about API. Now, before we go into Pidentic, there's a little thing, type hints, that were added in 3.6 and are the coolest thing ever. In Python, we don't have type validation, but we can hint to our Python code that this is going to be an integer. And this function is going to return, for example, another integer, or at least. And that's very good, because myself, code I have written two weeks ago, that's completely different person. I'm not going to know what's happening there. So if you have type hints, you're very easily able to just look at the name of the function and know what's happening in there without going into the code. However, you might be asking, okay, these are just hints. It's not going to make my code any better. I'm just writing extra stuff. Same as documentation. Well, I work in PyCharm, but I'm pretty sure we use code and bunch of other modern editor support types. When you try to send some horrible data, for example, I'm adding two integers and I send strings. PyCharm is going to mark that as a warning and complain to you. And we also have MyPy, which is an amazing tool that you can just run against your code and it's going to tell you you're doing something completely wrong here. And I always integrate it into my CICD pipelines. So nothing that's super horrible gets merged into production. You have to fix those errors. And introducing type hinting into our program has greatly, greatly reduced number of bugs because you do have your tests. And of course, you're going to do some property-based testing with hypothesis, but there's always some unforeseen function call. And MyPy can catch those. However, there is absolutely no runtime validation of your data. So when your code is running and you're not providing the inputs to your code, but it's provided by a different Python script or you're reading it from some stream or somebody is just sending you post requests and you're writing that out, Python doesn't care about that. Even though you type hinted I want integer to be user ID, you can get a string. Everything is going to work fine, then it's going to break into database. And you're going to return error 500. Now, we have multiple status codes. But the most important ones are 400 and 500. 400 means front end to mess things up. 500 something went wrong on the server. We don't want 500. Now, getting started with Pridentic is very, very easy. As you can see, we just import base model and create a very simple class. You can provide type hint, default value, and then we just call it like this. And it just works. This is the whole code that does validation of the user class. It's going to complain. It's going to throw validation errors. And most importantly, it's going to tell you what you did wrong. So you put this into your endpoints. Then you don't have to do anything. It's going to scream at the front end people. Now, in fast EPI, it chooses Pridentic a lot. You can do this for return types. So your code is going to throw error when you are the one that's returning the garbage data to the front end. So it does two way validation for anything going in and everything going out, which is super great for figuring out what's going wrong. And in programming, 90% of the time, that's what you're doing. Also, I did work a little bit with Scala. And Scala is a very, very programming language. Because by default, everything in Scala is immutable. And for me, that was like, why would I make my list immutable? But as I worked a little bit more with that, I realized how much of my code relies on side effects. You provide input parameters and you get an output. But in Python, it's very easy to have something, for example, merge to list function, where you add a second list to the first list and return that one. If you take a look at the code, everything looks perfectly nice. But you can modify the input parameter. And if somebody doesn't know that, that's going to make stuff super, super crazy. So what we want to do is basically every single time, we want to avoid side effects of the function, unless explicitly thought. And we want to make stuff immutable. Because in presenting, that's super easy. You can set it up in the class as configuration. And then you cannot change the data. You have no idea how many bugs I caught by myself modifying the input request of the user. And that is great. Use immutability by default. Now, as I mentioned, a bunch of stuff is coming into the pedantic. From the front end, people, in most of the cases, you're going to receive a JSON. File that Python is going to turn it into a dictionary. And that dictionary, first API does a bunch of cool stuff in magic. That dictionary goes into your pedantic model as an input. If it's wrong, it complains. If not, it works perfectly fine. However, on the other end, when you're getting data from the database, in most cases, you're going to be using ORM, in our case alchemy. And you get ORM model. You can do that to input it and get a pedantic model, which is much lightweight. It just has these types. It doesn't have a bunch of database-related options. And best of things, all stuff, you're not in danger of accidentally changing the database and doing that, which I did a couple of times in production. Now, pedantic also allows the exporting data, because you can send a pedantic model to the front end. You can just call simple method that creates a dictionary or a JSON and throw that out. And that's it. Super easy to use and very, very intuitive. Most of the time, we want to have some custom validation of the date. When we want to go beyond the simple validation, it's not just a type. For example, one check, does this string have minimal length? Is there a certain property? For example, they have email string as a type. But let's imagine it does not exist. You can do some regular validation into it, and it will check that. Here, I just created a class unicor. And our pattern function does is you make a field name alludator, tell it for which parameter it works. And every time that class is created, it's going to take that input value, check it. In our case, we are checking is the unicor name magical. If it's not, it's going to create a value error. If it's good, it just returns a titled value, which is amazing. That's all there is to the custom validator logic. And in pedantic, you can also define custom fields. So for example, let's say we have a bunch of classes that are using the same type of validation. You can declare that field, then reuse it in a bunch of models. And it's super great. Now, you can also have custom types. You use custom types every time you have to share validators between models. And best of all, alias. This is really crazy stuff that they discovered while working with front-end people. Because front-end and back-end don't move at the same speed. Usually, it's much faster to change something in the back-end. While in front-end, they have Q&A, visual testing, bunch of other people are working on that. So your IP can move between the versions. And a field name can change. For example, let's say here, we are using username. We change the database and everything. But front-end code hasn't been updated. They're using user underscore name. You can tell to pedantic, this field has an alias. It can be named differently. Always good. Pedantic is going to take care of that stuff. And once migration is done on the front-end side of things, you just remove the alias. And then it's going to break. But it's post-transitional state. Also very cool stuff is that every class, you can set up various configurations for that. By default, pedantic is just going to ignore stuff. For example, here we have parent that only has a name. But let's say we pass a name, surname, date of birth, and all that stuff. Pedantic is just going to ignore it. It's just going to take one value. We can also allow it to accept those values. So it's going to create objects with all these additional values, but it's not going to validate them. I do not recommend you doing that. What I love adding is forbid. So if I get more data that I'm expecting, I love for pedantic to scream at front-end people instead of me telling them, this request is wrong. Because maybe they are sending me some data that is not supported and that is signal for them. And then when they tell me, no, no, this is actually good, then I put it to allow. You can use other pedantic models inside of another pedantic model as a type. And this works very nicely. In this case, we have ice creams. And we have perfect meal that just includes the list of all the ice creams. That's it. This is the whole code. In some cases, you want to have recursive models that refer to themself. You can just import from future annotation and just use the name of the class. This is the whole deal. Without import from future, you have to update your references, edit as a string, and it looks horrible. I love stuff that are short. For some reason, if you are feeling so inclined, you can create dynamic models. You have create model function. You throw it a string. And then you send a field with types. It's going to create a model for you in the rhyme time. And you can use that for validation. One disclaimer, I never used this feature, but it looks super cool. Identity can also be used for settings. And you have multiple environments. Multiple version of the software. You want to make sure your settings are OK. So in fast API, on the runtime, it starts up. It needs to load. OK, this is where my database is. This is my string and all that cool stuff. And you want to validate that. So in pie data, it's super easy. And it has a list of priorities for reading. First, if you explicitly create a pedantic model for settings and pass it, say, OK, use this database, it's going to use that. Otherwise, it reads for environmental variables, which is super nice if you're working inside of Docker. You can have .env file, which is nice when you're developing your local machine, but never use N files in production because you really don't want to have on the server in plain text, database, password, username, and all that stuff. I've seen that a lot of times, and you do not want it. And afterwards, if everything else fails, it will check, did we have a default value for that field. If we did, all good. If not, scream error. Basically, in order to start, you need to provide me a database URL. Pedantic has amazing documentation. Fast API and Pedantic, they are such a great resource. You can just go on their website. Everything's explained with a bunch of examples. And for me, that's the most important stuff. Can I figure out what's happening by just looking at their website? And yes, I can. And they explain a bunch of edge cases, much better than I do. So use their website. It's actually pretty cool. Now, we have Pedantic version 2, which is newly released. And I think three days before I got here, Fast API also started supporting it. What's different from Pedantic 1? They do the same thing. But Pedantic 2 is written in Rust. So it's several magnitudes faster, which if you're working with REST endpoints, doesn't mean anything to you. Majority of your time is not going to be spent on validating frontend inputs. But I'm waiting for database to respond. So maybe your code was working 100 milliseconds. Now it runs for 10 milliseconds. No, it's not. However, if you're working with data science and you have to go over CSE and validate all that data, you are now going to have actually a very good time, instead of early. Because when you have two gigabytes of CSV files that you need to validate before you throw them into database or some pipeline processing, now that actually is usable in Python. Earlier, you could not drink a coffee, but make lunch, drink coffee, and then go play around. Well, it's important to some of your stuff. So that is all. You can connect with me on LinkedIn. I love having virtual coffees with people talking with them. You're all amazing. Also, if you think your Python code could use some love, contact me and free for consulting and stuff. So. Thank you very much for the presentation. We have a few minutes time for questions. So if anybody would want to ask one, please get up, get to that microphone. And that microphone, you could ask a question. It's here in the middle. There you go. Or you come to the front. OK. While we're waiting for the question, a little reminder for those who are leaving early, please take your glasses and paper bags or paper cups with you. We had problems in the other room where people left too many of these. And if you see one left by the others, please take that as well. Your question, please. Thank you for the talk. My question is one common example, one common use case you gave is validating data coming from the front end, right? Untrusted user input. And especially in this particular use case, JSON schema would be another way to do that if I understand you correctly. And especially with the use case that you gave with the dynamic data class generation, is there anything or would this be a perspective to basically dynamically generate data classes, authentic data classes based on the JSON schema that you may already have, to basically have a native Python valid schema based on an existing JSON schema? Does that make sense? Yes. And that's actually a pretty good use case for dynamic models location. Do you know if there's already a library that does exactly that, or is it something one would have to do? I actually don't know about it, but that's a real cool idea. Well, that was a question. Yeah. Thanks for the question. Are there any other questions in the room? Don't be shy. Ask everything. It's still possible to ask questions, but it seems that everybody has learned a lot about it and now needs to try it out at home. And then we will get some questions. But if you are using Fast API, you're using it anyway, so you will be exposed to it. And then you might want to try it out in your other non-web server projects. Yeah. If you think of any other questions, feel free to reach out to me on LinkedIn. I'll be more than happy to answer. I'm not a contributor to pedantic. I just love the library. OK, so thank you very much for everybody to come here. We'll take a short break and then continue in roughly seven minutes with the next talk.