Tasks manifest¶
Build and check manifest¶
fractal-task-tools includes a set of task models to be used in the task_list.py module. An example may look like
from fractal_task_tools.task_models import ConverterCompoundTask
TASK_LIST = [
ConverterCompoundTask(
name="Convert Cellvoyager to OME-Zarr",
executable_init="tasks/cellvoyager_to_ome_zarr_init.py",
executable="tasks/cellvoyager_to_ome_zarr_compute.py",
meta_init={"cpus_per_task": 1, "mem": 4000},
meta={"cpus_per_task": 1, "mem": 4000},
category="Conversion",
modality="HCS",
tags=["Yokogawa", "Cellvoyager", "2D", "3D"],
docs_info="file:task_info/convert_cellvoyager_to_ome_zarr.md",
),
]
Once the task_list.py module is defined, fractal-task-tools also includes a command-line interface for creating and checking a manifest file.
The create command can be used as in
fractal-manifest create --package my-task-package
__FRACTAL_MANIFEST__.json, in the root folder where the package my-task-package is installed.
The check command can be used as in
fractal-manifest check --package my-task-package
JSON Schemas¶
Each task listed in the manifest is associated to a JSON Schema that represents its arguments (or two schemas, if the task has both a non-parallel and a parallel unit). These schemas are stored in the args_schema_non_parallel and args_schema_parallel properties of each task.
This kind of schemas are not used at task runtime (where the validity of task arguments is typically enforced by the @pydantic.validate_call decorator), but they form the basis for constructing the fractal-web user interface that lets a user edit task arguments.
The args_schema_version property, which is set at the manifest level, determines a set of constraints on the task-arguments schemas. What is described below applies to the current one as of fractal-task-tools=0.4.0a3, named args_schema_version = "pydantic_v2". The discussion about an upcoming specification is tracked at https://github.com/fractal-analytics-platform/fractal-task-tools/issues/97.
Restrictions on task functions¶
Some patterns are forbidden in the Python functions representing Fractal tasks.
Argument names¶
The following keywords are reserved and cannot be used for a task-argument name:
"args""kwargs""v__args""v__kwargs""v__duplicate_kwargs""v__positional_only"
Union types¶
When top-level task arguments or nested properties have a union type annotation, it must be one of the two supported cases described below
Supported case 1: Plain binary unions with None¶
The first supported case is the one of an union of a given type and None. If the default is set, it must be None. Here are some examples of supported and non-supported type annotations for task arguments:
from pydantic import Field
def task_function_ok(
arg1: int | None,
arg2: int | None = None,
arg3: int | None = Field(default=None),
arg4: int | None = Field(default_factory=lambda: None),
arg5: Optional[int],
arg6: Annotated[int | None, "a comment"],
arg7: Annotated[int | None, "a comment"] = None,
arg8: Annotated[int | None, "a comment"] = Field(default=None),
arg9: int | None = Field(default_factory=lambda _: 7), # Since the factory requires additional data, it is ignored and the default is not populated.
):
pass
def task_function_bad(
arg1: int | str,
arg2: int | str | None,
arg3: int | None = 1,
arg4: int | None = Field(default=1),
arg5: int | None = Field(default_factory=lambda: 1),
):
pass
Supported case 2: Tagged unions¶
The second supported case is the one of a tagged union, see e.g. https://docs.pydantic.dev/latest/concepts/unions/#discriminated-unions-with-str-discriminators.
Here is a supported example:
from typing import Literal
from typing import Annotated
class Model1(BaseModel):
label: Literal["label1"] = "label1"
field1: int = 1
class Model2(BaseModel):
label: Literal["label2"] = "label2"
field1: int
field2: str
MyTaggedUnion = Annotated[Model1 | Model2, Field(discriminator="label")]
def task_function_ok(
arg1: MyTaggedUnion,
):
pass
Customizations of schema generation¶
The general approach for customizing the Pydantic schema-generation procedure is described at https://docs.pydantic.dev/latest/concepts/json_schema/#customizing-the-json-schema-generation-process.
In fractal-task-tools, this includes the following customizations (which are applied at all levels, that is, both for top-level task arguments and for nested properties):
- When the generated schema includes an
anyOfarray, we remove any{"type": "null"}element from it. - When the generated schema includes a
defaultvalue which is set tonull, we remove it. - The the type annotation is a
Fieldwith adefault_factorywhich is set and which does not require any argument, we compute thedefaultvalue asdefault_factory().