Why Build Python Packages with Pixi?
Building Python packages with Pixi offers unique advantages:- Cross-language support - Manage Python packages alongside Rust, C++, R, and other languages
- Unified tooling - Build both conda and Python packages with the same tool
- Conda ecosystem - Access packages from conda-forge, not just PyPI
- Workspace support - Develop multiple interdependent packages together
Creating Your First Python Package
This project uses a src-layout, but Pixi supports both flat- and src-layouts.
from dataclasses import dataclass, fields
from rich.console import Console
from rich.table import Table
@dataclass
class Person:
name: str
age: int
city: str
def main() -> None:
console = Console()
people = [
Person("John Doe", 30, "New York"),
Person("Jane Smith", 25, "Los Angeles"),
Person("Tim de Jager", 35, "Utrecht"),
]
table = Table()
for column in fields(Person):
table.add_column(column.name)
for person in people:
table.add_row(person.name, str(person.age), person.city)
console.print(table)
[project]
name = "python_rich"
version = "0.1.0"
requires-python = ">= 3.11"
dependencies = ["rich"] # (1)!
[project.scripts]
rich-example-main = "python_rich:main" # (2)!
[build-system] # (3)!
build-backend = "hatchling.build"
requires = ["hatchling"]
main functionhatchling works well with minimal configThis generates a
pixi.toml file. You can also integrate everything into pyproject.toml by prepending tool.pixi. to each table.[workspace] # (1)!
channels = ["https://prefix.dev/conda-forge"]
platforms = ["linux-64", "osx-64", "osx-arm64", "win-64"]
preview = ["pixi-build"]
[dependencies] # (2)!
python_rich = { path = "." }
[tasks] # (3)!
start = "rich-example-main"
[package] # (4)!
name = "python_rich"
version = "0.1.0"
[package.build] # (5)!
backend = { name = "pixi-build-python", version = "0.4.*" }
[package.host-dependencies] # (6)!
hatchling = "==1.26.3"
[package.run-dependencies] # (7)!
rich = "13.9.*"
pyproject.tomlpixi-build-python backend converts Python packages to conda packagesAdvanced Configuration
Using Custom Backend Channels
For the latest backend features:Noarch Packages
For pure Python packages without compiled extensions:Custom Build Configuration
Real-World Example
Here’s a complete example from thearray-api-extra package:
pixi.toml
Understanding Host vs Run Dependencies
Why specify dependencies twice?
Why specify dependencies twice?
Python packages need to declare dependencies in two places:In In This allows the same package to work in both ecosystems.
pyproject.toml (for PyPI):pixi.toml (for conda):What are host-dependencies?
What are host-dependencies?
Host dependencies are needed during the build process. For Python:These come from conda channels, ensuring consistent build environments.See dependency types for details.
Integration with pyproject.toml
You can integrate Pixi configuration intopyproject.toml:
pyproject.toml
Next Steps
Workspaces
Combine multiple packages in one workspace
Dependency Types
Understand build, host, and run dependencies
C++ Integration
Mix Python with C++ packages
Build Variants
Build against multiple Python versions
Common Issues
Package not found after build
Package not found after build
Ensure your package is added to workspace dependencies:
Import errors at runtime
Import errors at runtime
Add missing dependencies to
run-dependencies: