Prérequis
Avant de commencer ce guide, assurez-vous de disposer de :
- Un terminal (macOS, Linux ou Windows avec PowerShell)
- Une familiarité de base avec la ligne de commande
- Une exposition préalable à Python et
pip(utile mais pas obligatoire) - Aucune installation Python existante requise — uv peut gérer Python pour vous
Ce que vous allez apprendre
À la fin de ce guide, vous serez capable de :
- Installer
uvet comprendre pourquoi il remplace toute une pile d'outils - Créer et structurer un projet Python avec un
pyproject.toml - Ajouter, supprimer et épingler des dépendances avec un fichier de verrouillage reproductible
- Gérer les versions de Python sans
pyenv - Exécuter des outils en ligne de commande sans polluer votre environnement global
- Organiser des monorepos multi-paquets avec des espaces de travail
- Construire une image Docker rapide et mise en cache pour la production
Pourquoi uv ?
Pendant plus d'une décennie, les développeurs Python ont jonglé avec une boîte à outils déroutante : pip pour installer, pip-tools ou poetry pour verrouiller, virtualenv pour isoler, pyenv pour changer de version de Python et pipx pour exécuter des outils globaux. Chaque outil avait sa propre configuration, ses propres bizarreries et son propre plafond de performance.
uv, écrit en Rust par Astral (l'équipe derrière le linter Ruff), réduit toute cette pile à un seul binaire. Il est souvent 10 à 100 fois plus rapide que les workflows basés sur pip, car il parallélise les téléchargements, met agressivement en cache via un magasin global adressé par contenu, et résout les dépendances avec un résolveur conçu sur mesure.
Les principaux avantages :
- Un seul outil, une seule configuration. Les projets vivent dans un
pyproject.tomlstandard, verrouillé par un fichieruv.lock. - La vitesse. Les installations à froid semblent instantanées ; les installations à chaud sont quasi nulles grâce à la réutilisation du cache par liens physiques.
- Gestion de Python intégrée. uv télécharge et épingle lui-même les interpréteurs Python — aucun Python système requis.
- Compatibilité directe avec pip. Une interface
uv pippermet une migration progressive.
Étape 1 : Installer uv
uv est livré sous forme de binaire autonome sans aucun prérequis Python.
Sur macOS ou Linux :
curl -LsSf https://astral.sh/uv/install.sh | shSur Windows (PowerShell) :
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"Vous pouvez aussi l'installer via Homebrew, pipx ou même pip :
brew install uv
# ou
pipx install uvVérifiez l'installation et apprenez à la maintenir à jour :
uv --version
uv self updateAstuce : uv s'installe par défaut dans
~/.local/bin. Siuv --versionest introuvable, ajoutez ce répertoire à votrePATHet redémarrez votre shell.
Étape 2 : Créer votre premier projet
Échafaudons un projet. uv prend en charge plusieurs structures — --app pour les applications, --lib pour les bibliothèques distribuables et --package pour les applications empaquetées avec un backend de build.
uv init weather-cli --app
cd weather-cliCela génère un point de départ propre :
weather-cli/
├── .python-version
├── README.md
├── main.py
└── pyproject.toml
Le pyproject.toml est l'unique source de vérité :
[project]
name = "weather-cli"
version = "0.1.0"
description = "Add your description here"
readme = "README.md"
requires-python = ">=3.12"
dependencies = []Remarquez qu'il n'y a pas encore d'environnement virtuel ni d'étape d'installation de Python. uv crée les deux paresseusement la première fois que vous ajoutez une dépendance ou exécutez du code.
Étape 3 : Ajouter et supprimer des dépendances
Ajouter un paquet fait trois choses à la fois : cela met à jour pyproject.toml, crée un .venv si nécessaire, et écrit un fichier de verrouillage.
uv add httpx richVous verrez uv résoudre, télécharger et installer en une fraction de seconde :
Using CPython 3.12.4
Creating virtual environment at: .venv
Resolved 8 packages in 12ms
Installed 8 packages in 23ms
+ httpx==0.27.2
+ rich==13.9.4
...
Besoin d'une plage de versions précise ? Passez la contrainte directement :
uv add "httpx>=0.27,<1.0"La suppression est symétrique et met aussi à jour le fichier de verrouillage :
uv remove richPour les paquets avec fonctionnalités optionnelles (extras), utilisez --extra :
uv add fastapi --extra standardÉtape 4 : Groupes de dépendances pour les outils de développement
Les dépendances de production et de développement ne doivent pas se mélanger. uv utilise la table standard [dependency-groups], avec un groupe dev intégré.
Ajoutez les outils qui ne comptent que pendant le développement :
uv add --dev pytest ruff mypyVotre pyproject.toml les enregistre désormais séparément :
[dependency-groups]
dev = [
"pytest>=8.3.0",
"ruff>=0.8.0",
"mypy>=1.13.0",
]Vous pouvez aussi définir des groupes nommés arbitraires — par exemple un groupe docs :
uv add --group docs mkdocs mkdocs-materialLors du déploiement, n'installez que ce dont la production a besoin :
uv sync --no-devPourquoi c'est important : garder les linters, vérificateurs de types et lanceurs de tests hors de votre image de production rend les builds plus petits, plus rapides et plus sûrs.
Étape 5 : Fichiers de verrouillage et reproductibilité
Chaque fois que les dépendances changent, uv met à jour uv.lock — un instantané entièrement résolu, multiplateforme et haché de tout votre arbre de dépendances. Versionnez-le.
Pour régénérer explicitement le fichier de verrouillage :
uv lockPour synchroniser votre environnement avec le fichier de verrouillage (la commande que vous exécuterez le plus en CI) :
uv syncPour mettre à niveau un seul paquet dans ses contraintes :
uv lock --upgrade-package httpxPour tout mettre à niveau :
uv lock --upgradeEn CI, vous voulez que le build échoue bruyamment si le fichier de verrouillage est obsolète plutôt que de le régénérer silencieusement :
uv sync --lockedCette option affirme que le fichier de verrouillage est déjà à jour — parfait pour des pipelines reproductibles.
Étape 6 : Exécuter du code et des scripts
Vous n'activerez plus jamais un environnement virtuel. uv run exécute une commande dans l'environnement du projet, en synchronisant d'abord les dépendances si nécessaire.
uv run main.py
uv run pytest
uv run ruff checkComme uv garantit que l'environnement correspond au fichier de verrouillage avant l'exécution, les bugs du type « ça marche sur ma machine » disparaissent en grande partie.
uv prend aussi en charge les dépendances de script en ligne — un script à fichier unique peut déclarer ses propres dépendances avec le standard PEP 723 :
# /// script
# requires-python = ">=3.12"
# dependencies = ["httpx", "rich"]
# ///
import httpx
from rich import print
resp = httpx.get("https://api.github.com")
print(resp.json())Exécutez-le sans configuration — uv crée un environnement éphémère à la volée :
uv run fetch_repos.pyVous pouvez même ajouter automatiquement une dépendance au bloc de métadonnées d'un script autonome :
uv add --script fetch_repos.py pandasÉtape 7 : Gérer les versions de Python
uv remplace entièrement pyenv. Il peut télécharger et basculer entre les builds CPython sans toucher à votre Python système.
Listez ce qui est disponible et installez des versions spécifiques :
uv python list
uv python install 3.11 3.12 3.13Épinglez un projet à un interpréteur — cela écrit .python-version :
uv python pin 3.12Lorsque vous exécutez uv sync ou uv run, uv utilise automatiquement (et télécharge si nécessaire) l'interpréteur épinglé. Les nouveaux contributeurs clonent le dépôt et obtiennent la version exacte de Python sans aucune configuration manuelle.
Étape 8 : Exécuter des outils avec uvx
Pour les outils en ligne de commande ponctuels que vous ne voulez pas dans votre projet — formateurs, échafaudeurs, clients HTTP — uv fournit un lanceur isolé. uvx est l'abréviation de uv tool run.
Exécutez un outil dans un environnement jetable :
uvx ruff check .
uvx cowsay -t "uv is fast"Si vous voulez qu'un outil soit disponible en permanence sur votre PATH (le cas d'usage de pipx), installez-le :
uv tool install ruff
uv tool list
uv tool upgrade --allChaque outil obtient son propre environnement isolé, de sorte que leurs dépendances n'entrent jamais en conflit entre elles ni avec vos projets.
Étape 9 : Espaces de travail pour les monorepos
Les grandes bases de code contiennent souvent plusieurs paquets liés. Les espaces de travail d'uv, inspirés de Cargo, permettent à plusieurs paquets de partager un seul fichier de verrouillage et un seul environnement virtuel tout en restant construisibles indépendamment.
Définissez l'espace de travail dans le pyproject.toml racine :
[tool.uv.workspace]
members = ["packages/*"]Faites ensuite dépendre un paquet d'un autre via une source d'espace de travail :
[project]
dependencies = ["shared-core"]
[tool.uv.sources]
shared-core = { workspace = true }Désormais uv sync résout l'ensemble de l'espace de travail d'un seul coup, et une modification dans shared-core est immédiatement visible par chaque paquet qui en dépend — sans publication ni réinstallation.
Pour les dépendances provenant plutôt de Git ou d'un chemin local, [tool.uv.sources] les gère aussi :
[tool.uv.sources]
my-lib = { git = "https://github.com/acme/my-lib", tag = "v1.2.0" }
local-tool = { path = "../local-tool", editable = true }Étape 10 : Construire et publier
Quand votre bibliothèque est prête à être partagée, uv construit des distributions wheel et source standard :
uv buildLes artefacts atterrissent dans dist/. Publiez-les sur PyPI (ou un index privé) avec :
uv publishUtilisez un jeton via la variable d'environnement UV_PUBLISH_TOKEN plutôt que de coder en dur les identifiants.
Étape 11 : Une image Docker de production
uv brille dans les conteneurs grâce à ses montages de cache et ses installations pilotées par le fichier de verrouillage. Le modèle ci-dessous installe les dépendances dans une couche mise en cache avant de copier votre code source, afin que les changements de code n'invalident pas le cache des dépendances.
FROM python:3.12-slim
# Copier le binaire uv depuis l'image officielle
COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/
WORKDIR /app
# Installer d'abord les dépendances, avec un montage de cache et des bind mounts
RUN --mount=type=cache,target=/root/.cache/uv \
--mount=type=bind,source=uv.lock,target=uv.lock \
--mount=type=bind,source=pyproject.toml,target=pyproject.toml \
uv sync --locked --no-install-project --no-dev
# Copier maintenant le projet et l'installer
COPY . /app
RUN --mount=type=cache,target=/root/.cache/uv \
uv sync --locked --no-dev
# Exécuter dans l'environnement synchronisé
CMD ["uv", "run", "main.py"]La synchronisation en deux étapes — d'abord les dépendances, puis le projet — signifie que tant que uv.lock et pyproject.toml restent inchangés, Docker réutilise la lourde couche de dépendances et ne reconstruit que la petite couche du projet.
Migrer depuis pip ou Poetry
Vous n'avez pas à tout réécrire d'un coup. uv est livré avec une interface compatible pip :
uv pip install -r requirements.txt
uv pip compile requirements.in -o requirements.txt
uv venvPour une migration complète, exécutez uv init dans un projet existant, déplacez les entrées de votre requirements.txt dans pyproject.toml avec uv add, et versionnez le uv.lock généré. Les projets Poetry utilisent déjà pyproject.toml, la tâche principale consiste donc à traduire la section [tool.poetry.dependencies] dans la table standard [project] dependencies et à exécuter uv lock.
Tester votre configuration
Vérifiez l'ensemble du workflow de bout en bout :
uv init demo --app && cd demo
uv add httpx
uv add --dev pytest
uv run python -c "import httpx; print(httpx.__version__)"
uv sync --locked
uv treeSi uv tree affiche votre graphe de dépendances et que uv sync --locked se termine proprement, votre projet est reproductible et prêt pour la CI.
Dépannage
uv: command not found après l'installation — le répertoire du binaire (~/.local/bin) n'est pas dans votre PATH. Ajoutez-le et redémarrez le shell.
Le fichier de verrouillage change sans cesse en CI — vous exécutez uv sync au lieu de uv sync --locked. Utilisez la variante verrouillée dans les pipelines pour qu'un fichier obsolète fasse échouer le build plutôt que d'être réécrit silencieusement.
Mauvaise version de Python sélectionnée — vérifiez la présence d'un fichier .python-version parasite ou d'une contrainte requires-python qui exclut votre interpréteur. Exécutez uv python pin pour fixer la version explicitement.
Première installation lente — seul le tout premier passage remplit le cache global. Les installations suivantes, sur tous les projets, réutilisent des fichiers par liens physiques et sont nettement plus rapides.
Étapes suivantes
- Associez uv à Ruff (également d'Astral) pour un dispositif unifié de lint et de formatage propulsé par Rust
- Explorez les dépendances de script en ligne pour l'automatisation jetable et les scripts de données
- Ajoutez
uv sync --lockedà votre CI avant les tests pour garantir des exécutions reproductibles - Lisez d'autres guides d'outils Python sur noqta.tn, dont notre guide FastAPI Docker pour la production et les agents Pydantic AI à typage sûr
Conclusion
uv réduit le paysage fragmenté de l'outillage Python à un seul outil rapide et cohérent. Avec un unique binaire, vous échafaudez des projets, gérez les dépendances et les versions de Python, verrouillez pour la reproductibilité, exécutez des outils isolés, organisez des monorepos et expédiez des images Docker légères. La vitesse est l'accroche, mais le vrai gain est un seul modèle mental au lieu de cinq. Installez-le, exécutez uv init, et vous ne reviendrez que rarement à pip, poetry, pyenv ou pipx.