Poetry is a modern dependency management and packaging tool for Python that simplifies project setup, dependency resolution, and package distribution. It creates a smooth workflow that handles virtual environments, package installations, and project scaffolding in one cohesive toolchain.
This article will guide you through Poetry's essential features, explain its benefits over traditional tools, and demonstrate how to optimize your Python development workflow.
Prerequisites
Before exploring Poetry, ensure you have a recent version of Python installed on your system, which is Python 3.13 or higher. You should also know concepts like virtual environments and basic Python package management.
Why use Poetry?
Before diving into Poetry, let's understand why it significantly improves over traditional Python package management approaches. Here's what makes Poetry unique:
- Unified dependency management: While
pip
requires separate tools for environments and lockfiles, Poetry handles dependencies, virtual environments, and package publishing in a single tool - Deterministic builds: Poetry uses a sophisticated dependency resolver that creates lockfiles ensuring identical environments across different machines
- Project isolation: Poetry automatically manages virtual environments, eliminating the manual
venv
activation and deactivation process - Modern packaging standards: Poetry embraces
pyproject.toml
as the configuration standard, replacing outdatedsetup.py
and requirements files with a cleaner, more structured approach
Think of Poetry as an all-in-one solution that combines the functionality of pip, virtualenv, and setuptools while adding powerful features like dependency resolution and lockfile generation.
Throughout this tutorial, you'll discover how these features work together to simplify your Python workflow and make package management more reliable.
Installing Poetry
In this section, you will install Poetry on your machine.
While Poetry requires Python to work, it manages Python projects independently of your system Python. To verify you have Python installed, run:
python3 --version
You should see output similar to:
Python 3.13.2
The recommended method to install Poetry is through its official installer script:
curl -sSL https://install.python-poetry.org | python3 -
This command will download and install Poetry to ~/.local/bin
by default on Unix-based systems.
You can verify the successful installation by executing:
poetry --version
Poetry (version 2.1.1)
If the poetry
command isn't recognized, add Poetry to your PATH with:
export PATH="$HOME/.local/bin:$PATH"
This output confirms that Poetry is installed correctly and ready to use.
Getting started with Poetry
Now that Poetry is installed, let's explore its core functionality. At its foundation, Poetry is a dependency and environment manager that handles project initialization, virtual environments, and package installation through a single, intuitive interface.
Poetry provides two main ways to start a project: creating a new one from scratch, or initializing an existing directory. Let's start by creating a new project:
poetry new poetry-demo
This creates a directory named poetry-demo
. Navigate into it:
cd poetry-demo
Check the complete project structure using the tree
command:
tree
poetry-demo
├── README.md
├── pyproject.toml
├── src
│ └── poetry_demo
│ └── __init__.py
└── tests
└── __init__.py
4 directories, 4 files
The pyproject.toml
file is the heart of your project. It defines metadata, dependencies, build requirements, and other configuration options. When you create a new project, Poetry generates a file that looks similar to this:
[project]
name = "poetry-demo"
version = "0.1.0"
description = ""
authors = [
{name = "Your Name",email = "your.email@example.com"}
]
readme = "README.md"
requires-python = ">=3.13"
dependencies = [
]
[tool.poetry]
packages = [{include = "poetry_demo", from = "src"}]
[build-system]
requires = ["poetry-core>=2.0.0,<3.0.0"]
build-backend = "poetry.core.masonry.api"
Poetry automatically creates the directory structure needed for a proper Python package:
- A
README.md
file for project documentation - A package directory (with the same name as your project but using underscores instead of hyphens)
- A
tests
directory for your test files
This structure follows Python best practices, immediately preparing your project for development. Notice that Poetry assumes your package contains code in a directory with the same name as your project (but with underscores instead of hyphens) located in the root of your project.
In the following sections, you'll explore how to add dependencies to this project and manage your development environment.
Now, create a simple Python file to test your setup. Create a file named app.py
:
import requests
response = requests.get("https://python-poetry.org")
print(f"Poetry website status code: {response.status_code}")
print("Poetry makes Python dependency management elegant!")
To run this file using the Poetry-managed environment, use:
poetry run python app.py
Poetry website status code: 200
Poetry makes Python dependency management elegant!`
This workflow means you no longer need to remember to activate environments or worry about dependency conflicts. Poetry handles everything behind the scenes, ensuring a consistent and isolated development environment.
Managing dependencies with Poetry
In the previous section, you learned how to create a Poetry project and install basic dependencies. Now, let's explore how Poetry simplifies ongoing dependency management through its powerful commands and lockfile system.
Unlike traditional pip-based workflows, Poetry provides a complete suite of commands for adding, removing, and updating dependencies while maintaining consistent environments.
To add a new dependency to your project, use the add
command:
poetry add pandas
Using version ^2.2.3 for pandas
Updating dependencies
Resolving dependencies... (5.0s)
Package operations: 6 installs, 0 updates, 0 removals
- Installing six (1.17.0)
- Installing numpy (2.2.3)
- Installing pytz (2025.1)
- Installing tzdata (2025.1)
- Installing python-dateutil (2.9.0.post0)
- Installing pandas (2.2.3)
Writing lock file
This command:
- Adds
pandas
to yourpyproject.toml
file with an appropriate version constraint - Resolves all dependencies, including transitive ones
- Updates the
poetry.lock
file to ensure reproducible installations - Installs the packages into your virtual environment
Poetry easily handles complex dependency trees, resolving potential conflicts before they become problems. If you need a specific version, use:
poetry add "django>=5.1"
This ensures you get Django 5.1 or newer while maintaining compatibility with other packages in your project.
To remove packages you no longer need:
poetry remove pandas
Updating dependencies
Resolving dependencies... (0.1s)
Package operations: 0 installs, 0 updates, 5 removals
- Removing numpy (2.2.3)
- Removing pandas (2.2.3)
- Removing python-dateutil (2.9.0.post0)
- Removing pytz (2025.1)
- Removing six (1.17.0)
Writing lock file
Poetry removes the requested package and any dependencies that are no longer required, keeping your environment clean.
When you need to update dependencies to their latest compatible versions:
poetry update
This updates all packages to the latest versions allowed by the constraints in your pyproject.toml
, then regenerates the lock file.
For a more targeted update of specific packages:
poetry update pandas
One of Poetry's most powerful features is its lock file. When you clone a project with Poetry, you can guarantee identical environments across machines by simply running:
poetry install
This uses the poetry.lock
file to install the exact versions of all packages, eliminating "works on my machine" problems. If the lock file doesn't exist, Poetry will generate one based on the constraints in pyproject.toml
.
To see what packages are installed in your current environment:
poetry show
asgiref 3.8.1 ASGI specs, helper code, and adapters
django 5.1.7 A high-level Python web framework that encourages rapid development and clean, pragmatic design.
sqlparse 0.5.3 A non-validating SQL parser.
For a dependency tree that shows relationships between packages:
poetry show --tree
django 5.1.7 A high-level Python web framework that encourages rapid development and clean, pragmatic design.
├── asgiref >=3.8.1,<4
├── sqlparse >=0.3.1
└── tzdata *
This comprehensive approach to dependency management ensures your Python projects remain consistent, reproducible, and free from dependency conflicts.
Managing dependency groups in Poetry
In the previous section, we explored basic dependency management with Poetry. While adding dependencies directly to the main section is sufficient for simple projects, more complex applications benefit from organizing dependencies into groups based on their purpose.
Building on our poetry-demo
project, let's see how Poetry's dependency groups feature helps organize project dependencies more effectively.
Let's start by adding a testing framework to a dedicated development group:
poetry add --group dev pytest
Using version ^8.3.5 for pytest
Updating dependencies
Resolving dependencies... (2.2s)
Package operations: 4 installs, 0 updates, 0 removals
- Installing iniconfig (2.0.0)
- Installing packaging (24.2)
- Installing pluggy (1.5.0)
- Installing pytest (8.3.5)
Writing lock file
With this command, Poetry automatically creates a development dependency group in your pyproject.toml
:
[tool.poetry.group.dev.dependencies]
pytest = "^8.3.5"
This separation is powerful - it allows you to:
- Keep your production environment lean by installing only necessary dependencies
- Organize tools by their purpose
- Install specific groups only when needed
Let's expand the project by adding more development tools:
poetry add --group dev black mypy
Using version ^25.1.0 for black
Using version ^1.15.0 for mypy
Updating dependencies
Resolving dependencies... (3.4s)
Package operations: 7 installs, 0 updates, 0 removals
- Installing click (8.1.8)
- Installing mypy-extensions (1.0.0)
- Installing pathspec (0.12.1)
- Installing platformdirs (4.3.6)
- Installing typing-extensions (4.12.2)
- Installing black (25.1.0)
- Installing mypy (1.15.0)
Writing lock file
Now your development group includes code formatting and type checking tools:
[tool.poetry.group.dev.dependencies]
pytest = "^8.3.5"
black = "^25.1.0"
mypy = "^1.15.0"
Beyond development tools, you can create custom groups for other purposes. For example, create a documentation group:
poetry add --group docs sphinx sphinx-rtd-theme
Your pyproject.toml
now contains three distinct dependency groups:
...
[tool.poetry.group.dev.dependencies]
pytest = "^8.3.5"
black = "^25.1.0"
mypy = "^1.15.0"
[tool.poetry.group.docs.dependencies]
sphinx = "^8.2.3"
sphinx-rtd-theme = "^3.0.2"
When installing dependencies, you can choose which groups to include:
# Install all dependencies including dev and docs groups
poetry install --with dev,docs
# Install only main dependencies and dev tools, but not docs
poetry install --with dev
# Install only main dependencies, no groups
poetry install --without dev,docs
For production deployments, you typically want only the main dependencies:
poetry install --only main
This installs just pendulum
and its dependencies, resulting in a lean production environment without testing, linting, or documentation tools.
When running commands with Poetry, you can use tools from specific groups without manually activating environments:
# Run pytest from the dev group
poetry run pytest
# Run black from the dev group
poetry run black poetry_demo/
# Build documentation using sphinx from the docs group
poetry run sphinx-build docs _build
Organizing dependencies into purpose-specific groups makes your project more maintainable, with more precise separation between production dependencies and development tools.
This approach reduces installation time, prevents unnecessary packages in production, and makes it easier for contributors to understand the purpose of each dependency.
Final thoughts
This article explored how Poetry simplifies Python development by managing dependencies, virtual environments, and packaging in one intuitive tool. See the official Poetry documentation to learn more.
Poetry isn't the only modern tool available. You might also explore uv, another promising alternative for faster and simpler dependency management.
Thanks for reading!
Make your mark
Join the writer's program
Are you a developer and love writing and sharing your knowledge with the world? Join our guest writing program and get paid for writing amazing technical guides. We'll get them to the right readers that will appreciate them.
Write for us
Build on top of Better Stack
Write a script, app or project on top of Better Stack and share it with the world. Make a public repository and share it with us at our email.
community@betterstack.comor submit a pull request and help us build better products for everyone.
See the full list of amazing projects on github