Writing a Python package#
Writing a Python package is fairly straightforward, especially for "Python-only" packages.
In the second example we will build a package for numpy
which contains compiled code.
A Python-only package#
The following recipe uses the noarch: python
setting to build a noarch
package that can be installed on any platform without modification.
This is very handy for packages that are pure Python and do not contain any compiled extensions.
Additionally, noarch: python
packages work with a range of Python versions (contrary to packages with compiled extensions that are tied to a specific Python version).
context:
version: "8.1.2"
package:
name: ipywidgets
version: ${{ version }}
source:
url: https://pypi.io/packages/source/i/ipywidgets/ipywidgets-${{ version }}.tar.gz
sha256: d0b9b41e49bae926a866e613a39b0f0097745d2b9f1f3dd406641b4a57ec42c9
build:
noarch: python # (1)!
script: pip install . -v
requirements:
# note that there is no build section
host:
- pip
- python >=3.7
- setuptools
- wheel
run:
- comm >=0.1.3
- ipython >=6.1.0
- jupyterlab_widgets >=3.0.10,<3.1.0
- python >=3.7
- traitlets >=4.3.1
- widgetsnbextension >=4.0.10,<4.1.0
tests:
- python:
imports:
- ipywidgets # (2)!
about:
homepage: https://github.com/ipython/ipywidgets
license: BSD-3-Clause
license_file: LICENSE
summary: Jupyter Interactive Widgets
description: |
ipywidgets are interactive HTML widgets for Jupyter notebooks and the IPython kernel.
documentation: https://ipywidgets.readthedocs.io/en/latest/
- The
noarch: python
line tellsrattler-build
that this package is pure Python and can be one-size-fits-all.noarch
packages can be installed on any platform without modification which is very handy. - The
imports
section in the tests is used to check that the package is installed correctly and can be imported.
Running the recipe#
To build this recipe, simply run:
A Python package with compiled extensions#
We will build a package for numpy
– which contains compiled code.
Since compiled code is python
version-specific, we will need to specify the python
version explicitly.
The best way to do this is with a "variant_config.yaml" file:
This will replace any python
found in the recipe with the versions specified in the variants.yaml
file.
context:
version: 2.0.1
default_abi_level: 1.21
package:
name: numpy
version: ${{ version }}
source:
- url: https://github.com/numpy/numpy/releases/download/v${{ version }}/numpy-${{ version }}.tar.gz
sha256: 485b87235796410c3519a699cfe1faab097e509e90ebb05dcd098db2ae87e7b3
build:
python:
entry_points:
- f2py = numpy.f2py.f2py2e:main # [win]
- numpy-config = numpy._configtool:main
requirements:
build:
- ${{ compiler('c') }}
- ${{ compiler('cxx') }}
# note: some `host` dependencies that run at build time (e.g., `cython`, `meson-python`)
# should ideally be in `build` instead, this is because cross compilation of
# Python packages in conda-forge uses `crossenv` rather than regular cross compilation.
host:
# note: variant is injected here!
- python
- pip
- meson-python
- pkg-config
- python-build
- cython
- libblas
- libcblas
- liblapack
run:
- python
run_exports:
- numpy >=${{ default_abi_level }},<3.0.0a0
tests:
- python:
imports:
- numpy
- numpy.fft
- numpy.linalg
- numpy.random
- numpy.ctypeslib
- script:
- f2py -v
- numpy-config --cflags
about:
homepage: http://numpy.org/
license: BSD-3-Clause
license_file: LICENSE.txt
summary: The fundamental package for scientific computing with Python.
documentation: https://numpy.org/doc/stable/
repository: https://github.com/numpy/numpy
The build script for Unix:
mkdir builddir
$PYTHON -m build -w -n -x \
-Cbuilddir=builddir \
-Csetup-args=-Dblas=blas \
-Csetup-args=-Dlapack=lapack
$PYTHON -m pip install dist/numpy*.whl
The build script for Windows:
mkdir builddir
%PYTHON% -m build -w -n -x ^
-Cbuilddir=builddir ^
-Csetup-args=-Dblas=blas ^
-Csetup-args=-Dlapack=lapack
if %ERRORLEVEL% neq 0 exit 1
:: `pip install dist\numpy*.whl` does not work on windows,
:: so use a loop; there's only one wheel in dist/ anyway
for /f %%f in ('dir /b /S .\dist') do (
pip install %%f
if %ERRORLEVEL% neq 0 exit 1
)
Running the recipe#
Running this recipe with the variant config file will build a total of 2 numpy
packages:
At the beginning of the build process, rattler-build
will print the following message to show you the variants it found:
Found variants:
numpy-1.26.4-py311h5f8ada8_0
╭─────────────────┬───────────╮
│ Variant ┆ Version │
╞═════════════════╪═══════════╡
│ python ┆ 3.11 │
│ target_platform ┆ osx-arm64 │
╰─────────────────┴───────────╯
numpy-1.26.4-py312h440f24a_0
╭─────────────────┬───────────╮
│ Variant ┆ Version │
╞═════════════════╪═══════════╡
│ python ┆ 3.12 │
│ target_platform ┆ osx-arm64 │
╰─────────────────┴───────────╯