Developers come across the scenario of switching between multiple versions of interpreters, simply because the project they work on requires different interpreter versions and also different bunch of libraries. In python, luckily, we can use pyenv to manage multiple interpreter versions and further create virtual environments for every projects to help us not pollute the global space.
Ubuntu Setup
Assuming we got apt package manager, let us start by installing pipx
# Install PIPX
sudo apt install -y pipx
# Add to source
sudo pipx ensurepathNext, let us install uv package manager
# Install UV
curl -LsSf https://astral.sh/uv/install.sh | sh
# Source the uv
source $HOME/.local/bin/envSwitching Python Versions
Global (system-wide default)
pyenv global 3.12.1Per-project (recommended)
cd my_project
pyenv local 3.12.1This creates:
.python-version
Commit this file to your repo.
Per-shell (temporary)
pyenv shell 3.10.13Poetry is a modern Python tool that:
- Manages project dependencies
- Creates and manages virtual environments
- Builds and publishes Python packages
- Replaces
pip,virtualenv, andsetup.pywith one unified system
Think of it as npm for Python, but opinionated and reproducible.
Why Poetry Exists (the problem it solves)
Traditional Python workflow:
pip install requests
pip freeze > requirements.txt
virtualenv venv
source venv/bin/activate
Problems:
requirements.txtdoesnโt lock versions well- Virtual environments are manual
- Packaging is confusing (
setup.py,setup.cfg,MANIFEST.in) - Reproducing environments is unreliable
Core Concepts
pyproject.toml
Poetry stores everything in one file:
[tool.poetry]
name = "my-project"
version = "0.1.0"
[tool.poetry.dependencies]
python = "^3.12"
requests = "^2.31.0"
This replaces:
- requirements.txt
- setup.py
- setup.cfg
poetry.lock
This file pins exact versions so everyone installs the same packages.
Creating a New Project
poetry new my_project
cd my_projectOr initialize in an existing folder:
poetry initInstalling Dependencies
Add a package
poetry add requestsAdd dev dependency
poetry add --group dev pytest blackRemove package
poetry remove requestsVirtual Environment Commands
Activate shell
poetry shellRun command without activating
poetry run python main.py
poetry run pytestShow environment info
poetry env infoList environments
poetry env listRemove environment
poetry env remove pythonInstalling Project Dependencies
poetry installDependency Locking
Update dependencies (respecting version ranges)
poetry updateUpdate one package
poetry update requestsPackaging & Publishing
Build package
poetry buildPublish to PyPI
poetry publishUseful Utility Commands
| Command | What it does |
|---|---|
poetry show | List installed packages |
poetry show --tree | Dependency tree |
poetry check | Validate config |
poetry config --list | Show settings |
poetry export | Convert to requirements.txt |
Common Workflow
poetry init
poetry add fastapi uvicorn
poetry shell
python main.py
Or in CI:
poetry install --no-dev
poetry run python app.pyPoetry Configuration (Advanced & Useful)
# List all configs
poetry config --list
They can be:
- global (default)
- local (
--local, per project)
# Virtualenv Behavior
poetry config virtualenvs.create true
# Create virtualenvs automatically in the project root
poetry config virtualenvs.in-project true
# Create .venv/ inside project
poetry config virtualenvs.path "/custom/path"UV Package Manager
To install the dependencies for a cloned repository using uv, use the following command in the project root:
# Prepare python virtual environment
uv env --python 3.13 .venv
# Create environment, if exists removes it first
uv venv --python 3.13 --clear .venv
# Install the dependencies in your virtual environment
uv sync
# List all packages installed in the environment
uv pip listAlternatively, you don’t even need to run sync manually, if you simply try to run th code, uv will check your environment and sync it automatically before executing:
uv run python main.py
