Objective
In this unit, you'll learn how to manage Python projects, dependencies, and virtual environments using Poetry. By the end of this unit, you'll understand how to create a project, add dependencies, and build and publish packages.
Introduction to Dependency Management
Dependency management is the process of handling the libraries and packages that your code relies on. It ensures that the correct versions of these dependencies are used and that they are compatible with each other.
Poetry is a popular tool for managing dependencies in Python projects. It simplifies the process of adding, updating, and removing dependencies, and it helps maintain a consistent environment across different stages of development.
Installing and Configuring Poetry
Installing Poetry
To get started with Poetry, you'll need to install it. You can do this by running the following command:
curl -sSL https://install.python-poetry.org | python -
Configuring Poetry Settings
Once installed, you can configure Poetry settings, such as the default Python
version or the location of virtual environments, using the poetry config
command. For example, to set the default Python version, you can run:
poetry config virtualenvs.python /usr/bin/python3
Understanding the pyproject.toml
File
The pyproject.toml
file is a central configuration file used by Poetry to
manage the project's settings and dependencies. Here's a brief overview of its
main sections:
-
[tool.poetry]
: This section contains metadata about the project, such as the name, version, description, authors, and more. -
[tool.poetry.dependencies]
: This section lists the project's dependencies. You can specify the required packages and their versions here. -
[tool.poetry.dev-dependencies]
: This section lists the development dependencies, which are only needed for development and testing. -
[build-system]
: This section defines the build system used by the project, typically specifying Poetry itself.
Here's an example of what a pyproject.toml
file might look like:
[tool.poetry]
name = "my_project"
version = "0.1.0"
description = "A simple project"
authors = ["Your Name <youremail@example.com>"]
[tool.poetry.dependencies]
python = "^3.10"
requests = "^2.25"
[tool.poetry.dev-dependencies]
pytest = "^6.2"
[build-system]
requires = ["poetry-core>=1.0.0"]
build-backend = "poetry.core.masonry.api"
This file is automatically created when you initialize a new project with
Poetry, and you can modify it manually or use Poetry commands like
poetry add
to update the dependencies.
Understanding the pyproject.toml
file is key to working with Poetry, as
it provides a clear and concise way to manage your project's configuration
and dependencies.
Creating a New Project with Poetry
Initializing a New Project
Creating a new project with Poetry is a straightforward process. You can use
the poetry new
command followed by the name of your project to create a new
directory with the necessary structure:
poetry new my_project
This command will create a new directory called my_project
with the following
structure:
my_project/
├── pyproject.toml
├── README.md
├── my_project/
│ └── __init__.py
└── tests/
└── __init__.py
The pyproject.toml
file is automatically generated and contains the basic
configuration and dependencies for your project.
Adding and Managing Dependencies
Once your project is initialized, you can add dependencies using the
poetry add
command. For example, to add the requests
library, you can run:
cd my_project
poetry add requests
This command will update the pyproject.toml
file and the poetry.lock
file.
This file locks the versions of your dependencies, ensuring that every user of
your project gets the same versions of the dependencies.
The
poetry.lock
file is crucial for maintaining consistency across different environments. It ensures that the exact versions of the dependencies are used every time the project is built, preventing unexpected changes or conflicts.
You can also specify development dependencies using the --dev
flag. These are
dependencies that are only needed during development and testing:
poetry add pytest --dev
If you want to update a specific package or all packages to their latest
versions, you can use the poetry update
command:
-
To update a specific package:
poetry update requests
-
To update all packages:
poetry update
This command will update the specified packages to their latest versions,
considering the constraints defined in pyproject.toml
, and update
the poetry.lock
file accordingly.
If you no longer need a dependency, you can remove it using the
poetry remove
command:
poetry remove requests
This command will remove the requests
package from your project and update
both the pyproject.toml
and poetry.lock
files.
Managing the Project
Poetry provides several other commands to help you manage your project:
poetry install
: Installs the project's dependencies as specified in thepoetry.lock
file.poetry build
: Builds the project package.poetry publish
: Publishes the package to a package repository like PyPI.poetry run
: Executes commands in the virtual environment where the project's dependencies are installed.
By utilizing these commands, you can efficiently manage your project, ensuring that it has the correct dependencies, and build and distribute it as needed.
Semantic Versioning
When specifying dependencies, it's a good practice to use semantic versioning. This allows you to define a range of acceptable versions, giving you flexibility while maintaining compatibility.
Semantic versioning is a versioning scheme that follows a specific format:
MAJOR.MINOR.PATCH
. Each part has a specific meaning:
MAJOR
: Indicates incompatible changes that require user intervention.MINOR
: Adds new features in a backward-compatible manner.PATCH
: Includes backward-compatible bug fixes.
When specifying dependencies in Poetry, you can use semantic versioning to define a range of acceptable versions. This allows you to benefit from updates without risking compatibility issues.
Here's how you can use semantic versioning in Poetry:
-
Caret Requirements (
^
): This allows updates that do not modify the left-most non-zero digit. For example,^2.3.4
allows versions up to3.0.0
, but not including3.0.0
.[dependencies] requests = "^2.25"
-
Tilde Requirements (
~
): This allows updates that do not modify the specified digits. For example,~2.3.4
allows versions up to2.4.0
, but not including2.4.0
.[dependencies] flask = "~1.1.2"
-
Exact Version: You can specify an exact version if you want to lock the dependency to a specific release.
[dependencies] numpy = "1.20.0"
-
Wildcard Requirements (
*
): While it's possible to use a wildcard to accept any version, this is generally discouraged as it can lead to unexpected updates that might break your project.
Using semantic versioning in your pyproject.toml
file provides flexibility
in receiving updates while maintaining control over compatibility. It helps
ensure that your project stays up to date with the latest features and fixes
without risking unexpected behavior due to incompatible changes. By
understanding and utilizing semantic versioning, you can create a more robust
and maintainable project.
Working with Virtual Environments
Virtual environments are isolated environments where you can install dependencies without affecting other projects or the system's Python installation. Poetry automatically manages virtual environments for your projects, making it easier to handle dependencies and ensure that your project has exactly what it needs.
Understanding Virtual Environments
A virtual environment is like a self-contained Python installation. It allows you to install packages and dependencies that are isolated from the global Python environment. This isolation ensures that different projects on the same system do not interfere with each other, providing a consistent and controlled development environment.
Creating and Managing Virtual Environments with Poetry
When you create a new project with Poetry or add dependencies to an existing project, Poetry automatically creates a virtual environment for that project. You don't have to worry about creating or activating the virtual environment manually; Poetry takes care of it for you.
You can check the details of the virtual environment associated with your project by running:
poetry env info
This command will display information about the virtual environment, including the path and the Python version being used.
Activating and Deactivating Virtual Environments
While Poetry automatically handles the activation of virtual environments when
running commands like poetry run
, you may want to activate the virtual
environment manually to run Python scripts or other commands within that
environment.
To activate the virtual environment, you can use:
poetry shell
This command will start a new shell session with the virtual environment activated. You'll notice that your command prompt changes to include the name of the virtual environment.
To deactivate the virtual environment and return to your global Python
environment, simply exit the shell session by typing exit
.
Managing Multiple Virtual Environments
Poetry also allows you to manage multiple virtual environments for different Python versions or different sets of dependencies. You can list all virtual environments associated with a project by running:
poetry env list
And you can remove a virtual environment with:
poetry env remove python-version
Replace python-version
with the specific Python version of the virtual
environment you want to remove.
Working with virtual environments is an essential aspect of Python development, and Poetry makes this process seamless and straightforward. By automatically handling the creation and management of virtual environments, Poetry allows you to focus on your code without worrying about dependency conflicts or system-wide settings. Whether you're working on a single project or juggling multiple projects with different requirements, Poetry's virtual environment management provides a robust and flexible solution.
Poetry Best Practices
Poetry is a powerful tool for managing Python projects, and following best practices can help you make the most of it. Here are some guidelines to effectively use Poetry:
1. Keep Dependencies Up to Date
Regularly update your dependencies to benefit from bug fixes, performance
improvements, and new features. Use the poetry update
command to update
specific packages or all packages. In addition, periodically review your
project's dependencies and remove any that are no longer needed.
This helps keep your project clean and reduces potential security risks.
2. Lock Dependencies with poetry.lock
Always commit the poetry.lock
file to your version control system. This
ensures that everyone working on the project uses the same versions of
the dependencies, leading to consistent behavior across different environments.
3. Manage Development Dependencies Separately
If you have dependencies that are only needed during development (e.g., testing
frameworks), add them as development dependencies using the --dev
flag:
poetry add --dev pytest
4. Utilize Virtual Environments
Use Poetry's virtual environments to isolate your project's dependencies from the global Python environment. This helps prevent conflicts between different projects and makes it easier to manage dependencies.
5. Avoid Wildcard Dependencies
Avoid using wildcard (*) dependencies, as they can lead to unexpected updates that might break your project. Instead, specify a version range that you know is compatible with your project.
Project: Create a Poetry Project for Displaying Random Quotes
In this project, you'll create a Poetry project named random_quote
that
displays random quotes using the Turtle graphics library and the requests
library to fetch quotes from an API.
Step 1: Create a New Project with Poetry
Navigate to where you want the project directory to reside and then run:
poetry new random_quote
This will create a directory structure that should look like:
random_quote/
├── pyproject.toml
├── README.md
├── random_quote/
│ └── __init__.py
└── tests/
└── __init__.py
Change your current directory to the random_quote
folder. This directory
that contains the pyproject.toml
file is considered your top level
project directory.
Step 2: Add Dependencies
Next, add the requests
library as a dependency:
poetry add requests
Step 3: Create the Python Script
The random_quote
directory inside your root project folder is where all your
program source code will reside. Navigate into that folder and create a new
Python file named main.py
that contains the following code:
import turtle
import requests
def main():
# Make a GET request to the dummyJSON endpoint and parse out the quote and author
response = requests.get('https://dummyjson.com/quotes/random')
data = response.json()
quote = data['quote']
author = data['author']
# Create a new turtle screen and set its background color
screen = turtle.Screen()
screen.bgcolor("lightyellow")
# Initialize a turtle object
t = turtle.Turtle()
t.hideturtle()
# Position the turtle and display the quote
t.penup()
t.goto(0, 50) # Position the quote
t.write(quote, align="center", font=("Arial", 16, "italic"))
# Position the turtle and display the author
t.goto(0, -50) # Position the author
t.write(f"- {author}", align="center", font=("Arial", 14, "bold"))
# Wait until the window is closed
turtle.done()
if __name__ == '__main__':
main()
At this point, your directory structure should look like the following:
random_quote/
├── pyproject.toml
├── README.md
├── random_quote/
│ └── __init__.py
│ └── main.py
└── tests/
└── __init__.py
Step 4: Configure the Project to Run with Poetry
Back in the root project folder, open the pyproject.toml
file and add
a [tool.poetry.scripts]
section to define a custom script that runs your
program:
[tool.poetry.scripts]
random_quote = 'random_quote.main:main'
The value 'random_quote.main:main'
is used to define the entry point for
the script. Here's what each part means:
-
random_quote
: This refers to the top-level package or directory containing your Python code. In your directory structure,random_quote
is the name of the folder containing themain.py
file. -
.main
: This part refers to the specific Python module (file) within the package where the entry point function is defined. In this case, it's themain.py
file. -
:main
: After the colon:
, you specify the name of the function that will be called when the script is run. In this case, it's themain
function within themain.py
file.
So, the full value 'random_quote.main:main'
tells Poetry to look inside
the random_quote
package, find the main.py
module, and call the main
function within that module when the script is run.
Step 5: Build and Test the Project
Build your project:
poetry install
Run your project using Poetry:
poetry run random_quote
This command will execute the random_quote
script, displaying a
random quote on the screen.
In this unit, you've gained some experience managing Python projects with Poetry, handling dependencies and working with virtual environments. These skills are essential for modern Python development and will help you create robust and maintainable code.
In the next unit, we'll shift back to the Turtle graphics library and explore some of its advanced functionality that will help us build our game in the final unit.