-
Section 1: Getting Started
-
Section 2: Core Syntax and Data Types
-
Section 3: Collections
-
39: Set Operations: Union, Intersection, Difference
-
Section 4: Control Flow
-
Section 5: Functions
-
Section 6: Turtle Graphics and Early Practice Projects
-
Section 7: Working with Files and I/O
-
Section 8: Regular Expressions
-
Section 9: Object-Oriented Python
-
Section 10: Error Handling
-
Section 11: Modules and Packages
-
Section 12: Iterators, Generators, and Functional Tools
-
Section 13: Decorators and Metaprogramming
-
Section 14: Concurrency and Parallelism
-
Section 15: Working with Dates, Times, and Numbers
-
Section 16: Standard Library Deep Dive I: Data Structures
-
Section 17: Standard Library Deep Dive II: System and Introspection
-
Section 18: Standard Library Deep Dive III: Security and Encoding
-
Section 19: Standard Library Deep Dive IV: Text and Data Utilities
-
Section 20: Networking and Web Basics
-
Section 21: Working with Databases
-
Section 22: Testing and Quality
-
Section 23: Advanced Typing
-
Section 24: Context Managers and Resource Handling
-
Section 25: Text, Unicode, and Binary Data
-
Section 26: More Functional and Iteration Tools
-
Section 27: Data Validation and Configuration
-
Section 28: Working with Images and Media
-
Section 29: Property-Based and Documentation Testing
-
Section 30: Packaging and Deployment
-
Section 31: Performance and Internals
-
Section 32: Design Patterns in Python
-
Section 33: GUI Programming
-
Section 34: Security Basics
-
Section 35: Data Structures and Algorithms
-
Section 36: Practical Projects
-
Section 37: Capstone Projects
-
Section 38: Interview and Algorithm Practice
-
Section 39: Writing Idiomatic Python
165: Introduction to Poetry for Dependency Management
A few years ago, I spent an entire Tuesday afternoon debugging a crash that only happened on my colleague's machine. We were both using a standard requirements.txt file. On my machine, the app ran perfectly. On hers, it threw a cryptic ImportError because one of our dependencies—a library we didn't even know we were using, but that another library relied on—had released a breaking update overnight. Since we hadn't pinned that "grandchild" dependency, pip just grabbed the latest version during her fresh install. We spent four hours chasing a ghost, only to realize that requirements.txt is essentially just a shopping list, not a blueprint.
That's where Poetry comes in. If you've been using pip and venv, you're used to managing your environment and your dependencies as two separate chores. Poetry merges them. It treats your project as a cohesive package, handling the virtual environment and the dependency resolution in one go. It moves us away from the fragile requirements.txt and toward a more deterministic system.
The Deterministic Power of the Lock File
The real secret sauce in Poetry is the distinction between the pyproject.toml and the poetry.lock file. In your pyproject.toml, you define your intent. You might say, "I need pandas version 2.0 or higher." This is flexible and readable. However, the poetry.lock file records the exact version of every single package installed, including the dependencies of your dependencies.
When you share your code via Git, you commit both files. When your teammate runs poetry install, Poetry doesn't look at the toml file to see what's "new"; it looks at the lock file to recreate your environment byte-for-byte. This eliminates the "it works on my machine" excuse entirely. I personally find this peace of mind worth the initial effort of installing the tool.
Managing Dependencies without the Manual Mess
Instead of manually editing a text file and then running pip install -r requirements.txt, you use Poetry's CLI to mutate your project state. For example, if you're building a tool that needs to fetch data from an API and process it into a CSV, you'd simply run:
poetry add requests pandas
Poetry does three things here: it finds versions of requests and pandas that are compatible with each other, updates your pyproject.toml, and writes the specific hashes to poetry.lock. If you need a package only for testing—like pytest—you can keep your production environment lean by using a group:
poetry add pytest --group dev
This separates your "runtime" needs from your "developer" needs, which is a lifesaver when you're deploying to a production server and don't want to waste 200MB of RAM on testing frameworks that will never be executed in the wild.
Handling the Virtual Environment Automatically
One of the most annoying parts of Python development is remembering to activate the correct .venv folder. Poetry handles this under the hood. You don't have to manually create a folder or remember where it lives. If you want to run a script using the environment Poetry managed for you, you just prefix your command with poetry run:
poetry run python main.py
Alternatively, if you prefer the traditional feel of an active shell, poetry shell will drop you into a sub-shell with the environment already activated. It's a small quality-of-life improvement, but when you're switching between five different projects a day, it removes a significant amount of mental friction.
📋 Practical Task
Exercise: Migrating a Weather Scraper to Poetry
You have a legacy script called weather_fetcher.py that relies on the requests library to pull data from an API and python-dateutil to handle timestamps. Currently, it uses a requirements.txt file. Your goal is to migrate this project to Poetry to ensure environment stability.
Requirements:
- Initialize a new Poetry project in the current directory using
poetry init(you can accept the defaults for the interactive prompts). - Add
requestsandpython-dateutilas production dependencies using the Poetry CLI. - Add
pytestas a development-only dependency. - Verify that a
poetry.lockfile has been generated. - Run the script
weather_fetcher.pyusing thepoetry runcommand.
Validation: Your project is complete when you can run poetry show and see all three packages listed with their specific locked versions.
There are no comments for now.