14 puntos por GN⁺ 2025-07-22 | 7 comentarios | Compartir por WhatsApp
  • uv automatiza la gestión de dependencias al ejecutar scripts de Python
  • Sin necesidad de gestionar un entorno virtual por separado, se crea y mantiene automáticamente un entorno por script
  • Los paquetes necesarios se pueden declarar de varias formas, como con inline metadata u opciones de línea de comandos
  • La versión de Python y la gestión de paquetes también se pueden declarar por script y ajustarse automáticamente
  • Los archivos lock y las opciones para restringir versiones de dependencias mejoran la reproducibilidad y el mantenimiento

Descripción general

  • uv es una herramienta que administra automáticamente las dependencias de paquetes que necesita un script de Python al ejecutarse
  • El usuario no tiene que encargarse manualmente de la tediosa creación de entornos virtuales ni de la instalación de paquetes
  • Ofrece varias opciones de ejecución, formas de usar inline metadata, distintos métodos para declarar dependencias y varias funciones de control

El entorno de Python y el papel de uv

  • Python tiene un entorno único para cada instalación
  • En general, se recomienda crear y administrar entornos virtuales
  • uv administra automáticamente los entornos virtuales y maneja las dependencias de forma declarativa
  • Los scripts simples se pueden ejecutar de inmediato solo con uv run example.py
  • Si se usa la biblioteca estándar, funciona sin configuración adicional

Paso de argumentos y métodos de entrada

  • Se pueden pasar argumentos de línea de comandos al script
  • También permite ejecutar código de script recibido directamente desde la entrada estándar y admite la función de here-document

Entorno de proyecto y opción --no-project

  • Si el script se ejecuta dentro de una carpeta de proyecto (por ejemplo, donde hay un pyproject.toml), también se instalan las dependencias del proyecto
  • Si no se necesitan, se puede ignorar el entorno del proyecto colocando la bandera --no-project antes del nombre del script

Declaración y gestión de dependencias del script

  • Si se necesitan paquetes externos, se pueden especificar dependencias para la ejecución usando la opción de línea de comandos --with
  • También admite restricciones de versión específicas, y se pueden indicar varias dependencias repitiendo la opción
  • Es posible agregar dependencias adicionales en el entorno del proyecto y, si no se desea, se puede controlar con --no-project

Inline Script Metadata (formato PEP 723)

  • Python ahora admite un formato estándar para declarar dependencias o versión de Python dentro del propio script
  • Con uv init --script se puede crear fácilmente un script con metadatos inline incluidos
  • Con uv add --script se pueden agregar y gestionar las dependencias necesarias del script en formato TOML
  • Si hay metadatos inline, las dependencias del proyecto se ignoran y solo se aplican las dependencias del script

Declaración y gestión de la versión de Python

  • Se puede especificar la versión de Python deseada dentro del script o al momento de ejecutarlo
  • Si la versión indicada no existe, se descarga y configura automáticamente

Escritura de scripts ejecutables directamente con shebang

  • Usando shebang (#!...) se puede crear un ejecutable directo con el método uv run --script
  • También en este caso se pueden declarar en la parte superior del script las dependencias y la versión de Python

Soporte para índices de paquetes y autenticación

  • Con la opción --index se puede usar un índice de paquetes personalizado
  • La información del índice también se incluye en los metadatos
  • Si se requiere autenticación, se puede consultar la documentación correspondiente

Fijación de dependencias (Lock) y mejora de la reproducibilidad

  • Con uv lock --script se pueden crear y gestionar archivos lock a nivel de script
  • Después, al ejecutar o agregar dependencias, el archivo lock se reutiliza y se actualiza si hace falta
  • Se ofrece la opción exclude-newer (excluir lanzamientos posteriores a una fecha específica) para la reproducibilidad de versiones
  • La fecha se especifica con una marca de tiempo RFC 3339

Flexibilidad de la versión de Python

  • En cada ejecución se puede indicar el uso de cualquier versión de Python mediante una opción de línea de comandos
  • Ejemplo: uv run --python 3.10 example.py

Soporte para Windows

  • Los scripts con extensión .pyw se ejecutan con pythonw en Windows
  • También se pueden ejecutar scripts con interfaz gráfica junto con sus dependencias

Documentación de referencia

  • Para un uso más detallado de los comandos, se puede consultar la documentación de referencia del CLI y la guía de ejecución/instalación de la herramienta

Conclusión

  • uv es una herramienta que administra de forma automática y sencilla el entorno de ejecución, las dependencias, las versiones, los índices de paquetes y la reproducibilidad de los scripts de Python, mejorando al mismo tiempo la productividad y la confiabilidad

7 comentarios

 
ihabis02 2025-07-24

Yo también me pasé de pip a uv, y de verdad solo por la velocidad ya vale la pena hacer el cambio.

 
idunno 2025-07-23

Lo mencionan seguido, así que ayer lo probé por primera vez... de verdad es rapidísimo. Caray...

 
ytuniverse 2025-07-23

Creo que ya he visto más de 5 publicaciones sobre uv aquí;;;

 
pmc7777 2025-07-23

Dejando de lado las demás funciones, solo por la velocidad ya hay razones suficientes para usarlo.
Si me dijeran que vuelva a usar pip, ya no podría de ninguna manera.

Para la gestión de paquetes del sistema de conda lo estoy reemplazando con flake.nix, y salvo en trabajo colaborativo o en proyectos ya mantenidos con conda+pip, personalmente creo que de ahora en adelante usaré uv+nix.

 
ndrgrd 2025-07-22

Últimamente he reemplazado la mayoría de las ejecuciones de Python con uv, y de verdad es muy rápido.
Aunque hay algunas funciones avanzadas que no son totalmente compatibles, en la mayoría de los casos funciona casi igual.

 
GN⁺ 2025-07-22
Comentarios en Hacker News
  • He comprobado que la función de "declarar dependencias del script" es realmente útil
    Como se muestra en la guía oficial, se pueden indicar las dependencias como comentarios al inicio del código Python, de esta manera

    # /// script
    # dependencies = [
    #  "requests<3",
    #  "rich",
    # ]
    # ///
    import requests, rich
    # ... script
    

    Si guardas este archivo como script.py y luego lo ejecutas con "uv run script.py", las dependencias declaradas se instalan como por arte de magia en un entorno virtual temporal y se puede ejecutar de inmediato
    Esto implementa PEP 723 de Python, y Claude 4 también conoce este truco, así que si le pides que escriba “un script de Python con dependencias inline del script”, lo genera correctamente
    Por ejemplo, puedes pedirle código que use httpx y click para descargar archivos grandes y mostrar una barra de progreso
    Antes de Claude 4, para algo así hacían falta un proyecto personalizado e instrucciones aparte, pero ahora ya no
    También se puede consultar un caso de uso más detallado

    • El modo shebang también me parece realmente útil
      Si agregas un shebang en la primera línea del script como se muestra abajo, puedes ejecutarlo como ./script.sh

      #!/usr/bin/env -S uv run --script
      # /// script
      # dependencies = [
      #  "requests<3",
      #  "rich",
      # ]
      # ///
      import requests, rich
      # ... script
      
    • Ojalá usara el mismo formato que un archivo requirements
      Si fuera así, para usuarios que no tengan uv también se podría ofrecer en un comentario simple un one-liner para instalar lo mismo con pip
      Algo como pip install -r <(head myscript.py) podría funcionar

    • En realidad, PEP723 ya no solo está soportado por uv, que está ganando mucha atención últimamente, sino también por pipx y hatch
      Y herramientas como pip-tools también lo incluyen en su hoja de ruta
      (ver el issue relacionado)

    • La primera vez que lo vi, por un momento pensé que lo de al lado de requests era un emoji de corazón

    • Me parece una idea realmente genial
      Pero me gustaría que algún día se adoptara como sintaxis integrada del lenguaje en vez de comentarios mágicos
      Los comentarios se ven algo desordenados
      Claro, entiendo que desde la perspectiva de las herramientas los comentarios mágicos son más fáciles de parsear, y que Python core no tiene demasiado conocimiento de packaging, entre otras consideraciones estructurales, pero aun así me gustaría que algún día existiera sintaxis integrada

  • Estoy de acuerdo con este enfoque
    Aunque en Python el archivo requirements.txt no es estrictamente obligatorio, es una pena que si no se gestiona bien sea muy común que las cosas terminen rompiéndose
    Ver tuit relacionado

  • Quiero compartir una trampa con la que me topé usando este enfoque
    Lo utilicé en un script para reiniciar el router cuando se caía internet, pero como la instalación de dependencias depende de tener conexión, si no hay red el script mismo deja de funcionar
    Lo detecté a tiempo y lo resolví preinstalando las dependencias, pero para que no les pase lo mismo, recomendaría no usar esto en entornos realmente airgapped (sin conectividad de red)
    Incluso con caché de uv, puede haber fallos de caché

    • Si usas la opción uv run --offline, puede aprovechar dependencias cacheadas y ejecutarse sin revisar si hay versiones nuevas
      Lo mismo funciona con uvx (uvx --offline ...)

    • Entiendo que, si vas a usar dependencias o venv, por lo menos una vez hay que ejecutarlo con conexión a internet para que luego pueda usarse también offline

  • Últimamente siento que varias piezas del ecosistema de Python están empezando a encajar cada vez mejor entre sí
    Con la combinación de Marimo y dependencias de script de uv, he empezado a crear herramientas reproducibles de reporting/diagnóstico que otros equipos pueden usar fácilmente

  • Esta es la función de uv que más me gusta, tanto que por esto terminé cambiándome a uv
    Tenía varios scripts de git-hooks, cada uno con dependencias distintas, y no quería instalarlas en el venv principal
    Con solo agregar #!/usr/bin/env -S uv run --script --python 3.13, a los devs solo había que decirles que hicieran brew install uv, y ya podían usarlo directamente dentro del script sin crear un venv aparte

    • ¿Alguien sabe por qué hace falta el flag -S?
      En mi entorno BSD sentí que /usr/bin/env -S uv run --python 3.11 python y /usr/bin/env uv run --python 3.11 python terminaban lanzando el Python shell igual, así que el resultado parecía el mismo
      Incluso viendo el manual de env no me quedó clara la interpretación, así que agradecería cualquier dato útil
      (Aquí -S sirve para dividir los argumentos por espacios)

    • Gracias a UV, una migración grande de Python que originalmente pensábamos hacer a golang pudo reducirse
      Sobre todo para trabajos en forma de scripts pequeños, ya no hace falta moverlos

    • Estoy convencido de que esta función es realmente una “killer feature”

  • Si entre las dependencias está Pytorch, este enfoque puede tener algunas limitaciones
    Aunque Uv ofrece un muy buen soporte integrado para Pytorch, solo con el encabezado del script no hay una forma clara de elegir el índice de wheels más adecuado (CPU, CUDA, ROCm, etc.)

  • Ojalá VS Code pudiera reconocer fácilmente el venv que uv crea automáticamente
    Ahora mismo la extensión de Python marca en rojo todos los imports de terceros
    Como solución temporal, busco manualmente la ruta del venv dentro del directorio de caché de uv y la registro, pero si el venv se recrea con frecuencia, hay que repetirlo una y otra vez y resulta molesto

    • Puedes encontrar la ruta del entorno con uv python find --script "${filePath}"
      Estoy desarrollando una extensión que detecta eso automáticamente en VS Code y lo activa
  • Me encanta tanto esta función de UV
    Incluso jupyter notebook se puede ejecutar en una sola línea, sin instalación aparte, así

    uv run --with jupyter jupyter notebook
    

    Todo se instala en un entorno virtual temporal y después se limpia
    Si lo ejecutas dentro de un proyecto, también reconoce automáticamente las dependencias de ese proyecto

    • Aunque en realidad no se limpia de forma completamente “limpia”, ya que la carpeta de caché de uv puede seguir creciendo

    • Yo también uso mucho cosas como uv run --with ipython --with boto3 ipython, y de verdad ahorra muchísimo tiempo

  • Hace poco encontré un pequeño problema relacionado con uv run
    Si ejecutas un script fuera de la carpeta del proyecto, busca pyproject.toml en el directorio de trabajo actual y no en la ubicación real del archivo del script
    Por eso, un script que guarda sus dependencias en pyproject.toml puede no funcionar correctamente si lo ejecutas desde fuera con algo como “uv run path/to/my/script.py”
    Esto se soluciona si siempre usas dependencias inline o si pasas el argumento --project, pero es incómodo tener que escribir la ruta del script dos veces
    uv es excelente, pero este pequeño detalle sí se siente bastante molesto

  • Ya venía usando con satisfacción el shebang específico de uv y el enfoque de dependencias dentro del script
    Además de eso, me impresionó aún más que con uv lock --script example.py se pueda crear incluso un archivo lock dedicado a un solo script
    Me sorprende que, después de más de 20 años de packaging en Python, una experiencia tan natural haya aparecido recién ahora

    • Me da curiosidad el caso de uso para generar un lock para un solo script
      En nuestra organización también usamos las dependencias del lockfile para escanearlas con trivy fs uv.lock y así prevenir la ejecución de código con CVE conocidos