Reading Time: 10 minutes

La gestión de las dependencias en Python científico es una de las partes más importantes de la investigación reproducible. Una simulación puede fallar meses después porque cambiaron las versiones de paquetes, se cambió un intérprete de Python o una biblioteca numérica actualizada de manera que afecte a los resultados.

Esta guía explica cómo los archivos de bloqueo, los entornos y los administradores de paquetes modernos ayudan a los investigadores a mantener los flujos de trabajo científicos de Python reproducibles, portátiles y más fáciles de mantener.

Comida clave

  • Los archivos de bloqueo son uno de los pasos más impactantes para los flujos de trabajo científicos de Python reproducibles.
  • uv es un administrador de paquetes moderno y rápido y se usa cada vez más como una alternativa a PIP, PIP-tools y poesía.
  • PEP 751 introduce un formato de archivo de bloqueo estandarizado, pylock.toml, para reducir la fragmentación de la herramienta.
  • Conda sigue siendo importante para proyectos científicos de Python con dependencias que no son de Python como C, C++, MPI, HDF5 y CUDA.
  • Su elección de herramienta debe coincidir con su flujo de trabajo: uv para velocidad y reproducibilidad, conda para pilas científicas y de HPC y poesía para canalizaciones de publicación madura.

El modo de falla oculta en Scientific Python

Cada investigador de computación científica eventualmente ve el mismo problema. Una simulación funcionó el mes pasado, pero ahora falla con una discrepancia de versión. Peor aún, puede que aún se ejecute, pero produzca resultados sutilmente diferentes.

Esto no es solo un inconveniente. Es un fracaso de reproducibilidad. El entorno computacional cambió, incluidas las versiones de paquetes, los intérpretes de Python o las dependencias de nivel inferior. Su código se rompió o produjo resultados silenciosos que ya no son equivalentes a la ejecución original.

La causa raíz generalmente son las dependencias no ancladas. Incluso cuando el código está controlado por versiones, el trabajo permanece vinculado a una máquina específica y en un momento dado si el entorno no es reproducible.

Python científico hace que este problema sea especialmente serio. A diferencia de muchos proyectos web, la informática científica a menudo depende de cadenas complejas de bibliotecas numéricas, paquetes compilados y compilaciones sensibles al hardware. Numpy, Scipy, Fipy, HDF5, MPI, OpenBLA y versiones específicas de Python deben trabajar juntas.

La solución es gestionar las dependencias deliberadamente. Utilice Lockfiles para congelar versiones exactas, realizar un seguimiento de los entornos en el control de versiones y documentar cómo se debe volver a crear el entorno.

¿Qué es un archivo de bloqueo?

Un archivo de bloqueo es una instantánea del entorno de software exacto de un proyecto. Registra las versiones específicas de todas las dependencias, incluidas las subdependencias, que se instalaron la última vez que se configuró el proyecto.

Piense en ello como una receta congelada para su configuración de software. Cualquiera puede volver a crear el mismo entorno más tarde, incluso si las versiones de paquetes han cambiado ascendente.

sin archivos de bloqueo

# requirements.txt without a lockfile
numpy>=1.25.0
scipy>=1.11.0
fipy>=4.3.0

# On another machine or after a month:
pip install -r requirements.txt

# This might install newer versions:
# numpy 1.26.x, scipy 1.12.x, or different dependency builds

Este tipo de configuración permite que las versiones de paquetes cambien. El código aún puede ejecutarse, pero pueden cambiar el comportamiento numérico, la precisión, el comportamiento del solucionador o las internas de dependencia.

con archivos de bloqueo

# uv.lock or another lockfile records exact resolved versions

uv sync

# Anyone who runs the sync command gets the same resolved environment

Esto es importante para los proyectos de simulación porque las bibliotecas numéricas pueden cambiar las rutas de código en todas las versiones. El comportamiento de punto flotante puede diferir entre las compilaciones. Los solucionadores de PDE y los marcos científicos también pueden comportarse de manera diferente entre los lanzamientos.

Un archivo de bloqueo reduce esta incertidumbre al hacer que la instalación sea determinista.

El panorama de gestión de dependencias de Python

El ecosistema de Python tiene varias opciones prácticas de gestión de dependencias. Cada herramienta tiene diferentes fortalezas, y la elección correcta depende de si el proyecto es Python puro, centrado en HPC, orientado a paquetes o construido para reproducirse a largo plazo.

UV: la opción rápida y moderna

uv es un administrador de paquetes basado en óxido construido por Astral. Su objetivo es reemplazar varias herramientas comunes de Python, incluidas PIP, PIP-Tools, PiPX, PYENV y virtualenv, con un solo flujo de trabajo rápido.

Los investigadores están cambiando a uv por varias razones:

  1. velocidad. uv puede instalar paquetes mucho más rápido que los flujos de trabajo basados en PIP tradicionales, especialmente con el almacenamiento en caché.
  2. Archivo de bloqueo universal. Un solo uv.lock puede admitir instalaciones reproducibles en todas las plataformas.
  3. Compatibilidad de PIP. Los comandos como uv pip install facilitan la migración.
  4. Gestión de versiones de Python. uv Puede instalar y administrar intérpretes de Python, lo que reduce la necesidad de herramientas separadas.
  5. Instalación independiente. uv no requiere que Python se instale primero.

Use uv para nuevos proyectos donde la velocidad, la reproducibilidad y la simple migración de PIP Matter.

Es especialmente útil para:

  • Nuevos proyectos de simulación.
  • Tuberías CI/CD donde el tiempo de instalación es importante.
  • Proyectos que necesitan gestión de dependencias y gestión de versiones de Python juntos.
  • Equipos que migran de PIP o PIP-Tools.

Flujo de trabajo UV básico

# Install uv
curl -LsSf https://astral.sh/uv/install.sh | sh

# Create a new project with Python 3.11
uv init my-simulation --python 3.11
cd my-simulation

# Add dependencies
uv add numpy scipy fipy

# Generate a lockfile
uv lock

# Sync to install from the lockfile
uv sync

La principal compensación es que la poesía todavía tiene flujos de trabajo de publicación maduros y manejo avanzado de grupos de dependencias. Si mantiene un paquete científico de Python para PYPI, la poesía puede seguir siendo atractiva.

Poesía: el director de proyecto establecido

La poesía es una herramienta completa de gestión de proyectos. Maneja la resolución de dependencias, los entornos virtuales, la creación de paquetes y la publicación en PYPI.

Los investigadores todavía eligen la poesía por varias razones:

  1. grupos de dependencias. La poesía puede separar el desarrollo, las pruebas, la documentación y las dependencias de CI limpiamente.
  2. Flujo de trabajo de publicación. Tiene soporte integrado para construir y publicar paquetes.
  3. ecosistema maduro. La poesía tiene años de uso de la producción, amplia documentación y una gran comunidad.

Usa la poesía cuando:

  • Publica un paquete de Python en PYPI.
  • Necesita una gestión de grupos de dependencias madura.
  • Su equipo valora un largo historial y una documentación establecida.

La compensación es la velocidad. La poesía puede tardar más de uv para las instalaciones en frío, la generación de archivos de bloqueo y las adiciones de paquetes. Para proyectos pequeños, esto puede no importar. Para proyectos grandes y canalizaciones de CI, la diferencia puede volverse notable.

Conda: el elemento científico

Conda sigue siendo una de las herramientas más importantes para Python científico, especialmente cuando el proyecto necesita dependencias que no sean de Python.

Conda es útil para la investigación porque puede administrar paquetes de Python, paquetes R, bibliotecas compiladas, compiladores, MPI, HDF5, CUDA y otras dependencias a nivel de sistema en un entorno.

Conda es importante cuando:

  • Necesita dependencias que no sean de Python como C, C++, MPI, HDF5, FFTW o CUDA.
  • Se dirige a clústeres de HPC.
  • Sus bibliotecas científicas dependen de un código C o FORTRAN compilado.
  • Trabajas en Python y R.

La compensación es que la conda puede ser más lenta que uv para la resolución de la dependencia de Python pura y puede que no produzca archivos de bloqueo universales multiplataforma con la misma facilidad.

Flujo de trabajo básico de la CONDA

# Create environment
conda create -n my-sim python=3.11
conda activate my-sim

# Install packages, including non-Python dependencies
conda install numpy scipy hdf5 openmpi

# Export to environment file
conda env export --no-builds | grep -v "prefix:" > environment.yml

# Restore the environment
conda env create -f environment.yml

Pip-Tools: la opción minimalista

pip-tools Puente los flujos de trabajo de PIP tradicionales y los archivos de bloqueo. Es ligero y permanece cerca de la interfaz PIP.

Use herramientas PIP cuando:

  • Quieres un enfoque simple.
  • Estás migrando desde PIP y no quieres aprender una herramienta más grande.
  • Su proyecto es pequeño y no necesita grupos de dependencias avanzados.

La compensación es que las herramientas pip pueden generar archivos de salida específicos de la plataforma. También es menos completo que la poesía o uv.

PEP 751: El futuro de los archivos de bloqueo

PEP 751 propone un formato de archivo estandarizado para grabar dependencias de Python para que los entornos puedan instalarse de forma reproducible. Este formato se llama pylock.toml.

lo que resuelve

Las herramientas de dependencia de Python han utilizado históricamente diferentes formatos de archivo de bloqueo. PDM, PIP Freeze, PIP-tools, poesía y uv todos los entornos de enfoque se bloquean de manera diferente.

Esto crea varios problemas:

  • Bloqueo de vendedor. Puede ser difícil cambiar entre herramientas.
  • Fragmentación de herramientas. Los escáneres de seguridad y las herramientas de automatización pueden admitir solo algunos formatos.
  • Dificultad de auditoría. Los diferentes formatos tienen diferentes sintaxis y convenciones.

PEP 751 propone pylock.toml como un formato estandarizado.

Por qué es importante para Python científico

El formato propuesto es útil para la investigación porque es:

  • Legible por humanos, usando TOML.
  • generado por máquina, por lo que las herramientas pueden escribir una salida consistente.
  • consumible por herramientas que no son de Python.
  • Seguro por diseño, con hashes criptográficos para la protección de la cadena de suministro.
  • Lo suficientemente flexible como para representar múltiples entornos o grupos de dependencias.

Una vez que se adopta ampliamente, pylock.toml puede reducir la necesidad de formatos de archivo de bloqueo específicos de la herramienta. Para los investigadores, esto significa una mejor interoperabilidad. Un archivo de bloqueo podría ser consumido por cualquier herramienta compatible y auditado más fácilmente por servicios externos.

El espectro de reproducibilidad

La reproducibilidad es un espectro. El nivel correcto depende del riesgo, la duración del proyecto y los requisitos de publicación.

Nivel Enfoque Costo reproducibilidad mejor para
Bueno Dependencias de documentos en Léame Mínimo verificación manual Scripts y tutoriales rápidos
Mejor Archivo de entorno como requirements.txt o environment.yml Bajo Instalación automatizada Proyectos compartidos y colaboradores
Mejor Entorno Lockfile Plus controlado por versiones Moderar reproducción exacta Publicaciones y archivos a largo plazo
Máximo Contenedorización con Docker o Singularidad Elevado Aislamiento fuerte HPC y flujos de trabajo publicados

Para proyectos de investigación, el mínimo es fijar versiones exactas en requirements.txt o environment.yml. El enfoque recomendado es utilizar uv lock o exportación de conda para generar un archivo de entorno reproducible. La mejor práctica es rastrear ese archivo en Git y documentar cómo recrear el entorno en el archivo Léame.

Flujos de trabajo prácticos para proyectos científicos

Flujo de trabajo 1: Nuevo proyecto de simulación con UV

# Initialize project
uv init my-simulation --python 3.11
cd my-simulation

# Add core dependencies
uv add numpy scipy matplotlib

# Add scientific libraries
uv add fipy mpmath

# Generate lockfile
uv lock

# Add dev dependencies
uv add --group dev pytest black ruff

# Commit everything
git add pyproject.toml uv.lock
git commit -m "Initial project structure with pinned dependencies"

Esto funciona porque el archivo uv.lock está comprometido con git. Cualquiera que clone el repositorio y ejecute uv sync obtiene las mismas versiones resueltas.

Flujo de trabajo 2: Proyecto HPC con Conda y Singularidad

# On your workstation
conda create -n hpc-sim python=3.11
conda activate hpc-sim
conda install numpy scipy hdf5 openmpi

# Export environment
conda env export --no-builds | grep -v "prefix:" > environment.yml

# Build Singularity image from Docker
docker build -t my-sim:latest .
singularity build my-sim.sif docker://my-sim:latest

# Transfer to HPC cluster
scp my-sim.sif hpc-cluster:/scratch/

Esto funciona porque Conda administra las dependencias de la estación de trabajo, mientras que Singularity proporciona una contenedorización compatible con HPC. El archivo environment.yml se puede controlar y volver a crear en otro sistema.

Flujo de trabajo 3: migración de PIP a UV

# Start with existing requirements.txt
pip install uv

# Replace pip with uv for installs
uv pip install -r requirements.txt

# Generate a uv lockfile
uv lock

# From now on, use uv sync instead of pip install
uv sync

Esta ruta de migración es simple porque uv es compatible con muchos flujos de trabajo de estilo PIP. El archivo uv.lock se convierte en la única fuente de verdad para el entorno.

Errores comunes y cómo evitarlos

Error 1: Uso de dependencias no ancladas

# WRONG: Allows automatic updates
numpy>=1.0
scipy>=1.0

# RIGHT: Pin exact versions
numpy==1.26.4
scipy==1.11.4

Los cambios de versión menores pueden alterar el comportamiento numérico, los criterios de convergencia o la precisión del punto flotante. Fija las versiones exactas cuando la reproducibilidad importa.

Error 2: no cometer ningún archivo de bloqueo

Si su repositorio contiene pyproject.toml pero no lockfile, su proyecto no es totalmente reproducible. Un archivo de bloqueo es el requisito mínimo para las compilaciones deterministas.

Genere un archivo de bloqueo y confirme:

uv lock  # or conda export
git add uv.lock  # or environment.yml
git commit -m "Add lockfile for reproducible environment"

Error 3: ignorar las subdependencias

Incluso si fija paquetes de nivel superior, las subdependencias aún pueden cambiar el comportamiento.

# If you pin fipy but not its dependencies:
# numpy, mpmath, and other packages may upgrade independently

Utilice una herramienta que resuelva y ancla el árbol de dependencia completo, como uv, Conda o Poesía.

Error 4: entornos específicos de la plataforma

Algunas herramientas pueden generar una salida específica de la plataforma. Si desarrolla en macOS pero implementa en Linux, los archivos de entorno pueden fallar o resolver de manera diferente.

Utilice herramientas que admitan archivos de bloqueo multiplataforma o generen archivos de bloqueo en la plataforma de destino.

Error 5: Dependencias de datos externas

Si una simulación depende de API externas o de bases de datos que cambian, la reproducibilidad puede romperse incluso cuando el entorno de Python está bloqueado.

Snapshot datos externos cuando sea posible. Si eso no es posible, utilice puntos de enlace de API versionados y documente la versión exacta o la fecha de acceso.

Lo que recomendamos: Un marco de decisión

Utilice este marco de decisión al elegir una herramienta de gestión de dependencias para un proyecto científico de Python.

  1. ¿Necesita dependencias que no son de Python como C, C++, MPI, CUDA, HDF5 o FFTW?

    • Sí: use Conda, o use Conda dentro de Docker o Singularity.
    • No: Continúe con la siguiente pregunta.
  2. ¿Estás publicando un paquete de Python en PYPI?

    • Sí: Considere la poesía para los flujos de trabajo de publicación maduros o uv para la velocidad.
    • No: Continúe con la siguiente pregunta.
  3. ¿Estás trabajando en canalizaciones CI/CD?

    • Sí: use uv porque las instalaciones más rápidas pueden reducir el tiempo de CI.
    • No: O uv, Conda o poesía pueden funcionar dependiendo del proyecto.
  4. ¿Qué tan importante es la compatibilidad multiplataforma?

    • Alto: use uv donde un archivo de bloqueo universal se ajuste a sus necesidades.
    • Moderado: Conda puede funcionar bien, especialmente en sistemas de investigación tipo UNIX.

Para la mayoría de los nuevos proyectos de investigación, uv es un valor predeterminado fuerte cuando necesita velocidad y reproducibilidad. Para proyectos de HPC o flujos de trabajo con dependencias que no son de Python, empareja conda con la contenedorización.

Resumen

La gestión de dependencias en Scientific Python no es opcional. Es una base de investigación reproducible.

Los puntos más importantes son:

  1. Los archivos de bloqueo son esenciales. Fija las versiones exactas y síguelas en Git.
  2. uv es una opción moderna y fuerte para entornos rápidos y reproducibles.
  3. Conda sigue siendo vital para las pilas científicas con dependencias que no son de Python.
  4. PEP 751 tiene como objetivo unificar los formatos de archivo de bloqueo a través de pylock.toml.
  5. Un README con instrucciones de instalación claras es la documentación mínima que necesita todo proyecto.

Comience por auditar los proyectos actuales. Compruebe si los entornos están documentados y las dependencias están ancladas. Convierta un proyecto para usar un archivo de bloqueo. El costo inicial vale la pena cuando usted u otro investigador necesita volver a ejecutar la simulación meses o años después con confianza.

Guías relacionadas

Referencias y lectura adicional