Productive Python with Poetry
Tags: python, productivity, distribution, tutorial
Published: 2019-05-18 18:57:17


> This is part of a series explaining the different options for managing Python dependencies.  Make sure you've read the 
previous posts, this one will build on that information.

# TL;DR
Poetry addresses many of my complaints about the [pipenv] and [vanilla] stacks by providing a much nicer development experience.  On the downside, it's a much newer tool which is still developing some important features, and it's not backed by the [Python Package Authority (PyPA)] which has lead to some conflicts.

# Components
- [poetry]:  Used to manage dependencies, virtual environments, building, and publishing your project.
- [pyproject.toml]: Contains all your project metadata
- poetry.lock: A file used to synchronize exact versions of dependencies between environments
- [pip]: Used for some distribution cases


# Development
## TL;DR
Poetry provides by far the best developer experience of the three stacks discussed.

## Defining Requirements
- 👍 Dev Requirements: Just like Pipenv you can easily declare developer dependencies in the same file as all your other dependencies.
- 😍 Reproducibility: The most sane management of Python packages.  Poetry will install from your lock file, it only updates your dependencies when you tell it to.
- ✅ Adding new packages: This is done exactly the way it should be done.  If you do `poetry add somepackage`, it will get the latest version of somepackage and set the constraint to be compatible per [Semantic Versioning].  So if the latest version is 1.4.8, your constraint is ^1.4, meaning it can update to 1.4.9 or 1.5, but not 2.0.
- 😊 Alternative sources: Even easier than Pipenv.  Add your source to pyproject.toml and setup your credentials with `poetry config`.  Much easier than trying to get environment variables to work cross platform.

## Virtual Environments
- 😌 Setup: A breeze.  `poetry install` creates a virtual environment if one doesn't exist and is so much faster than Pipenv.  One slight tradeoff is Poetry supports multiple versions of Python for one project, which means you have to specify which version you want to use for any given point in time.  The recommendation is to use [pyenv] on -nix systems.  I've found the built in [py] launcher for Windows works fine too.
- 🙂 Usage: Pretty much the same story as Poetry, though there are some more bells and whistles.
    - Installing requirements: `poetry install`
    - Running: `poetry run python [your script]`
    - Activating the environment: `poetry shell` (also spawns a new shell)
    - Deactivating: `exit`
    
# Distribution
## TL;DR
Poetry makes *almost* everything better than Pipenv.  If you're doing source or prebuilt distribution, you'll be a little worse off.

## Build
- 🥰 Definitions: Your [pyproject.toml] which defines your dependencies also defines all the other metadata for your project!  No more setup.py.
- 😁 Building: `poetry build`.  Downside?  Only pure Python wheels are supported, no C code yet.

## Deploy
- ⚡ PyPI: `poetry publish`
- 👌‍ Source Distribution: You have to install Poetry on your server, but it has much less overhead than Pipenv so I think ti's worth it.
- 😥 Prebuilt Dependencies: The released version of Poetry has no way to do this.  My solution today is to use the Alpha version of Poetry (which I've had no issues with) and export a requirements.txt to use with [pip]

# Conclusion
Poetry is awesome!  It's still quite young (still on its way to [1.0]) but already better than the existing tools.  Given the direction it's heading, the community supporting it, and the friendly and supportive maintainer, I think it should be everyone's tool of choice for Python dependency management.

That's probably the end of this series.  There is, of course, always more to this topic, so if I missed anything or you have any questions please leave a comment below!

# Notable Mentions
Here are tools that I'm aware of but don't have enough experience with to give a full review on.  If you think one of these is worth spending time with and writing another part of this series on, please let me know.
- {% github ofek/hatch %}
- {% github dephell/dephell %}


[1.0]: https://github.com/sdispater/poetry/milestone/1
[pip]: https://pypi.org/project/pip/
[pipenv]: https://dev.to/dbanty/pipenv-the-newer-dependency-manager-23ga
[poetry]: https://poetry.eustace.io/
[py]: https://www.python.org/dev/peps/pep-0397/
[pyenv]: https://github.com/pyenv/pyenv
[pyproject.toml]: https://poetry.eustace.io/docs/pyproject/
[Python Package Authority (PyPA)]: https://www.pypa.io/en/latest/
[Semantic Versioning]: https://semver.org/
[vanilla]: https://dev.to/dbanty/vanilla-python-stack-99a