Skip to content

This document is a WORK IN PROGRESS.
This is just a quick personal cheat sheet: treat its contents with caution!


Poetry

Poetry is a tool for dependency management and packaging in Python. It allows you to declare the libraries your project depends on and it will manage (install/update) them for you.

Reference(s)

Table of contents


Install

With the official installer

  • First, define a poetry home:

    $ vi $HOME/.bashrc # or ${ZDOTDIR:-${HOME}}/.zshenv or wherever
        > ...
      + >
      + > # PYTHON POETRY
      + > export POETRY_HOME="${XDG_DATA_HOME:-${HOME/.local/share}}/poetry"
      + > export PATH="$POETRY_HOME/bin:$PATH"
        > ...
    
    $ source $HOME/.bashrc # or ${ZDOTDIR:-${HOME}}/.zshenv or wherever
    

  • Then install it, without automatically modifying your path:

    $ curl -sSL https://install.python-poetry.org | python3 -
    

  • Now, make sure poetry is up to date:

    $ poetry self update
    

  • Optionally, you might want to create a virtual environment per project inside the project's root directory. If so, the virtual environment will be created and expected in a folder named .venv:

    $ poetry config virtualenvs.in-project true
    

  • If you want to uninstall poetry:

    $ curl -sSL https://install.python-poetry.org | python3 - --uninstall
    

With the package manager

# apk add poetry
# apt install poetry
# dnf install poetry

TODO

# nix-env -iA nixos.cron
# nix-env -iA nixpkgs.poetry
# pacman -S python-poetry

TODO

TODO

# zypper install python-poetry

Config

  • List the current configuration:

    $ poetry config --list
    
  • Optionally, you might want to create a virtual environment per project inside the project's root directory. If so, the virtual environment will be created and expected in a folder named .venv:

    $ poetry config virtualenvs.in-project true
    
  • Enable tab completion for bash, fish or zsh:

$ poetry completions bash >> $HOME/.bash_completion
$ poetry completions fish > ${XDG_CONFIG_HOME:-${HOME}}/.config/fish/completions/poetry.fish
$ poetry completions zsh > ${ZDOTDIR:-${HOME}}/.zfunc/_poetry
$ vi ${ZDOTDIR:-${HOME}}/.zshrc
    > ...
    >
  + > # poetry completion
  + > #
  + > # prerequisite:
  + > #   * poetry: https://python-poetry.org/docs/#zsh
  + > #
  + > fpath+=${ZDOTDIR:-${HOME}}/.zfunc
  + > autoload -Uz compinit && compinit

Tips and tricks

If you also are using direnv, then you can add the following to your ${XDG_CONFIG_HOME:-${HOME/.config}}/direnv/direnvrc:

# see https://web.archive.org/web/20220927081123/https://rgoswami.me/posts/poetry-direnv/
# see https://web.archive.org/web/20220923191900/https://github.com/direnv/direnv/wiki/Python#poetry
layout_poetry() {
  if [[ ! -f pyproject.toml ]]; then
    log_error 'No pyproject.toml found.  Use `poetry new` or `poetry init` to create one first.'
    exit 2
  fi

  local VENV=$(dirname $(poetry run which python))
  export VIRTUAL_ENV=$(echo "$VENV" | rev | cut -d'/' -f2- | rev)
  export POETRY_ACTIVE=1
  PATH_add "$VENV"
}

Now, with this configuration, in a Poetry project you just have to create an .envrc file, which only has to contain the following line:

layout_poetry

Thanks to direnv, this will load the poetry virtual environment on the fly whenever entering your Poetry project. Note that you can do the same for similar tools like venv, pyenv, pyenv-virtualenv, virtualenvwrapper, pipenv and anaconda.

See https://web.archive.org/web/20220923191900/https://github.com/direnv/direnv/wiki/Python


Use

$ poetry help

new

  • Create a new project, e.g. your-project-name:

    $ poetry new your-project-name
    

  • Optionally, pass the --src option in order to have a src folder, for your source code, at the root of your project (instead of a your-project-name folder):

    $ poetry new --src your-project-name
    

init

  • Initialize a pre-existing project:
    $ cd pre-existing-project
    $ poetry init
    

virtual environment

By default, when creating or initializing a project, poetry creates a virtual environment in $HOME/.cache/pypoetry/virtualenvs. But optionally, you can use the virtualenvs.in-project configuration variable in order to create a virtual environment inside the project's root directory. If so, the virtual environment will be created and expected in a folder named .venv:

$ poetry config virtualenvs.in-project true

  • Check your environment configuration like so:

    $ poetry env info
    

  • Recreate a virtual environment:

    • delete your virtual environment: if using the default location of your virtual environment:

      $ rm -rf $HOME/.cache/pypoetry/virtualenvs/your-project-name-abc123DE-pyx.y/
      
      if your virtual environment is located in your project:
      $ rm -rf .venv/ # if your virtual environment is located in your project
      

    • run your project in order to recreate a virtual environment: if your project has been created without a src folder (default):

      $ poetry run python your-project-name/__init__.py
      
      if your project has been created with a src folder:
      $ poetry run python src/your-project-name/__init__.py
      

add

  • Add and install a package and its sub dependencies, e.g. click:

    $ poetry add click
    

    Note: it will update the pyproject.toml file accordingly.

  • Add and install a package as development dependency, and its sub dependencies, e.g. pytest:

    $ poetry add --dev pytest
    

remove

  • Removes a package from the current list of installed packages (e.g. remove click):

    $ poetry remove click
    

  • Removes a package from the development dependencies (e.g. remove pytest):

    $ poetry remove --dev pytest
    

run

  • If your-project-name contains a file called your_module.py, and if your_module.py contains the entry point function of your program (e.g. here: a function called main()), then you can run your program after defining the following "script" in your pyproject.toml:
    $ cat pyproject.toml
      > ...
      > [tool.poetry.scripts]
      > your-script = "your-project-name.your_module:main"
      > ...
    
    $ poetry run your-script
    

Warning

Defining a poetry "script", like above, is necessary before building and/or publishing your program. Indeed, the script name will be the executable name of your program for people to run it (e.g. with the above example, by running $ your-script).

Note

You can create as many poetry scripts as you want.

  • Alternatively, you can run your program - or a part of your program - like so (for development only):
    $ poetry run python your-project-name/program_part.py
    $ poetry run python pytest # e.g. run tests
    $ poetry run python black # e.g. run code formatting
    

shell

  • Activate and exit the virtual environment:
    $ poetry shell
    $ exit
    

check

  • Check/validate the structure of the pyproject.toml file and returns a detailed report if there are any errors:
    $ poetry check
    
  • Search for packages on a remote index, e.g. search for pendulum:
    $ poetry search pendulum
    

install

  • Install a poetry project dependencies and project's package (into the virtual environment):

    $ poetry install
    

  • After installing, make sure your project runs correctly by executing the poetry script defined earlier, e.g. run the following: $ your-script (not $ poetry run your-script).

  • Remove old dependencies no longer present in the lock file (from the virtual environment):

    $ poetry install --remove-untracked
    

  • Install without development dependencies (into the virtual environment):

    $ poetry install --no-dev
    

  • Install extra dependencies, i.e. enhancing the project but not required (into the virtual environment):

    $ poetry install --extras "mysql pgsql"
    

update

  • Update the dependencies to their latest versions:
    $ poetry update
    

    Note: this is equivalent to deleting the poetry.lock file and running install again.

show

  • Show/list the dependencies as a tree:
    $ poetry show --tree
    

build

  • Package your poetry project:

    $ poetry build
    

  • Make sure your project can run (after building):

    $ python -m venv /tmp/pyenv
    $ source /tmp/pyenv/bin/activate
    $ pip install /path/to/your/poetry/project/build/your-project-name-x.y.z-py3-none-any.whl
    
    Now you just have to make sure your project runs correctly by executing the poetry script defined earlier, e.g. run the following: $ your-script (not $ poetry run your-script).

publish

  • Make sure your project runs before publishing it (see run, install and build).

  • Publish your project to PyPI

    $ poetry publish # optionally add the `--build` option to build and publish together
    

    Note: this will package and publish the library to PyPI, at the condition that you are a registered user and you have configured your credentials properly.

  • E.g. adding an API token without keyring back end:

    $ PYTHON_KEYRING_BACKEND=keyring.backends.null.Keyring poetry config pypi-token.pypi <your-token>
    

  • Publish your project to PyPI without keyring back end:

    $ PYTHON_KEYRING_BACKEND=keyring.backends.null.Keyring poetry publish
    

Troubleshooting

EnvCommandError

You might get the EnvCommandError error when switching poetry version and still using the same virtual environment (see https://github.com/python-poetry/poetry/issues/2261 and https://github.com/python-poetry/poetry/issues/2629). In this case you might have to just remove the virtual environment of the affected project, in order to let poetry build it back.

If your virtual environment is in-project, then:

$ poetry config --list | grep "virtualenvs.in-project"
    > virtualenvs.in-project = true

$ rm -rf ./.venv

OR If your virtual environment isn't in-project, then:

$ poetry config --list | grep "virtualenvs.in-project"
    > virtualenvs.in-project = false

$ poetry config --list | grep "virtualenvs.path"
    > virtualenvs.path = "{cache-dir}/virtualenvs"  # /home/user/.cache/pypoetry/virtualenvs

$ rm -rf /home/user/.cache/pypoetry/virtualenvs/virtualenv_of_your_project

Finally, just run:

$ poetry install

ModuleNotFoundError: No module named 'cleo'

Note

This kind of error probably only affect poetry before version 1.2 and its associated new installation/update system.

If you get an error like the one bellow (every time you try to use a poetry command):

$ poetry --version
    > Traceback (most recent call last):
    >   File "/Users/username/.poetry/bin/poetry", line 12, in <module>
    >     from poetry.console import main
    >   File "/Users/username/.poetry/lib/poetry/console/__init__.py", line 1, in <module>
    >     from .application import Application
    >   File "/Users/username/.poetry/lib/poetry/console/application.py", line 3, in <module>
    >     from cleo import Application as BaseApplication
    > ModuleNotFoundError: No module named 'cleo'

Then, this might be because you updated Python to a version not yet supported by poetry (see https://github.com/python-poetry/poetry/issues/3071 and https://github.com/python-poetry/poetry/issues/4846). In this case, you might want to temporarily use poetry through venv + pip:

$ cd /path/to/your/broken/poetry/project
$ python -m venv .tmpvenv
$ source ./.tmpvenv/bin/activate
$ which pip
    > /path/to/your/broken/poetry/project/.tmpvenv/bin/pip
$ pip install cleo tomlkit poetry.core requests cachecontrol cachy html5lib pkginfo virtualenv lockfile
$ poetry --version
    > Poetry version x.y.z
$ poetry install

Now poetry can by used after entering the virtual environment ($ source ./.tmpvenv/bin/activate), while the issue is fixed by poetry developers.

Note that you can leave this environment with $ deactivate.


If this cheat sheet has been useful to you, then please consider leaving a star here.