A straightforward working environment for Python 🚀

pyenv + poetry for minimum complexity

With pyenv, it is possible to install isolated python versions on our computers. By adding the power of poetry, we can effortlessly manage the project's dependencies. Both tools allow us to minimize the time needed to be productive and start coding ASAP. Read on to find out how to get started!


I like to write this kind of guide when I start a new project. The reason is that it can take weeks, months, or even years before I work on the same stack again, and when that happens, I have a hard time remembering how to get started. With this, I can quickly be productive again.

In this case, I explain how to start or resume a project written in Python. I mean, how to efficiently and easily manage Python versions and project dependencies.

Table of Contents

"nvm and npm for Python"

In my last project, I worked with Node.js. The tools to manage Node.js versions and project dependencies were intuitive and easy to use. Now, thanks to pyenv and poetry, it is possible to work similarly in Python.

Version management with pyenv

If I run this on my Linux machine:

for p in $(compgen -c python | grep -E '.+\..+' | grep -v -E 'con|m|gdb' | sort -u); do printf "%-16s" $p; $p --version; done

I can see I have Python 2.7.17 and Python 3.6.9. Version 2.7 is used by the OS so it is better to leave it alone. I can do my stuff with 3.6 but what if the project I'm working now requires Python 3.8.5? Thankfully we have pyenv:

pyenv lets you easily switch between multiple versions of Python. It's simple, unobtrusive, and follows the UNIX tradition of single-purpose tools that do one thing well.

Awesome, right?

Working with pyenv

  1. Get pyenv by following this guide.
  2. Install an isolated version of 3.8.5 (my case) with $ pyenv install 3.8.5. Note this version will be located in the $(pyenv root)/versions folder.
  3. Check the next image to understand how pyenv works:

How does pyenv know which version of Python to use?

If interested to know, read Bonus-01.

Dependency management with poetry

This is also a breeze:

Poetry helps you declare, manage, and install dependencies of Python projects, ensuring you have the right stack everywhere.

Let's dig in!

Installing poetry

Follow this guide (it is better to use python3 instead of the system's Python to run the installation script). The command to execute in Linux would be:

curl -sSL https://raw.githubusercontent.com/python-poetry/poetry/master/get-poetry.py | python3

Uninstalling poetry

If interested to know how to do it, read Bonus-02.

Tying it all together

Option 1: Setting up a new project

  1. Define the Python version to use and create a boilerplate for your project with: $ pyenv shell 3.8.5 && poetry new <projectName>. Notice the project's version is set to 3.8.5 in the pyproject.toml file, but if you close the terminal session or execute $ pyenv shell --unset the python version will reset to the default one. To make a permanent change for the project run $ pyenv local 3.8.5 inside the project folder.
  2. Start the virtual environment with $ poetry shell.
  3. Add your dependencies with $ poetry add <dependency>.
  4. When done, start your favorite IDE and start coding!

Instruct VSCode to use poetry's virtual environments

If interested to know how to do it, read Bonus-03.

Option 2: Work on an existing project

  1. Clone your project and go into the project folder.
  2. Define the Python version to use. In my case: $ pyenv local 3.8.5. Notice a .python-version file has been created in the project's folder.
  3. Initialize the project with $ poetry init.
  4. Start the virtual environment with $ poetry shell.
  5. If the project was already using poetry install the dependencies with $ poetry install. You can also install them from a requirements.txt file with:
    $ for item in $(cat requirements.txt); do poetry add "${item}"; done
  6. When done, start your favorite IDE and start coding!

Bonus-01: How does pyenv know which version of Python to use?

As per the documentation: pyenv determines which Python version to use by reading it from the following sources, in this order:

  1. The PYENV_VERSION environment variable (if specified). You can use the pyenv shell command to set this environment variable in your current shell session.
  2. The application-specific .python-version file in the current directory (if present). You can modify the current directory's .python-version file with the pyenv local command.
  3. The first .python-version file found (if any) by searching each parent directory, until reaching the root of your filesystem.
  4. The global $(pyenv root)/version file. You can modify this file using the pyenv global command. If the global version file is not present, pyenv assumes you want to use the "system" Python. (In other words, whatever version would run if pyenv weren't in your PATH.)

Bonus-02: Uninstalling poetry

If python3 was used in the installation process run:

$ POETRY_UNINSTALL=1 bash -c 'curl -sSL https://raw.githubusercontent.com/sdispater/poetry/master/get-poetry.py | python3'

Otherwise use just python.

Bonus-03: Instruct VSCode to use poetry's virtual environments

Pretty simple. Open or create a settings.json file in your project's .vscode folder. The content should be:

{
    "python.pythonPath": "<THE-PATH-TO-YOUR-PROJECT'S-VIRTUAL-ENV-FOLDER>"
}

Remember Poetry's virtual environments are stored in a separate folder. In Linux, the python.pythonPath value is /home/<USER>/.cache/pypoetry/virtualenvs/<PROJECT-VIRTUAL-ENV>/bin/python

Bonus-04: Don't suffer :-)


Python Environment by xkcd