Python

Stop Copying Requirements: Use Poetry for Python Projects

Poetry replaces pip, virtualenv, and requirements.txt with one tool that handles dependency resolution, virtual environments, and lock files. Learn how to start a project, add dependencies safely, and avoid version conflicts.

July 2026 8 min read 10 views 0 hearts

Stop Copying Requirements.txt Files By Hand: Use Poetry Instead

You've been there. You start a new Python project, install a few packages with pip, then scramble to remember which ones you actually used. Later, someone else tries to run your code and gets a cryptic error because the versions don't match. Or worse—you deploy to production and something breaks because your local environment had a different package version hidden somewhere.

This is the mess that Poetry cleans up in about five minutes. And once you try it, you'll wonder why you ever did it the old way.

What Actually Is Poetry?

Poetry isn't just another package manager. It handles three things that pip alone does poorly:

  1. Dependency resolution – figuring out which versions of packages work together without conflicts
  2. Virtual environments – keeping projects isolated so they don't fight each other
  3. Lock files – ensuring everyone gets exactly the same versions

Think of it as pip + virtualenv + requirements.txt all wrapped into one tool that actually talks to each other.

Getting Started (Takes 30 Seconds)

First, install Poetry. On most systems it's a one-liner:

curl -sSL https://install.python-poetry.org | python3 -

Or on Windows with PowerShell:

(Invoke-WebRequest -Uri https://install.python-poetry.org -UseBasicParsing).Content | python -

Check it worked:

poetry --version

That's it. No separate virtualenv creation. No activating environments manually.

Starting a New Project

Instead of mkdir myproject && cd myproject && pip install flask, you do:

poetry new myapp
cd myapp

Look at what it created. You'll see a pyproject.toml file—this is the single source of truth for your project. Open it and you'll find:

[tool.poetry]
name = "myapp"
version = "0.1.0"
description = ""
authors = ["Your Name <you@example.com>"]

[tool.poetry.dependencies]
python = "^3.9"

[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"

That's clean. No scattered requirements files. No setup.py with boilerplate.

Adding Dependencies (The Real Magic)

Here's where Poetry shines. To add Flask:

poetry add flask

Watch what happens. Poetry: 1. Creates a virtual environment automatically if one doesn't exist 2. Fetches Flask and all its dependencies 3. Figures out which versions work together without conflicts 4. Updates pyproject.toml with the new dependency 5. Creates a poetry.lock file with exact version pins

You don't think about venvs. You don't think about version conflicts. You just tell it what you want.

Try adding something that conflicts:

poetry add "flask==1.0.0"

Poetry will tell you immediately that it can't resolve the dependency tree. Compare that to pip, which will happily install conflicting packages and let you discover the problem at runtime.

When Someone Else Runs Your Code

Here's the real test. You clone a project that uses Poetry:

git clone https://github.com/PythonSkillset/some-project.git
cd some-project
poetry install

That single command: - Creates a virtual environment - Installs every dependency at the exact version in the lock file - Sets up your project in editable mode (so changes to your code are reflected immediately)

No pip install -r requirements.txt followed by pip install -r requirements-dev.txt followed by wondering why it's still broken.

Splitting Dev and Production Dependencies

Your production app needs Flask and SQLAlchemy. Your development setup needs pytest and black. Poetry handles this cleanly:

poetry add --group dev pytest black

Now your pyproject.toml has:

[tool.poetry.group.dev.dependencies]
pytest = "^7.0"
black = "^23.0"

When someone does poetry install --only main, they get just production dependencies. When they do poetry install (without the flag), they get everything. Simple.

Updating Dependencies Safely

Pip's update behavior is chaotic. Poetry gives you control:

# See what's outdated
poetry show --outdated

# Update a specific package within version constraints
poetry update flask

# Update everything within constraints
poetry update

# Update to the latest version even if it breaks constraints
poetry add flask@latest

And because Poetry updates both pyproject.toml and poetry.lock together, you can always see exactly what changed and why.

The Tool That Makes CI/CD Easier

When you're deploying to production or running tests in CI, Poetry integrates beautifully:

# Example GitHub Actions workflow
- name: Install dependencies
  run: |
    pip install poetry
    poetry install --no-dev

That --no-dev flag is crucial. Your production server doesn't need pytest. Poetry respects that.

Common Gotchas (And How to Avoid Them)

Poetry creates its own virtual environment. If you activate a separate venv first, things get confusing. Either let Poetry manage it entirely, or tell it where to put things with poetry config virtualenvs.path.

The lock file belongs in version control. Always commit poetry.lock. It's the contract that says "this specific set of versions works together."

Poetry isn't pip. Don't try to use both in the same project. If you have an existing project, use poetry init to migrate, then remove your old requirements files.

When You Might Not Need Poetry

Small projects with one or two dependencies? Pip works fine. But anything you plan to share, deploy, or maintain for more than a week—Poetry saves you from headaches that only appear later.

The PythonSkillset team has been using Poetry for internal tools and client projects for over a year now. The number of "it works on my machine" tickets has dropped to nearly zero. That alone made it worth the switch.

Give it a try on your next project. You'll spend five minutes learning the basics and save hours tracking down version mismatches later.

Comments

Questions, corrections, and tips stay visible for everyone reading this page.

0 in thread

Join the discussion

Shown next to your comment.

Up to 4,000 characters

No comments yet

Be the first to leave a note — it helps the next reader.