v0.4.0
News
pytask became three years old in July, which is a suitable event to rethink pytask's design and blow dust off of some of its oldest components.
Here are the highlights of v0.4.0 🚀 ⭐
Highlights
New interfaces for products.
Every argument can be declared as a product with the new' Product' annotation. The path can be passed as a default value.
from pathlib import Path
from pytask import Product
from typing_extensions import Annotated
def task_hello_earth(path: Annotated[Path, Product] = Path("hello_earth.txt")):
path.write_text("Hello, earth!")
More explanation can be found at https://tinyurl.com/yrezszr4.
It is also possible to use the return of the task function as a product, which allows wrapping any third-party function as a task function. Read more about it here: https://tinyurl.com/pytask-return.
from pathlib import Path
from pytask import Product
from typing_extensions import Annotated
def task_hello_earth() -> Annotated[str, Path("hello_earth.txt")]:
return "Hello, earth!"
Every task argument is a dependency
In older pytask versions, only paths were treated as task dependencies. That meant when you passed other arguments to the task, and they changed, it did not trigger a rerun of the task.
Now, every argument to a task can be a dependency, and you can hash them if they should trigger a rerun. It is explained in https://tinyurl.com/pytask-hash.
from pathlib import Path
from typing import Annotated
from pytask import Product
from pytask import PythonNode
def task_example(
text: Annotated[str, PythonNode(value="Hello, World", hash=True)],
path: Annotated[Path, Product] = Path("file.txt"),
) -> None:
path.write_text(text)
A new functional interface
The functional interface for pytask has been reworked and accepts a list of task functions. You can use it within your terminal or a Jupyter notebook. Read this guide to learn more about it: https://tinyurl.com/pytask-functional.
from pathlib import Path
from typing import Annotated
from pytask import build
def create_text() -> Annotated[str, Path("hello_earth.txt")]:
return "Hello, earth!"
session = build(tasks=[create_text])
Custom Nodes through Protocols
In the newest version, nodes (dependencies and products) and tasks follow protocols. It allows for customizations like PickleNode
s that store any Python object as a pickle file and inject the object into the task when used as a dependency. It is explained in more detail in this guide: https://tinyurl.com/pytask-custom-nodes.
Other notable changes
- Python 3.12 is supported, and support for Python 3.7 is dropped.
@pytask.mark.depends_on
and@pytask.mark.produces
are deprecated. There are better options to define dependencies and products explained in https://tinyurl.com/yrezszr4.@pytask.mark.task
is also deprecated and replaced byfrom pytask import task
and@task
.
What's Changed
- Remove Python 3.7 support and add a new action for mamba. by @tobiasraabe in #323
- Replace pony with sqlalchemy>=1.4.36. by @tobiasraabe in #387
- Remove
@pytask.mark.parametrize
. by @tobiasraabe in #391 - Parse dependencies from all args if
depends_on
is not used. by @tobiasraabe in #384 - Add products with
typing.Annotation
. by @tobiasraabe in #394 - Refactor pybaum to
_pytask.tree_util
. by @tobiasraabe in #395 - Replace pybaum with optree and add paths to PythonNode names. by @tobiasraabe in #396
- Add support for
NamedTuple
and attrs classes in@pytask.mark.task(kwargs=...)
. by @tobiasraabe in #397 - Deprecate decorators for
depends_on
andproduces
. by @tobiasraabe in #398 - Use protocols instead of ABCs. by @tobiasraabe in #402
- Allow tasks to return products. by @tobiasraabe in #404
- Tracking changes in v0.4.0. by @tobiasraabe in #400
- Bump peter-evans/create-pull-request from 5.0.1 to 5.0.2 by @dependabot in #390
- [pre-commit.ci] pre-commit autoupdate by @pre-commit-ci in #388
- Allow to use prefix trees as nodes to parse function returns. by @tobiasraabe in #406
- Remove
.value
fromNode
protocol. by @tobiasraabe in #408 - Make
.from_annot
an optional feature of nodes. by @tobiasraabe in #409 - Allow to pass functions to
PythonNode(hash=...)
. by @tobiasraabe in #410 - Add protocols for tasks. by @tobiasraabe in #412
- Remove scripts to generate
.svg
s. by @tobiasraabe in #413 - Allow more ruff rules. by @tobiasraabe in #414
- A new functional interface. by @tobiasraabe in #411
- Deprecate
@pytask.mark.task
in favor of@pytask.task
. by @tobiasraabe in #417 - Simplify and fix code in
dag.py
. by @tobiasraabe in #418 - Convert
DeprecationWarning
toFutureWarning
for deprecated decorators. by @tobiasraabe in #420 - Remove deprecation warning for
produces
. by @tobiasraabe in #421 - Document new interface. by @tobiasraabe in #392
- Fix
import_path
. by @tobiasraabe in #424 - Publish
pytask.tree_util
. by @tobiasraabe in #426 - Fix type annotations of
task.depends_on
andtask.produces
. by @tobiasraabe in #427 - Document functional interface. by @tobiasraabe in #423
- Update example in
README.md
. by @tobiasraabe in #428 - Add better error message when
node.state()
throws error during DAG validation. by @tobiasraabe in #429 - Update parts of the documentation. by @tobiasraabe in #430
- Enable colors in WSL. by @tobiasraabe in #431
- Fix type checking for
pytask.mark.x
. by @tobiasraabe in #432 - Fix ids of
PythonNode
s. by @tobiasraabe in #433 - Add support for Python 3.12. by @tobiasraabe in #434
- Fix detection of task functions. by @tobiasraabe in #437
- Clarify some types. by @tobiasraabe in #438
- Refine typing. by @tobiasraabe in #440
Full Changelog: v0.3.2...v0.4.0