Skip to main content

pure-Python packages

This guide shows you how to create a conda-forge recipe for a pure-Python package (a package that contains only Python code and no compiled extensions).

Auto-generate the recipe

Using rattler-build generate-recipe (generates v1 format):

rattler-build generate-recipe pypi <package-name> --write

For more information about the v1 recipe format, see the rattler-build documentation. Note that the generated recipe is a starting point and may need adjustments based on the package's specific requirements.

Recipe template

Here is a minimal template for a pure-Python package v1 recipe:

recipe.yaml
schema_version: 1

context:
version: 1.2.3

package:
name: example-package
version: ${{ version }}

source:
url: https://pypi.org/packages/source/e/example-package/example_package-${{ version }}.tar.gz
sha256: 12ff4785d337a1bb490bb7e9c2b1ee5da3112e94a8622f26a6c77f5d2fc6842a

build:
noarch: python
number: 0
script: ${{ PYTHON }} -m pip install . -vv --no-deps --no-build-isolation

requirements:
host:
- python ${{ python_min }}.*
- pip
run:
- python >=${{ python_min }}

tests:
- python:
imports:
- example-package
python_version:
- ${{ python_min }}.*
- *
pip_check: true

about:
homepage: https://example.com/example-package
license: BSD-3-Clause
license_file: LICENSE
summary: Single-line summary of the package.
description: |
One or two paragraphs with more information about the package.
repository: https://github.com/example/example-package/
documentation: https://example.com/example-package-docs/

extra:
recipe-maintainers:
- LandoCalrissian

The context section

This section defines variables that can be reused throughout the recipe. For conda-forge recipes, you should at least define the version variable:

context:
version: 1.2.3

These variables can be referenced using the ${{ variable_name }} syntax elsewhere in the recipe.

The package section

package:
name: example-package
version: ${{ version }}
  • name: The conda package name, typically the PyPI package name with hyphens.
  • version: Use the version variable defined in the context section.

The source section

source:
url: https://pypi.org/packages/source/e/example-package/example_package-${{ version }}.tar.gz
sha256: 12ff4785d337a1bb490bb7e9c2b1ee5da3112e94a8622f26a6c77f5d2fc6842a
  • url: The PyPI source URL follows the pattern https://pypi.org/packages/source/<first-letter>/<package-name>/<package-name>-<version>.tar.gz. Note that the package name in the URL may use underscores instead of hyphens (e.g., example_package vs example-package).
  • sha256: The SHA256 hash of the source archive. Run openssl sha256 <artifact> to get its hash after downloading the source file.

The build section

build:
noarch: python
number: 0
script: ${{ PYTHON }} -m pip install . -vv --no-deps --no-build-isolation
  • noarch: python: Indicates that this is a pure-Python package and can be installed on any architecture.
  • number: The build number, starting at 0. Increment this when rebuilding the same version with recipe changes.
  • script: The build script uses pip to install the package:
    • ${{ PYTHON }} -m pip install: Ensures the correct Python interpreter is used.
    • -vv: Verbose output for debugging build issues.
    • --no-deps: Prevents pip from installing dependencies itself, as these are specified in the requirements.run section.
    • --no-build-isolation: Ensures that the host environment is used to build the package (instead of creating a new virtualenv).

Entry points

If your package has a command line interface, you can add entry points to the build section:

build:
entry_points:
- example-cli=example_package.cli:main

This creates a example-cli command that calls the main function from example_package.cli.

The requirements section

requirements:
host:
- python ${{ python_min }}.*
- hatchling
- pip
run:
- python >=${{ python_min }}
- click >=7.0
- requests
- numpy

Pure-Python packages typically only need host and run requirements. There is no build section needed, as pure-Python packages do not require a compiler.

Host requirements

  • python ${{ python_min }}.*: Use python_min to build against the minimum supported Python version.
  • Build backend dependencies: Specify the build system your package uses (e.g., hatchling, flit, setuptools, poetry-core, uv-build). Check your package's pyproject.toml to see which build backend is specified in the [build-system] section.
  • pip: Required to run the pip install command in the build script.

Run requirements

Add your package's runtime dependencies here. These should match what's specified in your package's pyproject.toml or setup.py.

  • python >=${{ python_min }}: Define the Python version dependency as minimum version and higher. Don't specify an upper bound unless absolutely necessary to avoid future conflicts.

The tests section

tests:
- python:
imports:
- example-package
python_version:
- ${{ python_min }}.*
- *
pip_check: true
  • imports: List the Python modules to import to verify the package installed correctly. This ensures basic functionality.
  • python_version: Test against the minimum supported Python version to ensure compatibility. Also test against the latest Python version (*) to catch any issues with newer releases.
  • pip_check: Runs pip check to ensure all dependencies are satisfied and there are no conflicts.

Command line tests

If your package provides CLI tools, you can add command line tests:

tests:
- script:
- example-cli --help
- example-cli --version

The extra section

A schema-free area for storing non-conda-specific metadata in standard YAML form. In conda-forge recipes, you have to add at least the recipe-maintainers field with the GitHub usernames of the maintainers:

extra:
recipe-maintainers:
- LandoCalrissian

More information