- Avec uv, la gestion des dépendances est automatisée lors de l’exécution de scripts Python
- Sans gestion d’environnement virtuel séparée, un environnement est automatiquement créé et maintenu pour chaque script
- Les paquets nécessaires peuvent être déclarés de différentes façons, comme via des métadonnées inline ou des options en ligne de commande
- La version de Python et la gestion des paquets peuvent aussi être déclarées au niveau du script et ajustées automatiquement
- Les fichiers de lock et les options de contrainte de version des dépendances améliorent la reproductibilité et la maintenabilité
Aperçu
- uv est un outil qui gère automatiquement les dépendances de paquets requises par un script Python lors de son exécution
- L’utilisateur n’a pas besoin de créer lui-même des environnements virtuels ni d’installer des paquets manuellement
- Il fournit plusieurs options d’exécution, l’usage de métadonnées inline, différentes façons de déclarer les dépendances et divers mécanismes de contrôle
Environnement Python et rôle de uv
- Python dispose d’un environnement propre pour chaque installation
- En général, il est recommandé de créer et gérer des environnements virtuels
- uv gère automatiquement les environnements virtuels et traite les dépendances de manière déclarative
- Un script simple peut être exécuté immédiatement avec
uv run example.py
- Si seul la bibliothèque standard est utilisée, cela fonctionne sans configuration supplémentaire
Passage d’arguments et modes d’entrée
- Il est possible de transmettre des arguments en ligne de commande au script
- L’outil prend aussi en charge l’exécution directe du code du script depuis l’entrée standard, ainsi que la fonctionnalité here-document
Environnement de projet et option --no-project
- Si un script est exécuté dans un dossier de projet (par exemple, là où se trouve
pyproject.toml), les dépendances du projet sont également installées
- Si ce n’est pas souhaité, on peut ignorer l’environnement du projet en plaçant le flag
--no-project avant le nom du script
Déclaration et gestion des dépendances du script
- Lorsqu’un paquet externe est nécessaire, il est possible d’indiquer la dépendance à l’exécution avec l’option
--with
- Les contraintes sur des versions spécifiques sont prises en charge, et plusieurs dépendances peuvent être indiquées en répétant l’option
- Il est possible d’ajouter des dépendances supplémentaires dans l’environnement du projet, et de contrôler cela avec
--no-project si besoin
Inline Script Metadata (méthode PEP 723)
- Python prend désormais en charge un format standard permettant de déclarer directement dans le script les dépendances ou la version de Python
uv init --script permet de créer facilement un script contenant des métadonnées inline
uv add --script permet d’ajouter et de gérer en format TOML les dépendances nécessaires au script
- En présence de métadonnées inline, les dépendances du projet sont ignorées et seules celles du script sont appliquées
Déclaration et gestion de la version de Python
- Il est possible de définir la version de Python souhaitée dans le script ou au moment de l’exécution
- Si la version indiquée n’est pas disponible, elle est automatiquement téléchargée et configurée
Écriture de scripts directement exécutables avec un shebang
- En utilisant un shebang (
#!...), il est possible de créer un exécutable direct avec la méthode uv run --script
- Dans ce cas également, la déclaration des dépendances et la version de Python peuvent être définies en tête du script
Prise en charge des index de paquets et de l’authentification
- L’option
--index permet d’utiliser un index de paquets personnalisé
- Les informations d’index peuvent aussi être incluses dans les métadonnées
- En cas d’authentification requise, il est possible de se référer à une documentation distincte
Verrouillage des dépendances et amélioration de la reproductibilité
uv lock --script permet de créer et gérer un fichier de lock au niveau du script
- Lors des exécutions suivantes ou de l’ajout de dépendances, le fichier de lock est réutilisé et mis à jour si nécessaire
- L’option
exclude-newer (exclure les versions publiées après une date donnée) est fournie pour la reproductibilité des versions
- La date est spécifiée au format horodaté RFC 3339
Souplesse des versions de Python
- À chaque exécution, il est possible de choisir n’importe quelle version de Python via une option en ligne de commande
- Exemple :
uv run --python 3.10 example.py
Prise en charge de Windows
- Les scripts portant l’extension
.pyw sont exécutés avec pythonw sous Windows
- Les scripts à interface graphique peuvent eux aussi être exécutés avec leurs dépendances
Documentation de référence
- Pour un usage plus détaillé des commandes, il est possible de consulter la documentation de référence de la CLI ainsi que les guides d’exécution et d’installation de l’outil
Conclusion
- uv est un outil qui gère automatiquement et simplement l’environnement d’exécution, les dépendances, les versions, les index de paquets et la reproductibilité des scripts Python, améliorant à la fois la productivité et la fiabilité
7 commentaires
Je suis moi aussi passé de pip à uv, et franchement rien que pour la vitesse, ça vaut le coup de changer.
Le sujet revient souvent, alors je l’ai essayé pour la première fois hier… c’est vraiment rapide. Wow…
J’ai l’impression avoir déjà vu plus de cinq posts sur uv ici ;; ;
Même en laissant de côté les autres fonctionnalités, la seule vitesse suffit largement à justifier son utilisation.
Si on me demandait de réutiliser
pip, j’en serais absolument incapable.J’ai remplacé la gestion des paquets système de conda par
flake.nix, mais en dehors des projets collaboratifs ou des projets existants maintenus avec conda+pip, j’utiliserai probablementuv+nixà l’avenir pour mes usages personnels.Uv - un outil de packaging Python ultra-rapide implémenté en Rust
Réinventer le workflow de développement Python avec uv
Utiliser des scripts Python avec uv et PEP 723
Un an d’utilisation de uv : avantages, inconvénients et points à considérer lors d’une migration
J’ai récemment remplacé la plupart de mes exécutions Python par
uv, et c’est vraiment rapide.Il existe bien quelques fonctionnalités avancées qui ne sont pas parfaitement compatibles, mais dans la plupart des cas, le comportement est presque identique.
Commentaires sur Hacker News
J’ai constaté à quel point la fonctionnalité de « déclaration des dépendances du script » est utile
Comme présenté dans la documentation officielle, on peut indiquer les dépendances en commentaire tout en haut du code Python, comme ceci
Si l’on enregistre ce fichier sous
script.pypuis qu’on l’exécute avecuv run script.py, les dépendances déclarées sont installées comme par magie dans un environnement virtuel temporaire et le script peut être lancé immédiatementIl s’agit d’une implémentation de la PEP 723 de Python, et Claude 4 connaît aussi cette astuce, donc si on lui demande d’écrire « un script Python avec des dépendances inline », il le fait correctement
On peut par exemple lui demander de générer du code qui télécharge un gros fichier avec httpx et click tout en affichant une barre de progression
Avant Claude 4, ce genre de fonctionnalité nécessitait un projet sur mesure et des consignes séparées, mais ce n’est plus le cas
On peut aussi consulter ce cas d’usage détaillé
Le mode shebang est lui aussi vraiment pratique
En ajoutant le shebang suivant à la première ligne du script, on peut l’exécuter comme
./script.shJ’aimerais que le format soit identique à celui d’un fichier requirements
Cela permettrait, pour les utilisateurs qui n’ont pas uv, d’ajouter un simple commentaire avec une commande en une ligne pour installer la même chose avec pip
Une approche du genre
pip install -r <(head myscript.py)semblerait possibleEn pratique, la PEP 723 est désormais prise en charge non seulement par uv, qui attire beaucoup l’attention en ce moment, mais aussi par pipx et hatch
Et le support figure aussi sur la feuille de route de pip-tools, entre autres
(voir ce ticket)
La première fois, j’ai cru que c’était un emoji cœur à côté de requests
Je trouve cette approche vraiment élégante
Mais j’aimerais qu’un jour cela soit adopté comme une syntaxe intégrée au langage plutôt que comme des commentaires magiques
Les commentaires donnent un aspect un peu brouillon
Bien sûr, je comprends que du point de vue des outils, les commentaires magiques sont plus simples à parser et qu’il y a aussi des questions structurelles, comme le fait que le cœur de Python ne maîtrise pas tant que ça le packaging, mais j’aimerais quand même voir apparaître une syntaxe native un jour
Je partage complètement cette approche
C’est dommage que, même si Python n’impose pas un fichier
requirements.txt, on se retrouve souvent avec des choses qui cassent quand on néglige sa gestionTweet associé
Je voudrais partager un piège rencontré avec cette méthode
Je l’ai utilisée pour un script qui redémarre le routeur quand Internet tombe, mais comme l’installation des dépendances dépend de la connexion réseau, si le réseau ne fonctionne plus le script lui-même devient inutilisable
Je m’en suis rendu compte à temps et j’ai résolu le problème en préinstallant les dépendances, mais ne faites pas la même erreur que moi et évitez de l’utiliser dans un vrai environnement air-gapped (complètement isolé du réseau)
Même avec le cache uv, on peut avoir un cache miss
Avec l’option
uv run --offline, on peut utiliser les dépendances en cache sans vérifier s’il existe de nouvelles versionsLa même chose fonctionne aussi avec
uvx(uvx --offline ...)Si l’on a besoin d’utiliser des dépendances ou un venv, il me semble qu’il faut au moins une première exécution avec une connexion Internet pour pouvoir ensuite l’utiliser hors ligne
J’ai l’impression qu’en ce moment, dans l’écosystème Python, de plus en plus de fonctionnalités commencent à bien s’emboîter
Avec la combinaison de Marimo et des dépendances de script uv, je commence à créer des outils de reporting et de diagnostic reproductibles, faciles à utiliser par d’autres équipes
C’est la fonctionnalité de uv que je préfère, au point de m’avoir fait passer à uv
Plusieurs scripts de git-hooks ont chacun leurs propres dépendances, et je ne voulais pas les installer dans le venv principal
Il suffisait d’ajouter
#!/usr/bin/env -S uv run --script --python 3.13, puis de dire aux devs de fairebrew install uv, et ils pouvaient les utiliser directement dans le script sans créer de venv séparéJe me demande si quelqu’un sait pourquoi le flag
-Sest nécessaireSur mon environnement BSD,
/usr/bin/env -S uv run --python 3.11 pythonet/usr/bin/env uv run --python 3.11 pythonlancent tous deux le shell Python, donc j’ai l’impression que le résultat est identiqueMême après avoir lu la page de manuel de env, je n’ai pas trouvé d’explication claire, donc si quelqu’un a une info utile, je suis preneur
(Ici,
-Ssert à séparer les arguments sur les espaces)Grâce à uv, une grande migration Python qui devait initialement se faire vers golang a pu être réduite
En particulier, les petits travaux sous forme de scripts n’ont plus besoin d’être déplacés
Je suis convaincu que c’est une véritable fonctionnalité « killer »
Si l’une des dépendances est Pytorch, cette approche peut être un peu limitée
Uv offre bien une prise en charge intégrée pour Pytorch, mais rien dans l’en-tête du script ne permet vraiment de choisir clairement l’index de wheels le plus adapté (CPU, CUDA, ROCm, etc.)
J’aimerais que VS Code puisse reconnaître facilement les venv créés automatiquement par uv
Pour l’instant, l’extension Python souligne tous les imports tiers en rouge
En solution temporaire, je vais chercher manuellement le chemin du venv dans le répertoire de cache de uv pour l’enregistrer, mais si le venv est recréé régulièrement, il faut recommencer à chaque fois, ce qui est pénible
uv python find --script "${filePath}"Je développe une extension pour que VS Code détecte automatiquement cela et active le bon interpréteur
J’adore tellement cette fonctionnalité de UV
On peut même lancer un notebook jupyter en une seule ligne, sans installation séparée, comme ceci
Tout est installé dans un environnement virtuel temporaire, puis nettoyé ensuite
Si on l’exécute dans un projet, ses dépendances sont aussi détectées automatiquement
Cela dit, ce n’est pas totalement « proprement » nettoyé, car le dossier de cache de uv peut continuer à grossir
Moi aussi, j’utilise souvent des commandes du type
uv run --with ipython --with boto3 ipython, et cela me fait vraiment gagner beaucoup de tempsJ’ai récemment remarqué un petit souci avec
uv runSi l’on exécute un script depuis l’extérieur du dossier du projet, il cherche
pyproject.tomldans le répertoire de travail courant plutôt qu’à l’emplacement réel du fichier scriptDu coup, un script dont les dépendances sont stockées dans
pyproject.tomlpeut ne pas fonctionner correctement si on le lance depuis l’extérieur avec une commande commeuv run path/to/my/script.pyOn peut contourner cela soit en utilisant toujours des dépendances inline, soit en passant l’argument
--project, mais cela oblige à saisir deux fois le chemin du script, ce qui est peu pratiqueuv reste excellent, mais cette petite particularité est assez agaçante
J’utilisais déjà avec satisfaction le shebang spécifique à uv et les dépendances définies dans le script
J’ai été encore plus impressionné en découvrant qu’on peut aussi générer un fichier lock dédié à un script unique avec
uv lock --script example.pyAprès plus de 20 ans de packaging Python, je suis surpris qu’une expérience aussi naturelle n’apparaisse que maintenant
Dans notre organisation, on scanne aussi les dépendances des lockfiles avec
trivy fs uv.lockafin d’éviter d’exécuter du code contenant des CVE connues