14 points par GN⁺ 2025-06-25 | 2 commentaires | Partager sur WhatsApp
  • Le gestionnaire de paquets uv et la PEP 723 permettent désormais d’exécuter des scripts Python sans se heurter aux problèmes de dépendances
  • La fonctionnalité uvx crée automatiquement des environnements virtuels jetables, ce qui élimine les contraintes de configuration de l’environnement
  • En intégrant les métadonnées PEP 723 dans un fichier Python, l’exécution automatique des scripts et la gestion des paquets deviennent plus pratiques
  • Un exemple de script exécutable montre qu’il est possible d’implémenter et de déployer rapidement un programme d’extraction de sous-titres YouTube
  • Grâce à cela, Python permet désormais lui aussi d’écrire des fichiers exécutables simples et autonomes, ce qui améliore fortement l’utilité des scripts

Vue d’ensemble

  • Dans Python, l’inconvénient qui obligeait à reconfigurer l’environnement et à réinstaller les paquets à chaque exécution d’un « script ponctuel » (one-off script) disparaît avec l’arrivée de uv et de la PEP 723
  • uv est un gestionnaire de paquets et de projets Python haute performance développé en Rust ; avec sa nouvelle fonctionnalité uvx, il gère de façon très rapide et simple la création d’environnements virtuels jetables, l’installation automatique des paquets et l’association avec la version de Python

Avantages de uv et uvx

  • La fonctionnalité uvx fonctionne de manière similaire à npx dans l’écosystème Nodejs, en créant rapidement un environnement d’exécution pour le paquet Python demandé (par exemple ruff)
  • Elle s’appuie sur des environnements virtuels jetables mis en cache pour offrir une exécution rapide sans surcoût
  • La configuration de l’environnement et l’installation des dépendances se font en une seule ligne de commande, sans que le développeur ait à gérer un environnement séparé

Présentation et usage de la PEP 723

  • La PEP 723 définit un standard permettant d’inclure des métadonnées de dépendances et d’environnement en haut d’un script Python
  • Exemple : il est possible d’y préciser requires-python, dependencies, etc.
  • Les outils externes qui reconnaissent ce format (comme uv) utilisent ces informations écrites dans le fichier de script pour automatiser l’installation, la configuration de l’environnement et l’exécution

Combiner uv et la PEP 723

  • Dans un vrai fichier d’exemple Python, on écrit ces métadonnées en tête du fichier, puis l’exécution avec la commande run de uv installe immédiatement tous les paquets nécessaires, configure la version de Python demandée et lance le code
  • Le code d’exemple appelle une API sur Internet (la liste des PEP) et affiche le résultat. Tout peut être exécuté en une seule ligne, sans installation de paquets supplémentaire ni configuration d’environnement

Cas pratique : un script de sous-titres YouTube

  • Un exemple de script Python est fourni avec un shebang (#!/usr/bin/env -S uv run --script) et des métadonnées PEP 723
  • L’installation automatique de paquets externes comme youtube-transcript-api ainsi que la configuration automatique de l’environnement virtuel sont prises en charge
  • L’utilisateur peut fournir comme argument au fichier exécutable (ytt) une URL ou un ID de vidéo YouTube, puis obtenir immédiatement les sous-titres extraits
  • Après avoir accordé les droits d’exécution avec chmod, le script peut être lancé très simplement depuis le terminal

Amélioration de l’expérience développeur et élargissement des possibilités

  • Par le passé, même pour de simples scripts, on préférait souvent des langages produisant un binaire autonome comme Go ; désormais, Python offre lui aussi un niveau de simplicité comparable
  • La combinaison de uv et de la PEP 723 facilite grandement le partage, le déploiement et l’automatisation de l’exécution des scripts Python
  • L’exemple GitHub (cottongeeks/ytt-mcp) montre qu’il est possible de développer des cas d’usage plus complexes

2 commentaires

 
ndrgrd 2025-06-25

uv est incroyablement rapide, c’est vraiment appréciable. En ce moment, je l’utilise partout où c’est possible.

 
GN⁺ 2025-06-25
Avis Hacker News
  • Comme l’auteur du billet, ces temps-ci j’ai davantage tendance à me tourner vers des one-off Python cross-platform et des scripts perso plutôt que vers Go, mais je reste insatisfait par le fait que le système de vérification de types de Python soit un chaos absolu ; j’espère que des outils comme ty ou pyrefly amélioreront un peu les choses

  • On a désormais l’impression que les scripts Python fonctionnent directement sans faire souffrir avec virtualenv Ce serait bien d’avoir une expérience comparable côté shell scripts Le packaging, la gestion des dépendances et la reproductibilité en sont toujours à l’âge de pierre Aujourd’hui encore, la réalité, c’est soit curl | bash en s’en remettant à la chance, soit un README rempli de 3 dépendances manquantes et de 12 étapes manuelles Nix ? On dirait une option utilisable uniquement pour ceux qui ont déjà transcendé le temps, l’espace et le manuel de Nix Docker ? Si télécharger une distribution Linux pour lancer une seule commande sed vous paraît raisonnable, alors pourquoi pas Il faut vraiment un juste milieu simple, déclaratif et accessible à tous

    • Personnellement, je préfère n’écrire que des shell scripts qui n’utilisent que des binaires et bibliothèques déjà fournis nativement par l’OS cible Viser la portabilité pour des shell scripts est en pratique un choix qui ne colle pas très bien Si un shell script utilise des commandes spécifiques à macOS et qu’il faut l’exécuter sur Linux, aucun gestionnaire de paquets ne pourra résoudre ce problème
    • Nix ne me semble pas si difficile à utiliser pour cet usage précis Si on installe Nix sur une autre distribution, on peut l’utiliser assez simplement, par exemple comme ceci NixOS ou l’ensemble du packaging Nix sont certes assez exigeants, mais pour les shell scripts uniquement, la barrière d’entrée reste plutôt basse
    • Je ne ressens pas vraiment le besoin d’écrire de nouveaux shell scripts Si l’environnement autorise l’installation de toutes les dépendances, des outils comme uv s’occupent déjà de tout Et si vous aimez Clojure, je recommande aussi babashka
    • Si le packaging, la gestion des dépendances et la reproductibilité paraissent préhistoriques en shell script, c’est peut-être justement parce que, dès qu’on en a besoin à ce niveau, le shell n’est plus l’outil adapté À mon sens, le shell ne convient qu’à de petits scripts d’une vingtaine de lignes Le langage lui-même n’est pas d’une qualité suffisante pour aller bien au-delà
    • Recommandation pour mise On l’utilise en entreprise pour gérer les environnements de développement, et il permet de configurer l’environnement bien plus simplement que Docker ou Nix Le support de l’installation en parallèle est un gros avantage par rapport à un Dockerfile classique
  • C’est une tendance vraiment excellente, et on a l’impression qu’elle se démocratise de plus en plus Je l’ai découverte au départ sur le blog de simonw, et on peut voir le sujet dans ce billet de blog de simonwillison En mars de cette année, il y a aussi eu une discussion Hacker News autour d’un autre billet de blog J’aimerais que cette tendance reste longtemps en page principale afin que davantage de gens en prennent conscience

  • Après avoir essayé uv sur de petits projets, l’expérience est vraiment excellente La combinaison uv run et uv tool run (uvx) rend extrêmement simple l’installation et l’exécution directes, sur une VM, de scripts Python depuis GitHub Pas besoin de git clone, ni de créer ou d’ouvrir un venv, ni de faire un pip install Surtout, uv est tellement rapide qu’au début j’ai cru qu’il y avait un problème ; en pratique, le résultat est environ 10 fois plus rapide que pip Les outils et la documentation sont encore un peu inachevés, mais c’est déjà largement utilisable vu le niveau d’innovation et d’utilité

    • Franchement, je suis impressionné que uv installe des dépendances plus vite que pyenv n’affiche --help
  • Rust fait aussi évoluer une idée similaire de shell scripts typés en fichier unique C’est d’ailleurs en Rust que j’ai vu ce mode de fonctionnement pour la première fois (prise en charge de l’exécution d’un fichier unique avec gestion des dépendances incluse) J’espère que ce modèle s’implantera dans davantage de langages ; c’est très utile pour se partager des gists ou écrire rapidement de petits outils Voir aussi le document RFC cargo-script

  • Lorsqu’on utilise uv run --script, inclure les métadonnées dans le script rend un peu moins pratique le fait d’ouvrir directement un REPL Python depuis le script pour tester des modifications Par exemple, il faut faire quelque chose comme ceci :

    $ uv run --python=3.13 --with-requirements <(uv export --script script.py) -- python
    >>> from script import X
    

    J’aimerais qu’il existe une manière plus concise Par exemple, l’idéal serait quelque chose comme :

    $ uv run --with-script script.py python
    

    Cela dit, en exécutant en pratique la commande ci-dessous, on peut entrer directement dans l’environnement Python et venv correspondant au script :

    $ "$(uv python find --script script.py)"
    >>> from script import X
    

    En revanche, il faut d’abord avoir exécuté le script une fois pour que l’environnement soit créé

    • Si vous avez besoin d’une fonction pour appeler un REPL après le setup, je recommande cet exemple de gist On peut aussi ajouter au script un flag comme --interactive et l’exposer comme option CLI J’écris souvent de petits CLI basés sur Typer de cette façon Dans un script de dev, j’ai aussi déjà utilisé un flag --sql pour entrer dans un REPL SQL DuckDB
    • Une méthode simple présentée ici :
      cat ~/.local/bin/uve
      #!/bin/bash
      temp=$(mktemp)
      uv export --script $1 --no-hashes > $temp
      uv run --with-requirements $temp vim $1
      unlink $temp
      
  • Si vous utilisez conda, il est possible d’activer directement l’environnement dans un wrapper shell pour le script Python Par exemple :

    #!/usr/bin/env bash
    eval "$(conda shell.bash hook)"
    conda activate myenv
    python myscript
    

    Cela dit, ce n’est pas une approche aussi autonome que le style PEP 723

  • Après avoir vu les fils HN d’hier et d’aujourd’hui, j’ai décidé d’essayer uv pour la première fois, et j’ai été très impressionné par sa rapidité et la facilité de gestion des dépendances Ce serait encore mieux si la documentation officielle s’améliorait, notamment avec un guide pour passer d’un workflow requirements.txt à uv La façon de définir la version de Python par projet m’a semblé un peu confuse (définition à deux endroits : .python-version et pyproject.toml)

    • J’ai déjà rédigé un ebook explorant les outils de développement Python J’y avais justement signalé certains manques de la documentation officielle ; je recommande donc aussi : comment migrer depuis requirements.txt et comment changer la version de Python d’un projet uv S’il y a d’autres sujets que vous aimeriez voir traités, n’hésitez pas à les proposer
    • Le champ requires-version dans pyproject.toml désigne la plage de versions compatibles garantie, tandis que .python-version indique la version précise à utiliser pour le développement Avec uv init, les deux semblent identiques au départ, mais avec le temps, requires-version finit par indiquer une version minimale prise en charge plus basse que celle de .python-version requires-version entre aussi dans les métadonnées du paquet et influence la résolution des dépendances chez d’autres personnes qui utiliseront le paquet publié Par exemple, si la v1 prend encore en charge une ancienne version de Python mais pas la v2
    • J’ai un ressenti similaire, mais je m’obstine à conserver mon propre workflow (synchroniser le même fichier via Dropbox sur tous mes ordinateurs et l’utiliser quel que soit le système) Comme avec npm ou dotnet, lorsqu’on change de plateforme, il faut exécuter npm update ou dotnet restore, mais venv continue de bien fonctionner sans problème En revanche, avec uv, le changement de plateforme donne l’impression d’être plus complexe et de nécessiter davantage de nettoyage manuel
    • pyproject.toml sert (indépendamment de uv lui-même) à définir l’environnement nécessaire lorsqu’on partage son code avec des développeurs externes et des utilisateurs Il sert à préciser quel environnement est requis lors de la construction d’un paquet pour PyPI, et la plage de versions est définie pour élargir le plus possible la réutilisabilité du code par d’autres .python-version, lui, ne sert qu’à uv, uniquement lorsqu’il prépare mon environnement de développement Si un environnement a déjà été préparé à l’avance, il n’est pas forcément nécessaire d’en configurer un nouveau uv n’est pas encore le backend de build officiel, mais cette fonctionnalité est en préparation (issue #3957)
    • Je ne me suis pas penché sur le sujet en détail, mais je suppose que le rôle du fichier .python-version est surtout d’assurer la compatibilité avec d’autres outils qui n’ont pas de parseur TOML
  • J’avais autrefois envisagé de créer un outil permettant à des scripts Python d’installer eux-mêmes leurs dépendances (avec pour objectif un comportement à la uvx, mais fonctionnant avec seulement Python installé) L’inconvénient, c’est qu’il faut ajouter plusieurs lignes un peu étranges au tout début du script Si ça vous intéresse, c’est publié sur PyPI sous le nom pysolate

    • Il existe aussi le projet isolate, similaire mais peu répandu L’approche est un peu différente, mais reste intéressante
  • Message dans un style Grace Hopper inspiré de COBOL Il faudrait une culture où tous les programmes Python définissent une division ENVIRONMENT afin de documenter clairement l’environnement de compilation et d’exécution, y compris les exigences matérielles et logicielles Une telle structure aurait un effet décisif sur l’amélioration de la portabilité des programmes entre systèmes variés