+++ title = "A Python Environment Setup" author = ["Elia el Lazkani"] date = 2021-06-17 tags = ["python", "pipx", "pyenv", "virtual-environment", "virtualfish"] categories = ["misc"] draft = false +++ I've been told that `python` package management is bad. I have seen some really bad practices online, asking you to run commands here and there without an understanding of the bigger picture, what they do and sometimes with escalated privileges. Along the years, I have compiled a list of practices I follow, and a list of tools I use. I hope to be able to share some of the knowledge I've acquired and show you a different way of doing things. You might learn about a new tool, or a new use for a tool. Come along for the ride ! ## Python {#python} As most know, [Python](https://www.python.org/) is an interpreted programming language. I am not going to go into the details of the language in this post, I will only talk about management. If you want to develop in Python, you need to install libraries. You can find _some_ in your package manager but let's face it `pip` is your way. The majority of _Linux_ distributions will have Python installed as a lot of system packages now rely on it, even some package managers. Okay, this is the last time I actually use the system's Python. What ? Why ? You ask ! ## pyenv {#pyenv} I introduce you to [pyenv](https://github.com/pyenv/pyenv). Pyenv is a Python version management tool, it allows you to install and manage different versions of Python as a _user_. Beautiful, music to my ears. Let's get it from the package manager, this is a great use of the package manager if it offers an up to date version of the package. ```bash sudo pacman -S pyenv ``` If you're not using an _Archlinux_ based distribution follow the instructions on their [webpage](https://github.com/pyenv/pyenv#installation). Alright ! Now that we've got ourselves pyenv, let's configure it real quickly. Following the docs, I created `~/.config/fish/config.d/pyenv.fish` and in it I put the following. ```fish # Add pyenv executable to PATH by running # the following interactively: set -Ux PYENV_ROOT $HOME/.pyenv set -U fish_user_paths $PYENV_ROOT/bin $fish_user_paths # Load pyenv automatically by appending # the following to ~/.config/fish/config.fish: status is-login; and pyenv init --path | source ``` Open a new shell and you're all ready to continue along, you're all locked, loaded and ready to go! ### Setup the environment {#setup-the-environment} This is the first building block of my environment. We first start by querying for Python versions available for us. ```bash pyenv install --list ``` Then, we install the latest Python version. Yes, even if it's an upgrade, I'll handle the upgrade, as well, as we go along. Set everything up to use the new installed version. First, we set the global Python version for our _user_. ```bash pyenv global 3.9.5 ``` Then, we switch our current shell's Python version, instead of opening a new shell. ```bash pyenv shell 3.9.5 ``` That was easy. We test that everything works as expected by checking the version. ```bash pyenv version ``` Now, if you do a `which` on the `python` executable, you will find that it is in the `pyenv` shims' directory. ### Upgrade {#upgrade} In the **future**, the upgrade path is exactly the same as the setup path shown above. You query for the list of Python versions available, choose the latest and move on from there. Very easy, very simple. ## pip {#pip} [pip](https://pypi.org/project/pip/) is the package installer for Python. At this stage, you have to understand that you are using a Python version installed by _pyenv_ as your _user_. The pip provided, if you do a `which`, is also in the same shims directory. Using `pip` at this stage as a _user_ is better than running it as _root_ but it is also not touching your system; just your user. We can do **one** better. I'm going to use `pip` as a _user_ once ! I know, you will have a lot of questions at this point as to why. You will see, patience is a virtue. ## pipx {#pipx} Meet [pipx](https://github.com/pypa/pipx), this tool is the **amazing** companion for a _DevOps_, and _developer_ alike. Why ? You would ask. It, basically, creates Python _virtual environments_ for packages you want to have access to _globally_. For example, I'd like to have access to a Python **LSP** server on the go. This way my text editor has access to it too and, of course, can make use of it freely. Anyway, let's cut this short and show you. You will understand better. Let's use the only `pip` command as a _user_ to install `pipx`. ```bash pip install --user pipx ```
warning
You are setting yourself up for a **world of hurt** if you use `sudo` with `pip` or run it as `root`. **ONLY** run commands as `root` or with escalated privileges when you know what you're doing.