Part 1: A demonstration using Docker
In case you do not have Docker installed already
You can get free containers using play-with-docker. You can tell if you have docker installed by running docker run --rm hello-world
. You may need root access.
Start by launching a new container named poetry-ws-part-1
with the latest version of ubuntu and run a bash shell. The --rm
flag will remove the container after you exit it so it won't clutter your system.
docker run -it --name poetry-ws-part-1 ubuntu:latest bash`
You can remove the container afterwards after you've exited it with
docker container rm poetry-ws-part-1
Editing files inside a container
At this point you are now starting from a clean slate. Next steps require that you create and edit files using a terminal. A different, more comfortable approach is to attach a visualstudiocode instance to the container and treat it as a normal project. You will need the Remote Explorer
extension.
Installing pyenv
Install pyenv dependencies and other utilities.
apt update && apt install curl git vim build-essential libssl-dev zlib1g-dev \
libbz2-dev libreadline-dev libsqlite3-dev curl \
libncursesw5-dev xz-utils tk-dev libxml2-dev libxmlsec1-dev libffi-dev liblzma-dev -y
curl https://pyenv.run | bash
You will now have pyenv
installed. Let's configure it. As per the instructions, we need to add the following to our ~/.bashrc
file:
vim ~/.bashrc
Go to the end of the file and add the following:
# Load pyenv automatically by appending
# the following to
#~/.bash_profile if it exists, otherwise ~/.profile (for login shells)
# and ~/.bashrc (for interactive shells) :
export PYENV_ROOT="$HOME/.pyenv"
command -v pyenv >/dev/null || export PATH="$PYENV_ROOT/bin:$PATH"
eval "$(pyenv init -)"
Save and quit (:wq
in vim). Now we need to refresh our shell to load the new configuration:
exec "$SHELL"
Installing python with pyenv
You can now use pyenv
to install a new version of python. Let's install version 3.10.9
:
pyenv install 3.10.9
Let's make it available globally:
pyenv global 3.10.9
We can also install different versions of python and switch between them:
pyenv install 3.8.12
Installing pipx
We have now python 3.10.9 installed globally. Let's install pipx
with it:
python3 -m pip install --upgrade pip
python3 -m pip install --user pipx
python3 -m pipx ensurepath
Again, we need to refresh our shell to load the new configurations:
exec "$SHELL"
Installing poetry
Let's install poetry
with pipx
:
pipx install poetry==1.4.2 --force
And confirm it's installed with:
$ poetry --version
Poetry (version 1.4.2)
$ whereis poetry
poetry: /root/.local/bin/poetry
Configure poetry
We want to configure poetry to not create virtual environments by default:
# configure poetry
poetry config virtualenvs.create false`
poetry config virtualenvs.in-project false`
Creating a new project with poetry
We can create a new project with poetry named part-1
:
# create project
mkdir ~/part-1
cd ~/part-1
We will now create a virtual environment for this project only
pyenv virtualenv 3.10.9 poetry-ws-part-1
pyenv activate poetry-ws-part-1
pyenv rehash # refresh pyenv shims
Sourcing environment automatically
At the project level, type pyenv local poetry-ws-part-1
to tell pyenv
to source this environment every time you cd into the directory. pyenv
will do so by creating a file .python-version
at the directory. It does not need to be the name of a virtual environment, a version number e.g. 3.10.9 could also be used.
use poetry to create new project with
poetry init
The dialog will ask you a few questions. You can skip them by pressing enter or by passing --no-interaction
to the previous command. Skip the part poetry asks you about defining dependencies using the prompt. The dialog will then create a pyproject.toml
file.
Have a look at it! It should look something like this:
[tool.poetry]
name = "part-1"
version = "0.1.0"
description = ""
authors = ["You <you@mail.something>"]
readme = "README.md"
[tool.poetry.dependencies]
python = "^3.10"
[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"
Manage dependencies in your project
poetry add pandas
and remove dependencies
poetry remove pandas
Every time you add
or remove
packages with poetry, two things happen:
- the
pyproject.toml
file is updated and a new line is added under the dependencies section - a
poetry.lock
file is created or updated, containing the exact versions of the dependencies you are using and their relations.
Let's install cowsay
with poetry
:
poetry add cowsay
poetry add --group dev black
pyenv rehash # to update shims
cowsay hola # a cow should greet you, in spanish
____
| hola |
====
\
\
^__^
(oo)\_______
(__)\ )\/\
||----w |
|| ||
Go check your pyproject.toml
file again with the changes.
Writing your project as a CLI with poetry
cd ~/part-1
mkdir part-1
touch part-1/__init__.py
touch part-1/cli.py
Open part-1/cli.py
and add the following:
import cowsay
def cli():
return cowsay.cow('Hello World')
if __name__ == "__main__":
cli()
What is a CLI?
CLI stands for command line interface. It is a type of software that acts as an interface to another software, and is designed to be executed from a terminal and interact with the user through text. A common example is the git
CLI.
Confirm that your program works by running it with python part-1/cli.py
:
$ python part-1/cli.py
___________
| Hello World |
===========
\
\
^__^
(oo)\_______
(__)\ )\/\
||----w |
|| ||
We can now update our pyproject.toml
file to include a CLI entrypoint:
[tool.poetry]
name = "part-1"
version = "0.1.0"
description = "some description"
authors = ["Your Name <youremail@yopmail.com>"]
readme = "README.md"
packages = [{include = "part-1"}] # new
[tool.poetry.dependencies]
python = "^3.10"
pandas = "^2.0.0"
cowsay = "^5.0"
[tool.poetry.scripts]
part-1-cli = "part-1.cli:cli" # new
[tool.poetry.group.dev.dependencies]
black = "^23.3.0"
[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"
And now we can install our package with poetry
and run our little CLI by calling part-1-cli
:
poetry install # install package along with its CLI
pyenv rehash # refresh python shims
Try it out!
part-1-cli # launch cli