-
Book Overview & Buying
-
Table Of Contents
Python Automation Cookbook - Third Edition
By :
As a first step when working with Python, it is a good practice to explicitly define the working environment.
This helps you to detach from the operating system interpreter and environment and properly define the dependencies that will be used. Not doing so tends to generate chaotic scenarios. Remember, explicit is better than implicit!
Explicit is better than implicit is one of the most quoted parts of the Zen of Python. The Zen of Python is a list of general guidelines for Python programming, intended to provide clarity on what is considered Pythonic. The full Zen of Python can be invoked from the Python interpreter by calling import this.
This explicitness is especially important in two scenarios:
A common joke among developers is responding to a bug with 'it runs on my machine', meaning that it appears to work on their laptop but not on the production servers. Although a huge number of factors can produce this error, a good practice is to produce an automatically replicable environment, reducing uncertainty over what dependencies are really being used.
In Python 3 the venv module, which sets up a local virtual environment, is included as part of the standard library. (This was not the case in the previous version, where you had to install the external virtualenv package.) Using the venv module, none of the installed dependencies will be shared with the Python interpreter installed on the machine, creating an isolated environment.
In recent years a new tool has simplified the use of environments, installation of third-party modules and running them: uv. This tool is quickly being adopted by the Python community as it simplifies the work and is much quicker than the previous alternatives!
The command pip, included in Python, is used to install dependencies. When using it with an active virtual environment, it installs the required packages in it. uv simplifies the operation by managing automatically what virtual environment to use, based on the working directory, and where to install the packages.
Install uv if not already installed. The easiest way is to install it through the standard pip command:
$ pip install uv
Collecting uv
…
Installing collected packages: uv
Successfully installed uv-0.9.9
Before creating a virtual environment, check what Python binary you are calling:
$ uv run python -c "import sys; print(sys.executable)"
/usr/local/opt/[email protected]/bin/python3.14
You can create your local environment by calling uv venv:
$ uv venv
Using CPython 3.14.0 interpreter at: /usr/local/opt/[email protected]/bin/python3.14
Creating virtual environment at: .venv
Activate with: source .venv/bin/activate
You can see that now calling uv run returns the Python interpreter in your virtual environment instead of the interpreter in your system:
$ uv run python -c "import sys; print(sys.executable)"
/your/local/path/.venv/bin/python3
So far, this is a wrapper to create a virtualenv, but note that if we use uv we don't need to activate the virtual environment, we can just call it through uv run and it will run inside the environment:
$ uv run
Provide a command or script to invoke with `uv run <command>` or `uv run <script>.py`.
The following commands are available in the environment:
- python
- python3
- python3.14
See `uv run --help` for more information.
When running scripts inside uv run, it automatically uses any virtual environment in the directory. Previously you needed to manually enter the virtual environment and leave it.
It's also more explicit with the version of Python that you are using, and you can use a different version if necessary.
To force the version of Python to use, you can use the uv pin command:
$ uv python pin 3.14
Pinned `.python-version` to `3.14`
$ uv python pin
3.14
$ uv run python
Python 3.14.0 (main, Oct 7 2025, 09:34:52) [Clang 17.0.0 (clang-1700.3.19.1)] on Darwin
>>> exit()
$ "license" for more information.
If you want to use a different version of Python, uv will download it if necessary:
$ uv python pin 3.15.0a1
Updated `.python-version` from `3.14` -> `3.15a1`
$ uv run python
Python 3.15.0a1 (main, Oct 31 2025, 23:15:40) [Clang 21.1.4 ] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> exit()
The specific version is stored in a file called .python‑version
Be careful with discrepancies between the virtual environment and the Python version! If the Python version doesn't match the version on the virtual environment, it will use the pinned version. You may need to recreate the virtual environment by calling uv venv again.
To be sure that we use the Python 3.14 version, the last one fully released at the time of writing, pin it back again:
$ uv python pin 3.14
Pinned `.python-version` to `3.14`
Jaimes-iMac-24:chapter01 jaime$ uv run python -c "import sys; print(sys.executable)"
/your/local/path/.venv/bin/python3
uv simplifies the workflow by using the defined virtual environment. The virtual environment can contain its own version, third-party packages, etc.
The virtual environment contains all the Python data in the .venv directory. The best thing about it is that it can be deleted and recreated very easily, removing the fear of experimenting in a self-contained sandbox.
By default uv will use the .venv name for the subdirectory, but this can be overwritten by using the –directory argument.
Once created, the .venv works as a regular virtual environment in Python as well, and you can activate it manually, which will show it active by default with the name of the directory:
$ pwd
/your/local/path/.
$ source .venv/bin/activate
(path) $ which python
/your/local/path/.venv/bin/python3
(path) $ deactivate
$ which python3
/usr/local/bin/python3
This name can be changed with use of –prompt when creating the virtual environment.
uv is a pretty powerful tool and we have barely scratched the surface. The most important use case throughout the book will be to install third-party packages, as we will see in the next recipe, but take a look at the full documentation at https://docs.astral.sh/uv/ for others.
uv has an important use case for defining complex projects and handling dependencies, build packages, etc. While this is pretty powerful, it can only be confusing for the automation projects that are the focus of this book as it can be, frankly, a bit too much of an overhead. My recommendation is to use uv as a tool for creating virtual environments, installing packages and running scripts, unless you have a clear power use around packaging.