- 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
Yo también me pasé de pip a uv, y de verdad solo por la velocidad ya vale la pena hacer el cambio.
Lo mencionan seguido, así que ayer lo probé por primera vez... de verdad es rapidísimo. Caray...
Creo que ya he visto más de 5 publicaciones sobre uv aquí;;;
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.Uv - herramienta de empaquetado de Python ultrarrápida implementada en Rust
Revolucionando el flujo de trabajo de desarrollo en Python con UV
Usar scripts de Python con uv y PEP 723
Un año usando uv: ventajas, desventajas y puntos a considerar al migrar
Ú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.
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
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
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 funcionarEn 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 nuevasLo 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 pythony/usr/bin/env uv run --python 3.11 pythonterminaban lanzando el Python shell igual, así que el resultado parecía el mismoIncluso 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
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í
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 tiempoHace poco encontré un pequeño problema relacionado con
uv runSi 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 vecesuv 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.pyse pueda crear incluso un archivo lock dedicado a un solo scriptMe sorprende que, después de más de 20 años de packaging en Python, una experiencia tan natural haya aparecido recién ahora
En nuestra organización también usamos las dependencias del lockfile para escanearlas con
trivy fs uv.locky así prevenir la ejecución de código con CVE conocidos