⚙️ Modern Python Environment & Dependency Control with uv¶
This tutorial demonstrates how to use uv, an extremely fast Python package installer and resolver written in Rust.
uv replaces pip, pip-tools, virtualenv, and poetry in unified projects, improving installation speed and dependency resolution times by up to 10-100x.
How uv Works¶
Modern development teams face challenges with slow virtual environment creation and duplicate storage consumption. Traditional pip downloads and installs duplicate packages separately for every virtual environment.
uv changes this by utilizing a global content-addressable cache and leveraging hard links or symlinks where supported by the file system.
graph TD
subgraph traditional_workflow_slow_redundant ["Traditional Workflow (slow, redundant)"]
A["Project 1 venv"] -->|"Download & Build"| B["PyPI Package A"]
C["Project 2 venv"] -->|"Download & Build"| D["PyPI Package A (Duplicate)"]
B -->|"Write full copy"| E["Disk Space Used"]
D -->|"Write full copy"| E
end
subgraph rust_optimized_workflow_uv ["Rust-Optimized Workflow (uv)"]
F["PyPI Registry"] -->|"Rust Resolver"| G["Centralized uv Cache"]
G -->|"Ref-linked / Hard-linked"| H["Project 1 venv"]
G -->|"Ref-linked / Hard-linked"| I["Project 2 venv"]
H -->|"Zero Disk Overhead"| J["Optimized Disk Space"]
I -->|"Zero Disk Overhead"| J
end
A ~~~ G
In this module, we will explore:
- Inspecting the project environment configuration (
pyproject.toml). - Programmatically verifying installed dependencies.
- Synchronizing virtual environments.
# Ensure we run from the project root directory
import os
import sys
# Locate project root (searching upwards for mkdocs.yml)
current_dir = os.path.dirname(os.path.abspath(__file__)) if "__file__" in locals() else os.getcwd()
while current_dir != os.path.dirname(current_dir):
if os.path.exists(os.path.join(current_dir, "mkdocs.yml")):
break
current_dir = os.path.dirname(current_dir)
if os.path.exists(os.path.join(current_dir, "mkdocs.yml")):
os.chdir(current_dir)
if current_dir not in sys.path:
sys.path.insert(0, current_dir)
else:
print("⚠️ Could not find project root containing mkdocs.yml.")
import platform
print("=== Python Environment Diagnostics ===")
print(f"Python Executable: {sys.executable}")
print(f"Python Version: {sys.version}")
print(f"OS Platform: {platform.system()} ({platform.release()})")
print("======================================")
=== Python Environment Diagnostics === Python Executable: /home/t/MLOps/.venv/bin/python Python Version: 3.12.3 (main, Mar 23 2026, 19:04:32) [GCC 13.3.0] OS Platform: Linux (6.18.33.1-microsoft-standard-WSL2) ======================================
📦 1. Package Verification¶
Let's inspect some of the core dependencies we installed using uv (like DVC, MLflow, FastAPI, and Moto) to confirm they are accessible in our virtual environment.
try:
import dvc
print(f"✅ DVC is installed, version: {dvc.__version__}")
except ImportError:
print("❌ DVC is NOT installed.")
try:
import mlflow
print(f"✅ MLflow is installed, version: {mlflow.__version__}")
except ImportError:
print("❌ MLflow is NOT installed.")
try:
import fastapi
print(f"✅ FastAPI is installed, version: {fastapi.__version__}")
except ImportError:
print("❌ FastAPI is NOT installed.")
try:
import moto
print(f"✅ Moto (AWS mock service) is installed, version: {moto.__version__}")
except ImportError:
print("❌ Moto is NOT installed.")
✅ DVC is installed, version: 3.67.1
✅ MLflow is installed, version: 3.13.0
✅ FastAPI is installed, version: 0.136.3
✅ Moto (AWS mock service) is installed, version: 5.2.2
🛠️ 2. How to Work with uv¶
Here is a quick reference guide of commands to run in your terminal:
- Initialize a new project:
uv init - Add dependencies:
uv add pandas scikit-learn
- Remove dependencies:
uv remove pandas
- Sync project virtual environment:
uv sync - Run scripts inside the virtual environment:
uv run python main.py
🖥️ 3. Introducing the mlops CLI¶
To unify our operations, we have introduced a project-wide mlops CLI.
The first command we initiate is mlops status (or mlops diagnose), which verifies environment versions and crucial dependencies.
- Run CLI status locally:
uv run mlops status
- Run CLI status via Docker:
docker run --rm -it mlops-cli status
Let's run this diagnostics check programmatically:
import subprocess
result = subprocess.run(["mlops", "status"], capture_output=True, text=True)
print(result.stdout)
=== Python Environment Diagnostics ===
Python Executable: /venv/bin/python3
Python Version: 3.12.13 (main, Jun 11 2026, 01:09:00) [GCC 14.2.0]
OS Platform: Linux (6.18.33.1-microsoft-standard-WSL2)
======================================
✅ boto3 is installed (version: 1.43.28)
✅ dvc is installed (version: 3.67.1)
✅ mlflow is installed (version: 3.13.0)
✅ fastapi is installed (version: 0.136.3)
✅ moto is installed (version: 5.2.2)
/venv/lib/python3.12/site-packages/evidently/descriptors/text_match.py:140: SyntaxWarning: invalid escape sequence '\d'
TextMatch(text_column="description", match_items=r"\b\d{3}-\d{3}-\d{4}\b", match_type="regex")
✅ evidently is installed (version: 0.7.21)
❌ feast is NOT installed
✅ openai is installed (version: 2.41.1)
Now that we've verified our python environment and unified CLI entry point, let's move to the Notebook Documentation guide to understand how percent-style cells (#%%) are converted into rich docs!