 Thanks, everyone. Thanks for coming. Without further ado, this is my presentation. CLI application development made easier with Typer. Hope you enjoyed it. A bit about myself. My name is Vinicius. Vinicius Gubiana Ferreira. I'm from Brazil. I work at Azen Technologies. I work as a quality assurance team lead for about a year and a half now. Every now and then, I work on open source projects. I think the most amazing project that I worked was translating the Python documentation for Brazilian Portuguese. And I also love craft beer, my favorite one being VICE. Prague is a really great town for trying beers. If you know any place that have craft beer, let me know. And riding a bike back in my town. I don't even own a bike myself. It's a rental I rented per year, which is viable for me. I don't maintain this on bikes. And our schedule for today. We're going to talk about the motivations for this presentation, like answer the big questions such as, why am I here? Why are you watching me? What reason I decided to do this presentation? What problems you can and can solve with CLIs? Then we're going to get to know Typer and a few of the other libraries and package that do the same job as Typer, just to get some other that may be familiar for you. Then we're going to start with some code into getting to know Typer, how to actually create a CLI application. And to wrap it up, we're going to discuss the use case back at Azure and put side by side the pros and cons comparison. So first things first, the motivation for this presentation, a CLI in 2023. Why? That is the big question, right? And if you have no idea what a CLI is, it's pretty much any application that you run, only using your terminal. And can be known for other norms such as client applications, CLI application, and some other terms. And there are at least, I think, two big reasons to develop CLI applications. The first one that I decided to bring over here is mostly to hide complex operation and make any program actually easier to work. And there may be actually lots of different variations from this scenario, but I decided to pick one that I think it is the most recurring one, which is dealing with APIs. And dealing with APIs usually goes something slightly like this with the story. Here's our user. And he's actually the first thing you always have to do when dealing with an API is actually create a token to authenticate yourself to ensure you are who you actually say you are and you have the necessary permissions. And then if you get a token, then you're probably going to have to do something with your data that you actually want to change, like post, or patch something. And then you go to another endpoint. But then after you get that data, then you're probably going to need to confirm if the data that you actually have, and want, is actually a valid data, then you have to go to another endpoint. And after you get that, you go to another place. You've actually figured out that the first place you're actually going was not the correct place. And that can go on and on and on. And by the time you're actually done, you're probably going to be mad, frustrated, annoyed, pissed off, or whatever other feeling that you're actually feeling over here. And I think some of you would actually use the API development before might have this feeling. I see some people nodding their heads over here. I think they agree with me. And this life shouldn't actually be like this way. Be hard. Should be something simple. Like I want to go from A to B. That's it. All that is actually, it should be. I want to get into my car. I want to turn the keys, and I want to get from A to B. I don't care how the engine actually works, what's happening. I can, but it might not be necessary for me. But CLIs tend to go into that way from trying to make things simpler, just from A to B. And another good interesting point to develop CLI applications is mostly to think about improving user experience and developer experience. And let me know if you ever found a situation like this one that nowadays still happens a bit with me. You found a repository on the internet that says it solves your problem. But it doesn't tell you how. It's just magic. It just happens. And the developer have a mindset of something like it was hard to develop, and the user should probably figure out by himself. And of course, I blurred out the parts over here that I didn't find the repository and the author, just in case by any chance he's actually in the audience. And I'm going to hear bad words from him. I don't want that to happen. And usually, you go for documentation for that case. And documentation, every now and then, is very often. We see it's just a single line of code. And I picked this repository because this doesn't even have one line of code. It's actually half of line of documentation thought that that makes even worse. And CLIs are a great way to improving on that because if you use the dash, dash help option, then you already put documentation inside your application. So after this brief intro, let's talk about Typer and the competition of Typer. And even for Typer, it's actually great in doing its job. It's not the only tool out there. I'm going to quote some other tools that are actually available, some of them are actually being showed up here at Aerobite in 2023. I think the most famous one that has been a while for a while, it's ArcBars. If you Google it on the internet, then it's probably going to be the first one that actually shows up. Some people actually believe that it comes along with Python because the documentation for ArcBars, if you go to docs.python.org, then you're actually going to find documentation for ArcBars. So it's been, I don't know, maybe from Python 2.3 or something like that, that ArcBars it's been around. Then there's also click, which is also a great tool. And this is actually the engine of Typer, is actually what is running underneath Typer. Because Typer mostly has a new layer of code on top of click and makes using the library itself easier and simpler with a more modern Python approach. And we also have a PIL, which is being discussed here at Aeropite. I'm not really sure which day and time. And I read the docs for a PIL on a quick resume. And I quite couldn't grasp it, how amazing it is, at least compared to Typer. So if you have some time to spare, please check out the presentation. Don't remember the name of the person right now of a PIL. And there are other tools, many others. I know Bloomberg is also doing a presentation about their CLI. And there are tools that look like tools to develop CLIs. For example, Fabric and PyDoIt, PyPeer. But they're not exactly CLI development tools. They're more like Python script automation tools. So yeah, lots of presentation about CLI development this year. So thank you for coming to my presentation instead of other people's presentation. I really appreciate that. And speaking about Typer features, the biggest feature is actually it takes a lot of advantage on Python 3.6 plus type declarations that we saw a little bit before on the presentation about PyDentic. And this is probably where Typer gets its name from. I didn't see any specific place saying that explicitly. But I guess it's probably where it gets its name. It has auto completion pretty much out of the box. You don't have to do a lot of things to get auto completion working in your CLI application. And if you use any modern IDE, such as Visa Studio, JetBrains, IntelliJ, PyCharm, what else, Atom, and some others, then you just install the package and any necessary compliments into the IDE. And you're going to have auto completion when you are developing, so it's going to work just fine. As I mentioned, it's focused a lot on developer experience like you're going to help a lot your users into creating your CLI application. It's powered by click, as I mentioned, but with a more modern approach of Python. And it has 100% code coverage and 100% type annotated code, which is something hard to achieve, actually. And getting started with Typer is really easy. I always like to cover installing the necessary packages. And the first one, you just peep install Typer. And the actual recommended way is actually installing Typer all, which you add two other packets. One of them is actually rich, which is responsible for formatting and showing beautiful information on your terminal, which you'll check it out ahead. And also, Shellingham, which I hope I pronounced all right, is a package responsible for actually figuring out what shell are you using, because you can have a bash, zeng shell, fish, power shell, and many other. I don't know how many shells are nowadays, many, I think. And then you also have two ways of actually using tab auto completion. You can actually use it by using the Typer CLI, which you install it with that way, or by actually creating a Python package with Poetry, which is a recommended way. It's very simple and straightforward to install Poetry. You use that line. And if you never used Poetry before, you're still using peep. That's OK. I'm also going to cover about that. So all languages, frameworks, and packets, et cetera, they all have a hello word. And Typer is actually no exception. This is the hello word of Typer. It's pretty simple, just five lines of code. We just import Typer itself, and then we create an implicit command. We're going to cover commands in a couple of slides ahead. And then we just run our application. And what happens when we try to run this code? It's an error, of course, because nothing happens all right on the first attempt. But this is the blame is on us, because we forgot to pass an argument. We can already see rich and Typer doing its magic, all these yellow and red boxes. We didn't program anything at all about this. This is all in Typer and rich. And what it's saying over here is actually that we forgot to pass an argument, that argument is required, and there's nothing I can do to help you out. You must apply me with that actual value. And if we call the dash dash help option to see more information, then we already see pretty much the same information, but without the error, of course. We can see in the argument, it's called name, and it is required. And finally, if we pass that argument when we actually execute it, then it just executes our implicit comment as expected. It's just saying hello to whatever is the name of the person that we actually wrote over there. So our previous code didn't much look like a real application. Like I said in a previous talk, hello world is not something that you place on production. And let's improve on that. This is starting to look more like a real application. We're now going to learn about comments. And I'm going to highlight over here what actually changed. These are the important parts over here. We're actually, after creating a type of application and assigning it to a variable, and after getting that variable, we got lots of attributes and methods available for us. And probably the most important one is the common decorator. And in case nobody is aware what a decorator is, a decorator is pretty much a method that attach itself to another method. And what we do over here, we mark specific Python methods that can be used by our CLI application. And at the last line, we just execute our application in a slightly different way from what we did before. If we try to ask for help about this application, we can see at the bottom over there the two comments, the two methods that we created, are already available for us. And the comments are pretty much any action that we want to execute with our CLI application. And we can see on the right that the user doesn't actually need to know what's going on under the hood. The Python code that is actually being executed. He just knows about the comments and any necessary arguments or options. And I mentioned before about type declarations for Typer. And just in case if you never work with type declarations, doesn't have a clue what is that, I decided to cover it over here. It's pretty much this what's going on in this method. We have two parameters, a name, which is a string. And a formal, it's a boolean. It can assume true or false. And the biggest difference I decided to highlight over here is that the first one is actually an argument. It is required. And the second one, since it already have a default value, then you can choose by yourself if you actually want to pass that or not. If you don't pass, there's not going to be any error or any problem. The problem is just going to take the default value and carry on. If we ask for specific guidance called the dash-dash-help option, then we can see once again Typer doing its magic. Since it's a boolean, it can only be true or false. It created two options, dash-dash-formal and dash-dash-no-formal. And the option is actually the way name it for CLI applications when you have a default value in your argument. One thing that I decided to mention over here, which I find really amazing. Usually we don't document Python code only when really, really necessary. But documenting with Typer is actually recommended to help your users out. And there may be different possibilities in documenting your code. I decided to bring one over here that is probably the most easiest and magic, I believe it is. You just add simple triple quotes, comments, into your comments. And literally, but literally by magic, when you call the dash-dash-help option, they are transported directly for your users. And I'm really, at least, surprised by me because a comment is not actually executable by Typer. I have no idea how. This is actually ported for the final CLI application. This is rather interesting for me. I have to check Typer codes later on to find out how it is actually doing that. There are other ways into documenting. You can actually document your arguments, your options. And you can even use the Typer CLI to export your code, your methods, your signatures, and your triple quote comments into Markdown, and then place it on GitHub, GitLab, or any static site hosting. If you want to have your whole comment, your signature, documented for your code if they actually want to check everything that your application does. And you might have noticed before about this option over here, the install completion. This is actually how we set up auto-completion, which is when you're using your CLI, and you start to hit Tab, and the program auto-complete for you to help your users, to help you and your users. What happens over here, you use the Typer CLI, and you just type Typer, space-dash-install-completion. Then it says that it's going to install for you on your terminal, a specific file, it already is set. Then it tells you to either restart your terminal or to source that specific file. And from now on, if you use the Typer CLI or the Python package, then you have auto-completion out of the box. Something similar to that, you just go with Typer, the name of the file, and you start to hit Tab. It already suggested for us Run and Uchoose. Uchoose is used for creating the Markdown that I mentioned earlier. And Run is actually used for running your comments. You can see that they already filled automatically. And we also have the possibility of creating sub-comments. And wait, what exactly is a sub-comment anyway? So a sub-comment in the CLI world is pretty much a command that goes after another command. For example, we have this line of code. It is Docker container LS. Docker is actually the program. Container is a command. And LS is a sub-comment. So it's a good rule, but not a perfect rule, not everything that comes to the right of the command is actually a sub-comment. For example, we have this line. And almost at the end, these are not actually sub-comments. We have sub-comments, but what we have over here are arguments. We have the program, a command, a sub-comment, and two arguments, because they can change. They are not registered inside the code. And a good piece of advice regarding creating CLI applications is mostly to try to avoid these long lines, such as this one with Git, and similar as this, because this tends to get your users rather confusing. They're not going to be able, most likely, not going to remember all this whole line of sequence. They're either going to have to hit Tab a lot or go to the dash-dash help option to figure out, to learn, to remember. So try to keep your commands, the whole command line execution, as short as possible to help them out. And a quick example about sub-comments over here. And I'm going to try my best to explain, because I have actually four files to display. They don't actually fit the whole slide. It might be slightly hard. That's probably the worst part of this entire presentation, because it's hard to make them fit into these slides. This particular application, it's a fictional application, of course. We're going to play the role of Conquer from the old centuries, and try to manage our lands, our kingdoms, our towns, et cetera. So what we have over here, we have a main.py file. And we're actually importing another command, another file, which is called lands.py. And inside that lands.py, we're actually importing two other files to help us manage our rains and our towns. And then, those are two different files, with the rains.py file. Then we finally have two specific sub-comments, which allow us to conquer a specific rain. Or if they don't surrender during battle, just destroy it and burn it down. And similar with cities, we can actually create a new city to found it, or, once again, burn it. Very neuro-style. Not cool. It's not cool at all. But this is just a fictional example. And some people might be wondering, if this is actually possible to do with just a single file instead of multiple files to create sub-comments? And absolutely, Piper actually allow you to do that. But this might not be the best approach, because whole projects with a single file are not the greatest approach ever. And you get the risk of running into conflicts if you have more than one developer. And you also lose some interesting things, which is to use, for example, code owners from GitHub and GitLab. And about packaging and publishing, I find it interesting to cover this, in case somebody actually don't want to use the type of key. The recommended way, as I mentioned before, is by actually using poetry. And if you've never worked with poetry before, that's right, have a one-minute quick resume over here. You just create a new poetry project, and then you enter the fold of the project, add your Python package that you feel that you actually have to use. Poetry doesn't actually create a CLI for us by default. And then you just have to tell it that you open by project.toml and add just these two specific lines, which is your CLI application name over here. I call it EP 2023. And the actual path for which function you want to execute when running your CLI application. Then tell poetry to build your application, add a PyP talk, and to upload to pyp.org. And finally, tell poetry to publish to PyP. And that's about it. It's ready to be shared with anyone that you'd like. And for yourself. And to wrap it up, I'm going to quickly discuss a use case that would develop a CLI application at Azure. And if you paid attention during my self-presentation, you might have noticed that I mentioned I work as a QA quality assurance. And now some people are actually thinking, wait, it works as a QA. So why is it actually using Typer? And better yet, why is it actually using Python at all? So part of my job is mostly to develop tools to do CICD integration tests and many other quality assurance issues and tasks that come along, mostly to unblock people to help them out. And we have a project back at Azure before Typer, which is called Development Environment. This is literally the name of the project. That's why engineers don't work at marketing department because we're not great at naming stuff. And the purpose of this project is like to manage several projects together as an integration test and any other type on local development. And you can think of this as such as the ring from the Lord of the Rings, like one to handle them all. And this, in theory, sounds great. But in reality, it's slightly different. People have different results, different CPUs, different memory architectures, different lollages of Python or any other project that you want to manage. So the works on my machine is actually a real thing. We get different results with this project, depending on many different variables. And the worst part of this project, it has Docker Compose file to manage everything. But unfortunately, some of the projects, they also have a Docker Compose on themselves. So that actually makes it harder to not say almost impossible to manage everything like this. And to try to work around this, the fact that we have more than one Docker Compose file, we created years ago something that at least sounded a good idea back then, which was a make file. And let's just say it got out of hand, does not say worse things. So it become hard to maintain on the long run. And when you change something, it might get a chance of breaking things for other people. And to make things even worse, nobody is really responsible for this project. It's a collaborative approach into trying to get everything working together. And after Typer, you might have already figured out what we did. We developed a CLI with Typer, is everything that I've been working so far. We didn't deprecate the whole project right now. We're actually going to keep the Docker Compose. We're working on top of that. But the make file will actually want to deprecate it because it became really hard to maintain it. And the first thing that we actually do, we dynamically remove the depends on part. Because when we tried to start a service, we started, I don't know how many other services, one chain after the other. So lots of things were starting when you didn't request them to be started. We got the results like feedback from teams saying, I can't start this service. It takes a lot of RAM. I don't use it, et cetera. So that's something that we already started to work on top of that. We start services now individually. And we created Python profiles for each specific team. And we organized this make file into a new application, a Python application. Being split into different teams with different profiles, we're able to actually, in the future, restrain permissions using code owners from GitHub. But unfortunately, we needed extra Python package because with the make file, we already had things like Docker and Git out of the box. But we ended up needing a few extra two or three packets to do stuff. And here are the side-by-side results that I got when using Typer. I noticed that getting results with Typer is pretty quickly, like in maybe 10 minutes, something like that. You get your first application up and running very easily. It has a big focus on developer experience both for everybody who is using it or who is actually developing. Keeping your code organized is something that, compared to the make file, I found it really amazing. Restrain and permissions was a great bonus point. Type annotations is our first class citizens, as well as documentation and debugging. If you ever try to debug something with a make file, you'll probably know what I'm talking about. With Python, it's way much better. And the downsides that I noticed, you're probably unlikely going to need our Python package. You're not going to be able to change the world alone with just pure Python. And the CLI might not be the best solution for everyone. For example, if you are doing maybe computer vision or GUI development, something like that, then CLIs maybe, maybe are not for you. And here are the references. If you want to check the presentation later on, I'm going to share the slides so you can actually click on them to get more about how this presentation was made. If you have any questions, here's my contacts. You can catch me on any of these links. I'd love to hear your feedback, whether it's good or bad. Please refer to me, there's also a slack. I'm going to be around into the conference until the last day of the talks. So please reach out for me. And a big thank you for the EuroPython Commission, Society for Organizing this conference. It's pretty amazing. Thank you for staying until the end for coming and watching me. Thank you. Obrigado. Merci. Willem Denkin. Arigato. She... I can't pronounce that. Sorry. That's right. If you have any questions, feel free to ask. Thank you very much for this very inspiring talk. We have time for just a few more questions. If somebody has a question, you can step up to the microphone, which is over there. And if we... Yes, there is a question, please. Hi, Jaroslav. Thanks for your talk. Thank you very much. You mentioned that you can use it for testing APIs. So is there some... Is there a way how to integrate it, for example, into fast API or some framework, just to put the decorators on top of the fast APIs decorators? I think it's actually possible. This package was actually created by the creator of Fast API. I forgot to mention that. He considers it's the equivalent for development CLI applications. I think there is... There might be a decorator. I'm not really sure. I have to check out the documentation, something like that. But I think it might be possible. With Python code, you can do pretty much anything you like. So it's just a matter of figuring out how. Okay, thanks. And maybe the second question is there are some options how to disable it? Because if it's desired to test something, then maybe you don't wanna run it on a production. Yeah, yeah, it's probably... I think it might be possible. Once again, I have to check the documentation for that. Okay. Probably on code, I think. Not sure if the type already has something by default. Thank you very much. Thank you very much for the question. The next question, please. Hi, so if you had a CLI application already coded in ArcPars, would you transition to type or what would be the advantages of that? Mostly, I believe that with Typer, you probably have less code and more of your own code. With ArcPars, the code for ArcPars is actually gonna be injected in the middle of your application, more like even maybe some disperse and you're probably gonna have a lot of code. With Typer, I believe, mostly you're gonna need the decorators itself because they're not actually at least in the middle of your code. And it might be possible also to achieve some results that with ArcPars might be slightly more complicated. For example, splitting the CLI application to multiple files. At least I think it is actually harder in ArcPars. Thank you. Thank you for your questions. Okay, if there's no more questions, then let's have another round of applause for the issues. Thanks for the talk.