pyproject_toml.md•10.5 kB
We support the use of the `pyproject.toml` as our manifest file in pixi.
This allows the user to keep one file with all configuration.
The `pyproject.toml` file is a standard for Python projects.
We don't advise to use the `pyproject.toml` file for anything else than python projects, the `pixi.toml` is better suited for other types of projects.
## Initial setup of the `pyproject.toml` file
When you already have a `pyproject.toml` file in your project, you can run `pixi init` in a that folder. Pixi will automatically
- Add a `[tool.pixi.workspace]` section to the file, with the platform and channel information required by pixi;
- Add the current project as an editable pypi dependency;
- Add some defaults to the `.gitignore` and `.gitattributes` files.
If you do not have an existing `pyproject.toml` file , you can run `pixi init --format pyproject` in your project folder. In that case, Pixi will create a `pyproject.toml` manifest from scratch with some sane defaults.
## Python dependency
The `pyproject.toml` file supports the `requires_python` field.
Pixi understands that field and automatically adds the version to the dependencies.
This is an example of a `pyproject.toml` file with the `requires_python` field, which will be used as the python dependency:
```toml title="pyproject.toml"
[project]
name = "my_project"
requires-python = ">=3.9"
[tool.pixi.workspace]
channels = ["conda-forge"]
platforms = ["linux-64", "osx-arm64", "osx-64", "win-64"]
```
Which is equivalent to:
```toml title="equivalent pixi.toml"
[workspace]
name = "my_project"
channels = ["conda-forge"]
platforms = ["linux-64", "osx-arm64", "osx-64", "win-64"]
[dependencies]
python = ">=3.9"
```
## Dependency section
The `pyproject.toml` file supports the `dependencies` field.
Pixi understands that field and automatically adds the dependencies to the workspace as `[pypi-dependencies]`.
This is an example of a `pyproject.toml` file with the `dependencies` field:
```toml title="pyproject.toml"
[project]
name = "my_project"
requires-python = ">=3.9"
dependencies = [
"numpy",
"pandas",
"matplotlib",
]
[tool.pixi.workspace]
channels = ["conda-forge"]
platforms = ["linux-64", "osx-arm64", "osx-64", "win-64"]
```
Which is equivalent to:
```toml title="equivalent pixi.toml"
[workspace]
name = "my_project"
channels = ["conda-forge"]
platforms = ["linux-64", "osx-arm64", "osx-64", "win-64"]
[pypi-dependencies]
numpy = "*"
pandas = "*"
matplotlib = "*"
[dependencies]
python = ">=3.9"
```
You can overwrite these with conda dependencies by adding them to the `dependencies` field:
```toml title="pyproject.toml"
[project]
name = "my_project"
requires-python = ">=3.9"
dependencies = [
"numpy",
"pandas",
"matplotlib",
]
[tool.pixi.workspace]
channels = ["conda-forge"]
platforms = ["linux-64", "osx-arm64", "osx-64", "win-64"]
[tool.pixi.dependencies]
numpy = "*"
pandas = "*"
matplotlib = "*"
```
This would result in the conda dependencies being installed and the pypi dependencies being ignored.
As Pixi takes the conda dependencies over the pypi dependencies.
## Optional dependencies
If your python project includes groups of optional dependencies, Pixi will automatically interpret them as [Pixi features](../reference/pixi_manifest.md#the-feature-table) of the same name with the associated `pypi-dependencies`.
You can add them to Pixi environments manually, or use `pixi init` to setup the workspace, which will create one environment per feature. Self-references to other groups of optional dependencies are also handled.
For instance, imagine you have a project folder with a `pyproject.toml` file similar to:
```toml title="pyproject.toml"
[project]
name = "my_project"
dependencies = ["package1"]
[project.optional-dependencies]
test = ["pytest"]
all = ["package2","my_project[test]"]
```
Running `pixi init` in that project folder will transform the `pyproject.toml` file into:
```toml title="pyproject.toml"
[project]
name = "my_project"
dependencies = ["package1"]
[project.optional-dependencies]
test = ["pytest"]
all = ["package2","my_project[test]"]
[tool.pixi.workspace]
channels = ["conda-forge"]
platforms = ["linux-64"] # if executed on linux
[tool.pixi.environments]
default = {features = [], solve-group = "default"}
test = {features = ["test"], solve-group = "default"}
all = {features = ["all"], solve-group = "default"}
```
In this example, three environments will be created by pixi:
- **default** with 'package1' as pypi dependency
- **test** with 'package1' and 'pytest' as pypi dependencies
- **all** with 'package1', 'package2' and 'pytest' as pypi dependencies
All environments will be solved together, as indicated by the common `solve-group`, and added to the lock file. You can edit the `[tool.pixi.environments]` section manually to adapt it to your use case (e.g. if you do not need a particular environment).
## Dependency groups
If your python project includes dependency groups, Pixi will automatically interpret them as [Pixi features](../reference/pixi_manifest.md#the-feature-table) of the same name with the associated `pypi-dependencies`.
You can add them to Pixi environments manually, or use `pixi init` to setup the workspace, which will create one environment per dependency group.
For instance, imagine you have a project folder with a `pyproject.toml` file similar to:
```toml
[project]
name = "my_project"
dependencies = ["package1"]
[dependency-groups]
test = ["pytest"]
docs = ["sphinx"]
dev = [{include-group = "test"}, {include-group = "docs"}]
```
Running `pixi init` in that project folder will transform the `pyproject.toml` file into:
```toml
[project]
name = "my_project"
dependencies = ["package1"]
[dependency-groups]
test = ["pytest"]
docs = ["sphinx"]
dev = [{include-group = "test"}, {include-group = "docs"}]
[tool.pixi.workspace]
channels = ["conda-forge"]
platforms = ["linux-64"] # if executed on linux
[tool.pixi.environments]
default = {features = [], solve-group = "default"}
test = {features = ["test"], solve-group = "default"}
docs = {features = ["docs"], solve-group = "default"}
dev = {features = ["dev"], solve-group = "default"}
```
In this example, four environments will be created by pixi:
- **default** with 'package1' as pypi dependency
- **test** with 'package1' and 'pytest' as pypi dependencies
- **docs** with 'package1', 'sphinx' as pypi dependencies
- **dev** with 'package1', 'sphinx' and 'pytest' as pypi dependencies
All environments will be solved together, as indicated by the common `solve-group`, and added to the lock file. You can edit the `[tool.pixi.environments]` section manually to adapt it to your use case (e.g. if you do not need a particular environment).
## Example
As the `pyproject.toml` file supports the full Pixi spec with `[tool.pixi]` prepended an example would look like this:
```toml title="pyproject.toml"
[project]
name = "my_project"
requires-python = ">=3.9"
dependencies = [
"numpy",
"pandas",
"matplotlib",
"ruff",
]
[tool.pixi.workspace]
channels = ["conda-forge"]
platforms = ["linux-64", "osx-arm64", "osx-64", "win-64"]
[tool.pixi.dependencies]
compilers = "*"
cmake = "*"
[tool.pixi.tasks]
start = "python my_project/main.py"
lint = "ruff lint"
[tool.pixi.system-requirements]
cuda = "11.0"
[tool.pixi.feature.test.dependencies]
pytest = "*"
[tool.pixi.feature.test.tasks]
test = "pytest"
[tool.pixi.environments]
test = ["test"]
```
## Build-system section
The `pyproject.toml` file normally contains a `[build-system]` section. Pixi will use this section to build and install the project if it is added as a pypi path dependency.
If the `pyproject.toml` file does not contain any `[build-system]` section, Pixi will fall back to [uv](https://github.com/astral-sh/uv)'s default, which is equivalent to the below:
```toml title="pyproject.toml"
[build-system]
requires = ["setuptools >= 40.8.0"]
build-backend = "setuptools.build_meta:__legacy__"
```
Including a `[build-system]` section is **highly recommended**. If you are not sure of the [build-backend](https://packaging.python.org/en/latest/tutorials/packaging-projects/#choosing-build-backend) you want to use, including the `[build-system]` section below in your `pyproject.toml` is a good starting point.
`pixi init --format pyproject` defaults to `hatchling`.
The advantages of `hatchling` over `setuptools` are outlined on its [website](https://hatch.pypa.io/latest/why/#build-backend).
```toml title="pyproject.toml"
[build-system]
build-backend = "hatchling.build"
requires = ["hatchling"]
```
## Development dependencies with `[tool.uv.sources]`
Because pixi is using `uv` for building its `pypi-dependencies`, one can use the `tool.uv.sources` section to specify sources for any pypi-dependencies referenced from the main pixi manifest.
### Why is this useful?
When you are setting up a monorepo of some sort and you want to be able for source dependencies to reference each other, you need to use the `[tool.uv.sources]` section to specify the sources for those dependencies. This is because `uv` handles both the resolution of PyPI dependencies and the building of any source dependencies.
### Example
Given a source tree:
```
.
├── main_project
│ └── pyproject.toml (references a)
├── a
│ └── pyproject.toml (has a dependency on b)
└── b
└── pyproject.toml
```
Concretely what this looks like in the `pyproject.toml` for `main_project`:
```toml
[tool.pixi.pypi-dependencies]
a = { path = "../a" }
```
Then the `pyproject.toml` for `a` should contain a `[tool.uv.sources]` section.
```toml
[project]
name = "a"
# other fields
dependencies = ["flask", "b"]
[tool.uv.sources]
# Override the default source for flask with main git branch
flask = { git = "github.com/pallets/flask", branch = "main" }
# Reference to b
b = { path = "../b" }
```
More information about what is allowed in this sections is available in the [uv docs](https://docs.astral.sh/uv/concepts/projects/dependencies/#dependency-sources)
!!! note
The main `pixi.toml` or `pyproject.toml` is parsed directly by pixi and not processed by `uv`.
This means that you **cannot** use the `[tool.uv.sources]` section in the main `pixi.toml` or `pyproject.toml`.
This is a limitation we are aware of, feel free to open an issue if you would like support for [this](https://github.com/prefix-dev/pixi/issues/new/choose).