To use pytask for larger projects, organize the project as a Python package. This tutorial explains the minimal setup.
If you want to use pytask with a collection of scripts, you can skip this lesson and move to the next section of the tutorials.
!!! note
In case you are thinking about developing multiple packages in the project that should
be separated (one for dealing with the data, one for the analysis and a package for the
pytask tasks), consider using a [workspace](../how_to_guides/using_workspaces.md).
The following directory tree gives an overview of the project's different parts.
my_project
│
├───.pytask # Generated by pytask.
│
├───bld
│ └────...
│
├───src
│ └───my_project
│ ├────__init__.py
│ ├────config.py
│ └────...
│
├───pytask.lock # Generated by pytask.
│
└───pyproject.toml
Create the project files and folders for your project or start from pytask's
cookiecutter-pytask-project
template or any other
linked template or example project.
pytask creates the .pytask folder and pytask.lock file later when you run tasks.
The src directory only contains a folder for the project in which the tasks and source
files reside. The nested structure is called the "src layout" and is the preferred way
to structure Python packages.
It contains a config.py or a similar module to store the project's configuration. You
should define paths pointing to the source and build directory of the project. They
later help to define other paths.
from pathlib import Path
SRC = Path(__file__).parent.resolve()
BLD = SRC.joinpath("..", "..", "bld").resolve()!!! note
If you want to know more about the "`src` layout" and why it is NASA-approved, read
[this article by Hynek Schlawack](https://hynek.me/articles/testing-packaging/) or this
[setuptools article](https://setuptools.pypa.io/en/latest/userguide/package_discovery.html#src-layout).
The variable BLD defines the path to a build directory called bld. It is best
practice to store any outputs of the tasks in your project in a different folder than
src.
Whenever you want to regenerate your project, delete the build directory and rerun pytask.
The configuration depends on your package manager choice. Each creates different files to manage dependencies and project metadata.
=== "uv"
Create a `pyproject.toml` file for project configuration and dependencies:
```{ .toml .annotate title="pyproject.toml" }
[project]
name = "my_project"
version = "0.1.0"
requires-python = ">=3.10"
dependencies = ["pytask"]
[build-system]
requires = ["uv_build"] # (1)!
build-backend = "uv_build"
[tool.pytask.ini_options]
paths = ["src/my_project"] # (2)!
```
1. `uv_build` provides the build backend for this minimal package layout.
1. `paths` tells pytask where to collect task modules.
=== "pixi"
Create a `pixi.toml` file for project configuration:
```{ .toml .annotate title="pixi.toml" }
[project]
name = "my_project"
version = "0.1.0"
requires-python = ">=3.10"
channels = ["conda-forge"] # (1)!
platforms = ["linux-64", "osx-64", "osx-arm64", "win-64"]
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
[dependencies]
pytask = "*"
python = ">=3.10"
[tool.pytask.ini_options]
paths = ["src/my_project"] # (2)!
```
1. `conda-forge` is the default package source for the pixi environment.
1. `paths` tells pytask where to collect task modules.
The [tool.pytask.ini_options] section tells pytask to look for tasks in
src/my_project. You will learn more about configuration in the
configuration tutorial.
The pytask.lock file records which tasks and products are up to date. pytask updates
it during builds so later runs can skip unchanged tasks. This file should be kept in
version control.
!!! seealso
You will later learn how to sync the state of the lockfile with the project state with
the [`pytask lock`](../reference_guides/commands.md#pytask-lock) command or how the
lockfile enables you to
[move a project to another machine](../how_to_guides/move_project_to_another_machine.md),
but don't worry about it for now.
The .pytask directory is where pytask stores some of its ephemeral information. You do
not need to interact with it, nor do you need to keep it in version control.
=== "uv"
```console
$ uv sync
```
The command installs all packages. uv will ensure that all your dependencies are
up-to-date.
=== "pixi"
```console
$ pixi install
```
pixi automatically creates the environment and installs dependencies. pixi will ensure
that all your dependencies are up-to-date.