Aller au contenu

Création d'un environnement isolé avec uv

·4 mins·
Industrialisation
IndustrialisationProjet - Cet article fait partie d'une série.
Partie 1: Cet article

Isoler les dépendances de chaque projet évite les conflits de versions et garantit des exécutions reproductibles. Sur le terrain, on croise trois façons de faire : venv, Poetry et uv (comparaison ici).

En pratique, uv offre souvent le meilleur compromis : rapide, simple, reproductible, et capable de créer ou maintenir automatiquement l’environnement .venv du projet (docs.astral.sh).


1. Installer uv
#

uv s’installe via un binaire autonome ; il ne dépend pas de Python mais sait localiser ou installer une version lorsqu’il en a besoin (docs.astral.sh) :

curl -LsSf https://astral.sh/uv/install.sh | sh
uv --version

2. Initialiser le projet et la structure
#

# Crée le squelette du projet (pyproject.toml, README, main.py…)
uv init --package my_project
cd my_project

On peut ensuite compléter la structure :

mkdir -p data/{bronze,silver,gold} notebooks scripts tests
touch data/.gitkeep notebooks/.gitkeep scripts/.gitkeep tests/.gitkeep

Structure type :

my_project/
├─ pyproject.toml
├─ uv.lock
├─ src/
│  └─ my_project/
│     ├─ __init__.py
│     ├─ io.py
│     ├─ features.py
│     └─ train.py
├─ tests/
├─ scripts/
│  ├─ build_features.py
│  └─ train_model.py
├─ notebooks/
└─ data/

La première commande “projet” (uv run, uv sync, uv lock) crée .venv et uv.lock à la racine (docs.astral.sh).


3. (Optionnel) Pinner la version de Python
#

uv python install 3.12

uv crée alors un fichier .python-version précisant la version à utiliser. Il peut gérer ses propres Pythons, ou s’appuyer sur la version système (docs.astral.sh).


4. Ajouter les dépendances
#

# Dépendances runtime
uv add pandas numpy polars pyarrow

# Dépendances de développement
uv add --dev ruff pytest pre-commit

# Synchronisation
uv sync

uv sync maintient .venv à jour et installe le projet en editable, pratique pour le développement (docs.astral.sh).


Ajouter ou modifier des packages
#

Toujours passer par uv (et non pip) pour garder le projet cohérent :

# Ajouter une lib
uv add requests                 # runtime
uv add --dev ruff pytest        # dev only

# Pinner / mettre à jour
uv add "requests==2.32.*"
uv add --upgrade requests
uv lock --upgrade

# Supprimer
uv remove requests
uv sync

5. Utiliser les notebooks
#

# Ajouter ipykernel côté dev
uv add --dev ipykernel

# Créer le kernel lié à la .venv du projet
uv run python -m ipykernel install --user \
  --name "$(basename "$PWD")" \
  --display-name "Python ($(basename "$PWD"))"

Le kernel apparaîtra ensuite dans Jupyter / VS Code sous le nom choisi.


6. Scripts de dev et configuration des outils
#

Un pyproject.toml minimal :

[project]
name = "my_project"
version = "0.1.0"
description = "Exemple de projet data industrialisé avec uv"
readme = "README.md"
requires-python = ">=3.12"
dependencies = ["pandas", "numpy", "polars", "pyarrow"]

[tool.ruff]
line-length = 100
target-version = "py312"

[tool.pytest.ini_options]
addopts = "-q"

Exemples d’utilisation :

# Lancer le module principal
uv run python -m my_project

# Lancer les tests
uv run pytest

# Linter / formatage
uv run ruff check .
uv run ruff format .

7. Git & CI
#

.gitignore : même si uv ignore déjà .venv, on garde un fichier classique. L’essentiel est de committer pyproject.toml et uv.lock pour garantir la reproductibilité.

Export possible pour compatibilité :

uv export --format requirements-txt > requirements.txt

(À n’utiliser qu’en dernier recours, pour éviter la divergence entre les deux formats.)

En CI, on privilégie :

uv sync --frozen
uv run pytest

8. Combiner uv et Cookiecutter
#

Les deux outils sont complémentaires :

OutilRôle
CookiecutterGénère la structure, les fichiers et conventions du projet
uvGère les dépendances, l’environnement .venv et le lockfile

Exemple de workflow
#

uvx cookiecutter gh:mon-org/mon-template
cd mon_projet
uv init --package .          # si pyproject.toml absent
uv add pandas numpy pyarrow
uv add --dev ruff pytest ipykernel
uv sync

Bonus : post-gen hook
#

Dans un template Cookiecutter, on peut lancer uv automatiquement après génération :

# hooks/post_gen_project.py
import subprocess
subprocess.run(["uv", "sync"], check=False)

9. Snippets utiles
#

Starter uv (src layout, projet data)
#

uv init --package my_project
cd my_project
uv python install 3.12
uv add pandas numpy polars pyarrow matplotlib
uv add --dev ruff pytest pre-commit ipykernel
uv sync

# Qualité
uv run ruff check .
uv run ruff format .

# Tests
uv run pytest

Sources
#

Thibault CLEMENT - Intechnia
Auteur
Thibault CLEMENT - Intechnia
Data scientist
IndustrialisationProjet - Cet article fait partie d'une série.
Partie 1: Cet article