Python Poetry: A Complete Guide for Users and Creators
Poetry is a modern dependency management and packaging tool for Python that simplifies project setup, dependency management, and distribution. This guide covers Poetry from two perspectives: as a user working with existing projects, and as a creator building new ones.
Table of Contents
Quick Start: For Users
If you’re contributing to an existing Poetry project, follow these steps to get started quickly.
1. Install Poetry
First, install Poetry on your system:
1
2
| curl -sSL https://install.python-poetry.org | python3 -
poetry --version
|
2. Clone and Setup the Project
1
2
3
4
5
6
7
8
9
| # Clone the repository
git clone <repository-url>
cd project
# Configure Poetry to create virtual environment in project directory
poetry config virtualenvs.in-project true
# Install all dependencies from poetry.lock
poetry install
|
That’s it! Poetry will:
- Read the
pyproject.toml and poetry.lock files - Create a virtual environment (
.venv/) - Install all dependencies with exact versions
3. Working with the Project
run commands directly:
1
2
3
| poetry run python main.py
poetry run pytest
poetry run python -m mypackage.main
|
4. Managing Dependencies
View installed packages:
1
2
3
| poetry show # List all packages
poetry show --tree # Show dependency tree
poetry show requests # Show details for specific package
|
Update dependencies:
1
2
| poetry update # Update all packages
poetry update requests # Update specific package
|
5. Common User Commands
1
2
3
4
| poetry env info # Show environment information
poetry env list # List all virtual environments
poetry lock # Update poetry.lock without installing
poetry check # Validate pyproject.toml
|
Complete Guide: For Creators
Creating a new project with Poetry requires more initial setup, but provides better long-term project management.
Prerequisites
Before creating a Poetry project, set up your Python environment properly.
1. Install System Dependencies
Install build dependencies for Python:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
| sudo apt update
sudo apt install -y \
build-essential \
libssl-dev \
zlib1g-dev \
libbz2-dev \
libreadline-dev \
libsqlite3-dev \
libffi-dev \
liblzma-dev \
xz-utils \
tk-dev \
libncursesw5-dev \
libgdbm-dev \
libnss3-dev \
uuid-dev
|
2. Install pyenv
pyenv allows you to manage multiple Python versions:
1
| curl https://pyenv.run | bash
|
Important: Add pyenv to your shell:
1
2
3
4
| # Add to ~/.bashrc or ~/.zshrc
export PYENV_ROOT="$HOME/.pyenv"
export PATH="$PYENV_ROOT/bin:$PATH"
eval "$(pyenv init -)"
|
Then reload your shell:
3. Install Python Version
1
2
| pyenv install 3.10.5
pyenv versions # List installed versions
|
Note: Poetry requires Python >= 3.9. Use pyenv to install a compatible version if needed.
Installing Poetry
Ensure you’re using system Python before installing Poetry:
1
2
3
| pyenv shell --unset
pyenv global system
poetry --version
|
If Poetry isn’t installed:
1
2
| curl -sSL https://install.python-poetry.org | python3 -
poetry --version
|
Configuring Poetry
Configure Poetry to create virtual environments in your project directory:
1
| poetry config virtualenvs.in-project true
|
This creates .venv/ folders in each project, making them easier to manage and exclude from version control.
Creating a New Project
Poetry offers two ways to start a project:
Option 1: Initialize in Existing Directory
1
2
3
| cd ~/my_project
pyenv local 3.10.5 # Set Python version for this project
poetry init # Interactive setup wizard
|
The poetry init command will ask you:
- Project name
- Version
- Description
- Author
- License
- Compatible Python versions
- Dependencies to add
Option 2: Create New Project with Structure
Poetry can scaffold a complete project structure:
1
2
3
4
5
6
| # Update Poetry first
poetry self update
# Create new project
cd ~/repos
poetry new --src my_project --name my_package
|
Key Options:
--src: Creates a src/ directory layout (recommended for packaging)--name my_package: Names the package differently from the project directory
Generated structure:
1
2
3
4
5
6
7
8
9
| my_project/
├── pyproject.toml
├── README.rst
├── src/
│ └── my_package/
│ └── __init__.py
└── tests/
├── __init__.py
└── test_my_package.py
|
Configuring Your Project
1. Set Python Version
Tell Poetry which Python version to use:
1
2
3
| cd my_project
pyenv local 3.10.5
poetry env use $(pyenv which python)
|
If you used --src, add this to pyproject.toml:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| [tool.poetry]
name = "my_package"
version = "0.1.0"
description = "My awesome package"
authors = ["Your Name <you@example.com>"]
packages = [
{ include = "my_package", from = "src" }
]
[tool.poetry.dependencies]
python = "^3.10"
[tool.poetry.group.dev.dependencies]
pytest = "^7.0"
|
3. Install Dependencies
This creates the virtual environment and installs dependencies.
Managing Dependencies
Adding Packages
1
2
3
4
5
6
7
8
| # Production dependency
poetry add requests
poetry add numpy==1.26.4 # Specific version
poetry add "django>=4.0,<5.0" # Version range
# Development dependency
poetry add --group dev pytest
poetry add --group dev black mypy ruff
|
Removing Packages
1
2
| poetry remove requests
poetry remove --group dev pytest
|
Organizing Dependencies
Use dependency groups for different purposes:
1
2
3
4
5
6
| [tool.poetry.group.dev.dependencies]
pytest = "^7.0"
black = "^23.0"
[tool.poetry.group.docs.dependencies]
sphinx = "^5.0"
|
Install specific groups:
1
2
| poetry install --with docs
poetry install --without dev
|
Running Your Project
Example Project Structure
Let’s create a simple example:
1
2
3
4
5
6
7
8
9
10
11
12
13
| # src/my_package/__init__.py
__version__ = "0.1.0"
# src/my_package/main.py
import numpy as np
def main():
arr = np.array([1, 2, 3])
print(f"Array: {arr}")
print(f"Mean: {arr.mean()}")
if __name__ == "__main__":
main()
|
Running the Code
1
2
3
4
5
6
7
8
| # Activate environment
poetry shell
# Run as module
python -m my_package.main
# Or run directly without activation
poetry run python -m my_package.main
|
Example output:
1
2
3
4
5
6
7
8
9
10
11
12
| $ poetry add numpy==1.26.4
Updating dependencies
Resolving dependencies... (0.5s)
Package operations: 1 install, 0 updates, 0 removals
- Installing numpy (1.26.4)
Writing lock file
$ poetry run python -m my_package.main
Array: [1 2 3]
Mean: 2.0
|
Building and Publishing
Build Your Package
This creates distribution files in dist/:
my_package-0.1.0-py3-none-any.whl (wheel)my_package-0.1.0.tar.gz (source distribution)
Publish to PyPI
1
2
3
4
5
| # Configure PyPI credentials (once)
poetry config pypi-token.pypi your-api-token
# Publish
poetry publish
|
Or build and publish together:
Common Workflows
Workflow 1: Daily Development
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| # Start your session
cd my_project
poetry shell
# Make changes to code...
# Run tests
pytest
# Format code
black .
# Run your application
python -m my_package.main
|
Workflow 2: Adding a New Feature
1
2
3
4
5
6
7
8
9
10
11
12
| # Install new dependency
poetry add rich
# Update code to use it
# ...
# Test locally
poetry run pytest
# Commit changes (including poetry.lock)
git add pyproject.toml poetry.lock
git commit -m "Add rich for better output"
|
Workflow 3: Updating Dependencies
1
2
3
4
5
6
7
8
9
10
11
12
| # Check for outdated packages
poetry show --outdated
# Update specific package
poetry update requests
# Update all packages
poetry update
# Commit the updated lock file
git add poetry.lock
git commit -m "Update dependencies"
|
Workflow 4: Exporting Requirements
For compatibility with non-Poetry tools:
1
2
3
4
5
6
7
8
| # Export production dependencies
poetry export -f requirements.txt --output requirements.txt
# Export with dev dependencies
poetry export -f requirements.txt --output requirements.txt --with dev
# Without hashes (cleaner file)
poetry export -f requirements.txt --output requirements.txt --without-hashes
|
Best Practices
For Users and Creators
- Always commit
poetry.lock- Ensures everyone uses identical dependency versions
- Prevents “works on my machine” issues
- Use
.gitignore properly.venv/
*.pyc
__pycache__/
dist/
*.egg-info/
- Keep Poetry updated
- Use dependency groups
- Separate dev, test, and docs dependencies
- Keeps production installations lean
- Pin Python versions appropriately
1
2
3
4
| [tool.poetry.dependencies]
python = "^3.10" # Allows 3.10, 3.11, 3.12, etc.
# Or be more specific
python = ">=3.10,<3.13"
|
For Creators
- Use the
src/ layout- Prevents import confusion
- Better for packaging
- Enforces proper installation
- Document your project
- Keep README.md updated
- Document development setup
- Include example usage
- Set up pre-commit hooks
1
2
| poetry add --group dev pre-commit
poetry run pre-commit install
|
- Configure your IDE
- Point VS Code/PyCharm to Poetry’s virtual environment
- Both have built-in Poetry support
- Use semantic versioning
- Follow semver.org
- Use
poetry version to bump versions1
2
3
| poetry version patch # 0.1.0 -> 0.1.1
poetry version minor # 0.1.1 -> 0.2.0
poetry version major # 0.2.0 -> 1.0.0
|
Useful Commands Reference
Environment Management
1
2
3
4
| poetry env use python3.10 # Use specific Python version
poetry env info # Show environment details
poetry env list # List all environments
poetry env remove python3.10 # Remove environment
|
Dependency Management
1
2
3
4
5
6
7
8
| poetry add package # Add dependency
poetry add --group dev package # Add dev dependency
poetry remove package # Remove dependency
poetry update # Update all dependencies
poetry update package # Update specific package
poetry show # List installed packages
poetry show --tree # Show dependency tree
poetry show --outdated # Show outdated packages
|
Project Management
1
2
3
4
5
6
7
8
| poetry init # Initialize new project
poetry install # Install dependencies
poetry install --no-dev # Install without dev dependencies
poetry install --with docs # Install with optional group
poetry lock # Update lock file
poetry check # Validate pyproject.toml
poetry build # Build distributions
poetry publish # Publish to PyPI
|
Running Code
1
2
3
| poetry run python script.py # Run Python script
poetry run pytest # Run tests
poetry shell # Activate virtual environment
|
Troubleshooting
Issue: Poetry can’t find Python version
1
2
3
4
5
| # Make sure Python is installed
pyenv versions
# Set it explicitly
poetry env use $(pyenv which python)
|
Issue: Dependencies not resolving
1
2
3
4
| # Clear cache and retry
poetry cache clear pypi --all
poetry lock --no-update
poetry install
|
Issue: Virtual environment in wrong location
1
2
3
4
5
6
7
8
9
| # Check current setting
poetry config virtualenvs.in-project
# Set it to true
poetry config virtualenvs.in-project true
# Remove old environment and recreate
poetry env remove python
poetry install
|
Conclusion
Poetry simplifies Python project management for both users and creators:
As a User:
- Quick setup:
poetry install - Consistent environments via
poetry.lock - Simple dependency updates
As a Creator:
- Professional project structure
- Easy dependency management
- Simplified packaging and publishing
- Better collaboration through locked dependencies
Whether you’re contributing to open source or building your own projects, Poetry provides the tools to manage Python dependencies effectively.
Additional Resources