loading...
Cover image for Getting Started with Python Poetry

Getting Started with Python Poetry

bowmanjd profile image Jonathan Bowman Updated on ・3 min read

The Poetry packaging and dependency management tool is the somewhat-new hotness for creating and maintaining a Python project.

This article is an introductory tutorial (also known as "I am writing this down so I learn it better now and have somewhere to look when I forget it later").

Install Poetry

To install Poetry on Windows, launch a powershell window, then:

(iwr https://raw.githubusercontent.com/python-poetry/poetry/master/get-poetry.py -UseBasicParsing).Content | python
Enter fullscreen mode Exit fullscreen mode

Then make sure %USERPROFILE%\.poetry\bin is on your PATH variable. Search your start menu for "environment" and you should find somthing like "Edit environment variables for your account."

To do the same on Mac, Linux, etc.:

curl -sSL https://raw.githubusercontent.com/python-poetry/poetry/master/get-poetry.py | python
Enter fullscreen mode Exit fullscreen mode

Then make sure $HOME/.poetry/bin is in your PATH variable. Most likely, Poetry has already modified your ~/.profile to source $HOME/.poetry/env, but you can double-check this or configure the PATH in the way you choose.

The official Poetry docs provide further detail.

Initialize the project with poetry

Poetry can create the directory and initial structure.

poetry new --name greet --src pygreet
Enter fullscreen mode Exit fullscreen mode

This will create a directory pygreet with the package greet in a src directory.

While a variety of ways to structure your distribution package exist, I like the approach of placing Python code in a src directory. Poetry supports this with the --src flag, as shown above.

Add code

There are several decisions to be made about structuring code, and you are welcome to read my article on Python modules and packages.

For now, I am simply adding another module to the greet package, and will call it location.py. It contains the following code:

"""Send greetings."""

import arrow

def greet(tz):
    """Greet a location."""
    now = arrow.now(tz)
    friendly_time = now.format("h:mm a")
    location = tz.split("/")[-1].replace("_"," ") 
    return f"Hello, {location}! The time is {friendly_time}."
Enter fullscreen mode Exit fullscreen mode

So now the project directory looks like this:

pygreet/
├── README.rst
├── pyproject.toml
├── src
│   └── greet
│       ├── __init__.py
│       └── location.py
└── tests
    ├── __init__.py
    └── test_greet.py
Enter fullscreen mode Exit fullscreen mode

Adding dependencies

That import arrow in our code requires the date library arrow to be installed as a dependency. To do so, use poetry add:

poetry add arrow
Enter fullscreen mode Exit fullscreen mode

If you need to hunt for more packages, Poetry has a convenient search utility in poetry search, so that poetry search arrow will return a list of all PyPI packages with "arrow" in the name.

Install package and dependencies

To install the package in developer mode, along with its dependencies:

poetry install
Enter fullscreen mode Exit fullscreen mode

Using the virtual environment

The poetry run command will execute the command in the virtual environment. For instance, try the following:

[pygreet]$ poetry run python
>>> from greet.location import greet
>>> greet("Asia/Shanghai")
'Hello, Shanghai! The time is 4:05 am.'
>>>
Enter fullscreen mode Exit fullscreen mode

Executing a shell in the virtual environment (i.e. activating it) is also possible with poetry shell after which we can execute python or other commands.

[pygreet]$ poetry shell
Spawning shell within
~/.cache/pypoetry/virtualenvs/pygreet-abcd1234-py3.8
[pygreet]$ . ~/.cache/pypoetry/virtualenvs/pygreet-abcd1234-py3.8/bin/activate
(pygreet-abcd1234-py3.8) [pygreet]$ python
>>> from greet.location import greet
>>>
Enter fullscreen mode Exit fullscreen mode

And that is a great way to test the module we wrote... Uh, no. No, that's not it at all.

Write tests and use pytest with Poetry

Tests can be written while developing the project. Poetry has already partly scaffolded the initial tests by creating a tests directory and an initial test_greet.py file. Edit that file and add an additional test. Something like

from greet.location import greet

def test_greet():
    result = greet("America/New_York")
    assert "New York!" in result
Enter fullscreen mode Exit fullscreen mode

Then either run poetry run pytest or, if already in the shell launched by poetry shell, just running pytest will do.

If the tests passed, so have we. Nicely done.

Feel free to take a look at a follow-up article on building a command line tool with Poetry.

Discussion

pic
Editor guide
bowmanjd profile image
Jonathan Bowman Author

Yeah, that makes sense. Thanks for the explanation!

Collapse
bowmanjd profile image
Jonathan Bowman Author

This is great to hear! I am so curious about pyenv, too. I have used it, but haven't really found it necessary. Feel free to say more about the benefits of using pyenv with Poetry.