Ciencia reproducible con Pixi

Problema

Escribo este código

(numpy < 1.24)

>>> import numpy as np
>>> np.msort([1, 3, 2])
array([1, 2, 3])

Un tiempo después

(numpy == 1.24)

>>> np.msort([1, 3, 2])
<stdin>:1: DeprecationWarning: msort is
deprecated, use np.sort(a, axis=0) instead
array([1, 2, 3])

Otro tiempo después

(numpy >= 2.0)

>>> np.msort([1, 3, 2])
Traceback (most recent call last):
    np.msort([1, 3, 2])
    ^^^^^^^^
AttributeError: module 'numpy' has no
attribute 'msort'. Did you mean: 'sort'?

Solución: compartir el environment

Compartiendo el environment

¿Qué necesito? (manifest)

matplotlib >= 3.0

¿Qué versión instalé? (lockfile)

matplotlib  3.7.1
numpy       2.0.4


¿Por qué los dos?

  • lockfile:

    para obtener exactamente lo mismo

  • manifest:

    para modificar el environment

¿Cómo hacerlos?

Tool Manifest Lockfile
pip requirements.txt pip freeze > lock.txt
conda environment.yaml conda env export > lock.yaml
uv pyproject.toml uv.lock
pixi pixi.toml pixi.lock

Workflow con pixi

Estructura de carpeta

mi-proyecto/
mi-proyecto/
└── pixi.toml
mi-proyecto/
├── pixi.toml
└── pixi.lock
mi-proyecto/
├── pixi.toml
├── pixi.lock
└── .pixi/
    └── envs/
        └── default/
            ├── ...  # acá están instalados
            └── ...  # python, numpy y demás
  • pixi init
  • pixi add ‘numpy<2’
  • pixi lock
  • pixi install
  • pixi run python
pixi.toml
[workspace]
channels = ["conda-forge"]
platforms = ["osx-arm64"]

[dependencies]
pixi.toml
[workspace]
channels = ["conda-forge"]
platforms = ["osx-arm64"]

[dependencies]
numpy = "<2"
pixi.lock
version: 6
environments:
  default:
    channels:
    - url: https://prefix.dev/conda-forge/
    packages:
      osx-arm64:
      - conda: https://prefix.dev/conda-forge/osx-arm64/bzip2-1.0.8-h99b78c6_7.conda
      - conda: https://prefix.dev/conda-forge/noarch/ca-certificates-2025.4.26-hbd8a1cb_0.conda
      - conda: https://prefix.dev/conda-forge/osx-arm64/libblas-3.9.0-31_h10e41b3_openblas.conda
      - conda: https://prefix.dev/conda-forge/osx-arm64/libcblas-3.9.0-31_hb3479ef_openblas.conda
      - conda: https://prefix.dev/conda-forge/osx-arm64/libcxx-20.1.3-ha82da77_0.conda
      - conda: https://prefix.dev/conda-forge/osx-arm64/libexpat-2.7.0-h286801f_0.conda
      - conda: https://prefix.dev/conda-forge/osx-arm64/libffi-3.4.6-h1da3d7d_1.conda
      - conda: https://prefix.dev/conda-forge/osx-arm64/libgfortran-14.2.0-heb5dd2a_105.conda
      - conda: https://prefix.dev/conda-forge/osx-arm64/libgfortran5-14.2.0-h2c44a93_105.conda
      - conda: https://prefix.dev/conda-forge/osx-arm64/liblapack-3.9.0-31_hc9a63f6_openblas.conda
      - conda: https://prefix.dev/conda-forge/osx-arm64/liblzma-5.8.1-h39f12f2_0.conda
      - conda: https://prefix.dev/conda-forge/osx-arm64/libopenblas-0.3.29-openmp_hf332438_0.conda
      - conda: https://prefix.dev/conda-forge/osx-arm64/libsqlite-3.49.1-h3f77e49_2.conda
      - conda: https://prefix.dev/conda-forge/osx-arm64/libzlib-1.3.1-h8359307_2.conda
      - conda: https://prefix.dev/conda-forge/osx-arm64/llvm-openmp-20.1.3-hdb05f8b_0.conda
      - conda: https://prefix.dev/conda-forge/osx-arm64/ncurses-6.5-h5e97a16_3.conda
      - conda: https://prefix.dev/conda-forge/osx-arm64/numpy-1.26.4-py312h8442bc7_0.conda
      - conda: https://prefix.dev/conda-forge/osx-arm64/openssl-3.5.0-h81ee809_0.conda
      - conda: https://prefix.dev/conda-forge/osx-arm64/python-3.12.10-hc22306f_0_cpython.conda
      - conda: https://prefix.dev/conda-forge/noarch/python_abi-3.12-7_cp312.conda
      - conda: https://prefix.dev/conda-forge/osx-arm64/readline-8.2-h1d1bf99_2.conda
      - conda: https://prefix.dev/conda-forge/osx-arm64/tk-8.6.13-h5083fa2_1.conda
      - conda: https://prefix.dev/conda-forge/noarch/tzdata-2025b-h78e105d_0.conda

¿Por qué pixi?

¿No puedo usar pip/conda?

Con pixi

pixi add 'numpy < 2'
pixi lock
pixi install
pixi run python

Con conda

# escribo 'numpy < 2' a mano en `environment.yaml` 
conda update --file environment.yaml
conda export > lock.yaml
conda run python


Con conda

  • pasos independientes
  • los puedo omitir/olvidar
# no lo agrego a `environment.yaml` 
conda install 'numpy < 2'
# conda export -> me lo olvido
conda run python

Con pixi

  • pasos automáticos
pixi add 'numpy < 2'
# pixi lock     (auto)
# pixi install  (auto)
pixi run python

Más cosas

  • Multi-environment

    Ejemplo: para correr en CPU y en GPU

  • Conda y PyPI (Python Package Index)

    pixi add        numpy  # (desde conda)
    pixi add --pypi numpy  # (desde PyPI)
  • Tasks

    Definir tareas o comandos, con posibles dependencias

pixi.toml
[tasks]
calibrate = "python calibrate.py"

[tasks.start]
cmd = "python start.py"
depends-on = ["calibrate"]
instrucciones
Descargar el proyecto (incluyendo):
- pixi.toml
- pixi.lock

Correr:
- pixi run start
equivale a
pixi install
pixi shell  # activa el environment
python calibrate.py
python start.py
exit