so we've done two videos so far on the UV package manager tool for python applications and this is a new tool that's gaining popularity in the python ecosystem you can find links to those videos in the comments section and in the description of the video in this video we're going to move on and we're going to look at tool management using UV and what we're going to do in this video to demonstrate this is look at integration of two packages and that's rough and Pie test so let's get started with that and we have a coffee page linked in the description if you want to support the channel thanks very much to everyone who's contributed so far now on the features page of the UV documentation and this page is linked below the video we're going to go to the section On Tools now you can run and install tools that are published to python package indexes for example the rough tool or black and UV provides some commands that you can run in order to work with those tools so for example you have the UV tool run command and that's going to run the tool in a temporary environment and there's a shortcut for that and that's the uvx command and the uvx command you can think of it as being similar to pepex so these two commands are equivalent and they give you a way to run the tool in a temporary environment now if you want to install a particular tool user wide you can run the UV tool install command along with the name of the tool that you want to install and that's going to make it available across your entire system so for example if you're always using rough for your formatting and linting you can install that using this command and it's going to make it available in all your UV environments and similarly you can uninstall and list tools as well as run the update shell command and that command will update the shell to include the tool executables now what we're going to do is go to this guide on tools now many python packages provide applications that can be used as tools and we can run the uvx command to invoke a tool without necessarily installing it so for example to run Ru we can just run the uvx ru command and as was mentioned a second ago that's exactly equivalent to running the UV tool run command along with the name of of the tool now if the tool nams arguments you can provide these after the tool name and we're going to see some examples of that as well now tools are going to be installed into temporary isolated environments when you use the uvx command now I want to look at this note here just before we move on so if you're running a tool in a project and the tool requires that your project is installed and that's going to be the case when you run the pie test command or the mypie command then you want to use the UV run command instead of uvx otherwise the tool is going to be run in a virtual environment that's going to be isolated from your project so whether you run uvx or UV run is going to depend on the structure of your project and also whether it's a project or a single script and so on now I want to actually get started now and look at the code that we had from the previous video so we had this extremely basic fast API application with a single route Handler and we were running this using UV so if you look at Pi project. Tomo we had fast API and uvicorn as dependencies in py project. Tomo and we had add at the moment a Dev dependency of rough and notice that the dev dependencies are in a table in the P project.
Tomo file called tool. UV so that's where you can declare your development dependencies what we're going to see is that using this py project. Tomo file we can actually manage some configuration for the tools that we're going to use in a project and UV will then be able to read this from a single file this one here and it's going to cut down the number of files that you need to have in your project and that can be a big benefit for configuration to consolidate that in a single place so let's get started with rough what I'm going to do is just minimize the sidebar at the moment and we're going to go to the terminal and we're going to run the uvx command here and we're going to look at this main.
Pi file so if I run uvx the name of the tool that we're going to use is Ruff so we specify the name after the command and Ru has some subcommands that we can then execute here so for example if we wanted to check the contents of main. py for any linting issues we can run the UV rough check command we pass the name of the file and that's main. pi and you can see when we run this that it's preparing the package rough it's downloading that and it's going to then execute that in the environment and you can see that all checks have passed for the rough check command so that's how we can invoke rough in a temporary environment and of course because it's a development dependency here you can see it in the tool.
UV section we can also use the UV run command and what we can run here is rough check and again we're checking a single file and that's main. p and this time it's not going to use a temporary environment it's going to use the V directory within the project and that's the virtual environment that UV sets up automatically when you start running commands so what I'm going to do just to demonstrate how to work with Ru and UV here is I'm going to turn this file into something that doesn't quite conform with some of the standards in Python applications so I'm going to copy and paste some code into the file so we're going to remove this code here and I'm going to paste this in again and you can see now that we have a file that doesn't really look very good we have Imports and we have no separation between the Imports and some of the variables and functions that we're declaring here so it's not exactly in the style that python would expect and we're also importing a module that we're not actually using here so we can use rough to detect these instances and tell us about them and then we can either go and fix them manually or for some of these Ru will provide an automatic fix so let's see that in action now I'm going to save this file and let's clear the terminal at the bottom and we're going to use uvx again and remember that's going to run in an isolated environment so you can imagine that we don't have those development dependencies with Ru in P project. Tomo so we can run the check command again and again we're going to pass main.
pi and now we get some outputs here so I'm going to make the terminal bigger so we can see this the requests module is imported but not used and the output also gives you the rule code here of f401 and that rule corresponds to an import that's not actually used in the application so what we can do is we can actually run this with D- fix in order to Res resolve this so this is something that Ruff knows how to fix so let's pass D- fix into this command and before we run this I'm going to minimize the terminal and hopefully we can see the requests import is going to be removed here and when we run that you can see that it is removed now if you want to know more about how Ru Works we've got a link to that in the description of the video what we're going to do now is we're going to extend the rule set for Ru and we can do that in the P project. Tomo file now again you can find much more information in that previous video but let's go to this Tut here and this is on the rough documentation if we go to the configuration section you can specify some rules either in a p project. toal file or if you want some rough specific configuration files there is also the option of a rough.
tomal file and what we can do here is ADD tool. Ruff or tool. ruff.
lint and that's where you can specify some of these rules for example the line length for ruff's form matter and you can also use the extend select option if you need to extend the default rule set that Ruff is going to use now what we going to do just to demonstrate this is we're going to use extend select in the ru. tool. lint table within the P project.
Tomo file so let's go to P project. Tomo and underneath tool. UV I'm going to add tool.
ruff. lint and this is going to specify the rules for the rough linter when we use that now if we go back to the documentation I'm going to copy the extend select option that we have here and let's go back here and add that under this section and actually what I'm going to do is I'm going to include a broader rule set from ru so let's go back to the documentation and if we go to the section on rules I'm going to include all rules with the prefix e and w now these come from PI code style and we have errors which is what the E stands for and warnings which is what the W stands for now examples of Errors include this one here when you don't have an indented block when one is expected for example if you define a function the body of that function should be indented and same for conditional statements like if statements and for Loops as as well now what we're going to do is go back to P project. too and to add the entire rule set we can get rid of the explicit rule code and we're just going to reference e and I'm going to add W to this as well so we're extending the rules that Ruff is going to use when we run these commands so now if we go back to the terminal and what I'm going to do is Rerun the uvx rough command we're going to check main.
py and this time we get a new issue appearing in the console and that wasn't there before what we have is no new line at the end into the file and you can see the error code of w292 and this error code comes from the rule set beginning with w that we've added here so what we've done here when we run this rough command is we've specified configuration in the P project. Tomo file and for any number of tools that we have in the project there's a good chance we can Define the configuration in py project. Tomo for all of these and that's going to remove those individual config files from our project potentially and that might be something that you want to do just to to declutter your project directory and so on so to fix this it's very easy this no new line issue that we have here we just need to add a new line manually or again when we run the check command we can pass the D- fix flag and it's going to automatically add that new line and again if you want more detail on rough check out the previous video that we did on the package now I'm going to clear the terminal and as well as a linter with the rough check command we also have a formatter so we can run the rough format command and again I'm going to pass the explicit link to the file and when we do that you can see it's reformatted the entire file according to those pep conventions so we have the Imports at the top we declare a variable here and then we have some lines between that variable and the function the Handler function in fast API so now we have reformatted the file using rough so that's one tool that we've added to the project and we've specified the config in P project.
Tomo we're now going to add P test and we're going to add a small test for this very basic fast API route Handler now in order to use P test we need to add it as a dependency so if we go back to P project. Tomo you can see at the moment we have this dependencies array and we also have Dev dependencies we've got rough in the development dependencies and we're going to add py test also to development dependencies now I'm going to clear the terminal and we can use the UV ads command and if you want to know more about that see the original video we did on UV and we're adding P test to the project and we want to pass d-d that's going to add it to P project Tomo as a development dependency so let's execute this command and you can see it's installing py test very quickly it does that it's rapid and it's also added Pi test now to the development dependencies array in the pi project. Tomo file so let's get back to main.
py this is a very simple fast API route Handler and it returns a bit of text or so it seems at least that says hello from Fast API what we're going to do in the directory is add a tests. pi file so tests. pi and this is where we're going Define these tests using p test now fast API has a few utilities for testing so I'm going to go to the documentation and fast API under the hood is going to use a framework called Starlet so a lot of the power of fast API is built on top of Starlet and Starlet provides a test client that we can use now the test client uses httpx and that's different from HTM X which I've done a lot of videos on this is httpx and that's a package that allows you to send HTTP requests and it has an API is very similar to the requests package and that's a very common package in Python to install when you're working with requests and as it says here you can use py test directly with fast API now we are going to need to install httpx as well and here's the PIP command but we are going to use UV so let's go back to vs code I'm going to go back to the terminal at the bottom here and let's clear this out and we'll press the up key to get the last command what we're going to do is also install httpx and that's going to add that to the dev dependencies in the P project.
Tomo file again you can see how fast that was and if we go back to here you can see it's been added so now that we've added that what we can do is go back here and we're going to bring this import of the test client from the fast API test client module into the tests. py file so let's paste that in there and if we look at how this is actually used you can see that we passed the application object and that's the fast API app object into the test client to get back a client variable so what we're going to have to do is import the app object from main. py it's this one here on line three so I'm going to do that at the top and it's from Main let's import the app object and then we can create a client here and we're going to invoke the test client and we're going to pass the app into that now if we go back to the documentation what we're going to see is we have a function here called test Romain and that sends a get request using this client and then it inspects the response and perform some assertions on the response object for example the status code and also the content of the response now we're going to do something similar so let's go back to our file here and we're going to define a function here called test Main and the reason we're calling it that is because we have a main function here that returns this text here hello from Fast API so what we're going to do here is we're going to use the client and we're going to get a response by calling client.
getet so we're going to send a get request just to that route and we're going to check that we get a 200 status code so we're using a py test function here we can just use the assert keyword in Python and we're going to assert that response. status code is equal to 200 we're also going to check the content of the response so if we go back to main. Pi I'm going to copy this string here and we're going to make an assertion here about what's in response.
text so let's assert that response. text is equal to that string here hello from Fast API now I'm going to save this and we're going to run this test so let me minimize the sidebar there and we're going to go back to the terminal here and what I'm going to do on the terminal is run the UV run command so it's UV run and we can run py test because it's now installed in the virtual environment so if we run py test let's see what happens here now you can see it's collected zero items it's not found any tests and the reason for that is that we haven't told P test where the test function is where the test files are or directories so py test doesn't have a clue where to look for tests so we're going to fix that in a second by adding some config to P project. Tomo but what we can do is we can actually pass our file name to the pi test command so if we pass tests.
pi and then run this you can see that it's collecting that and we actually have an assertion error here and if you look at the assertion error we can see this line here assert that hello from Fast API with the string at the front of it is not equal to this one here and this looks a bit weird but the problem here is actually that the response contains Json content it's not a text response it's a Json response what we want is actually a plain text response here so what we're going to do is fix this problem because if we look at this function here we just want to return a string we don't want this to be part of a Json response it should just be some text so what we're going to do at the top is import the response object from Fast API and then we can return a response directly here so I'm going to paste the response object there and we're going to pass a keyword argument of content and set that equal to the text content and we can also pass a media argument here and actually that should be media type and we can set that to text slpl for a plain text response so we're returning a response object we're setting the content and we're setting the media type for that response so let's save this and go back to the terminal and if we rerun this again you can see that the test has passed so that's a kind of subtle error when you return something from a fast API route Handler by default it's going to return Json so the media type for that is going to be application / Json but we've changed that here by returning a response object and setting the media type directly now what I want to ideally do here is just run P test using UV so for example when we pass the file tests. py that is now working because we're telling P test where the test functions are but when we just run P test there we're not getting any results it's not collecting any tests what we want to do is add some configuration to P project. Tomo to tell py test where our test file is now in order to do this what we're going to do is go to the documentation so I'm going to open that just now and this is the configuration page on the py test documentation now what you would normally do in a project if you're not using p project.
tomal is you would Define a py test. ini file and that takes precedence over other files even when it's empty and what you can do is Define the py test block here and add your options for when the P test command is run for example you can add this option here called test paths and that can point to directories and individual files that contain your tests now of course we're working with py project. Tomo so what you can do is add a table for your py test inii options we're going to copy this just now and let's go back to our project so underneath the rough table here we're going to add one for pest.
ini options and we're going to add some options to this now and the first one we're going to add is the test paths now if we bring back the sidebar here and we look at what we have we have a single file within this project directory called tests St Pi so we're going to add that to the array of test paths and that's all we need to add in order to find the file so if we save this now and go back to the terminal I'm going to clear this and let's rerun UV run py test remember beforehand that was not collecting any tests but it's now finding our single test and that's passing so what we've done here is just add some config for a new tool to the P project. Tomo file and that's for pest. inii options and we've added the test paths and that means that when we run the UV run py test command P test will use these options and it's going to find the file and we can add other options here as as well so for example if we wanted to run this in quiet mode we can use the add Ops key here and we're going to set that to a string and if we pass minus Q to that that's going to run it essentially in quiet mode it's going to turn down the verbosity so let's save this and if we rerun the command on the terminal at the bottom we're going to see we get a lot less output here because it's now in quiet mode so we can add any number of valid pie test options into this table here in the P project.
Tomo file and then when we run the UV run command or indeed uvx it's going to read these options from the P project. Tomo file when it actually applies the tool so that's been a very quick intro on using different tools with UV and specifying options in P project.