{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Functional Interface\n", "\n", "pytask offers a functional interface to users who want more flexibility than is given by a command line interface. It even allows you to run pytask from a Python interpreter or a Jupyter notebook like this article here.\n", "\n", "\n", "Let's see how it works!" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "from pathlib import Path\n", "from typing import Annotated\n", "\n", "import pytask\n", "from pytask import task" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Here is a small workflow where two tasks create two text files and the third task merges both of them into one file.\n", "\n", "One important bit to note here is that the second task is created from a lambda function. So, you can use dynamically defined functions to create tasks.\n", "\n", "It also shows how easy it is to wrap any third-party function where you have no control over the signature, but you can still easily wrap them with pytask." ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "def task_create_first_file() -> Annotated[str, Path(\"first.txt\")]:\n", " return \"Hello, \"\n", "\n", "\n", "task_create_second_file = task(\n", " name=\"task_create_second_file\", produces=Path(\"second.txt\")\n", ")(lambda *x: \"World!\")\n", "\n", "\n", "def task_merge_files(\n", " first: Path = Path(\"first.txt\"), second: Path = Path(\"second.txt\")\n", ") -> Annotated[str, Path(\"hello_world.txt\")]:\n", " return first.read_text() + second.read_text()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now, let us execute this little workflow." ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
────────────────────────────────────────────── Start pytask session ───────────────────────────────────────────────\n", "\n" ], "text/plain": [ "\u001b[39m────────────────────────────────────────────── \u001b[0mStart pytask session\u001b[39m ───────────────────────────────────────────────\u001b[0m\n" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
Platform: darwin -- Python 3.12.12, pytask 0.6.0, pluggy 1.6.0\n",
"\n"
],
"text/plain": [
"Platform: darwin -- Python 3.12.12, pytask 0.6.0, pluggy 1.6.0\n"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"Root: /Users/tobiasr/git/pytask\n", "\n" ], "text/plain": [ "Root: \u001b[35m/Users/tobiasr/git/\u001b[0m\u001b[95mpytask\u001b[0m\n" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "\n" ], "text/plain": [] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
Collected 3 tasks.\n",
"\n"
],
"text/plain": [
"Collected 3 tasks.\n"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"\n",
"\n"
],
"text/plain": [
"\n"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "c58c8439b3e24cbd9bd96afd98ed0b06",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"Output()"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"\n"
],
"text/plain": []
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"╭─────────────────────────┬─────────╮\n",
"│ Task │ Outcome │\n",
"├─────────────────────────┼─────────┤\n",
"│ task_create_first_file │ . │\n",
"│ task_create_second_file │ . │\n",
"│ task_merge_files │ . │\n",
"╰─────────────────────────┴─────────╯\n",
"\n"
],
"text/plain": [
"╭─────────────────────────┬─────────╮\n",
"│\u001b[1m \u001b[0m\u001b[1mTask \u001b[0m\u001b[1m \u001b[0m│\u001b[1m \u001b[0m\u001b[1mOutcome\u001b[0m\u001b[1m \u001b[0m│\n",
"├─────────────────────────┼─────────┤\n",
"│ \u001b]8;id=73604;file://None\u001b\\task_create_first_file \u001b]8;;\u001b\\ │ \u001b[38;2;19;124;57m. \u001b[0m │\n",
"│ \u001b]8;id=609946;file://None\u001b\\task_create_second_file\u001b]8;;\u001b\\ │ \u001b[38;2;19;124;57m. \u001b[0m │\n",
"│ \u001b]8;id=378329;file://None\u001b\\task_merge_files \u001b]8;;\u001b\\ │ \u001b[38;2;19;124;57m. \u001b[0m │\n",
"╰─────────────────────────┴─────────╯\n"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"\n",
"\n"
],
"text/plain": [
"\n"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"───────────────────────────────────────────────────────────────────────────────────────────────────────────────────\n",
"\n"
],
"text/plain": [
"\u001b[2m───────────────────────────────────────────────────────────────────────────────────────────────────────────────────\u001b[0m\n"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"╭─────────── Summary ────────────╮\n", "│ 3 Collected tasks │\n", "│ 3 Succeeded (100.0%) │\n", "╰────────────────────────────────╯\n", "\n" ], "text/plain": [ "\u001b[38;2;19;124;57m╭─\u001b[0m\u001b[38;2;19;124;57m──────────\u001b[0m\u001b[1;38;2;242;242;242m Summary \u001b[0m\u001b[38;2;19;124;57m───────────\u001b[0m\u001b[38;2;19;124;57m─╮\u001b[0m\n", "\u001b[38;2;19;124;57m│\u001b[0m \u001b[38;2;242;242;242m \u001b[0m\u001b[38;2;242;242;242m3\u001b[0m\u001b[38;2;242;242;242m \u001b[0m\u001b[38;2;242;242;242m \u001b[0m\u001b[38;2;242;242;242mCollected tasks\u001b[0m\u001b[38;2;242;242;242m \u001b[0m\u001b[38;2;242;242;242m \u001b[0m\u001b[38;2;242;242;242m \u001b[0m\u001b[38;2;242;242;242m \u001b[0m \u001b[38;2;19;124;57m│\u001b[0m\n", "\u001b[38;2;19;124;57m│\u001b[0m \u001b[38;2;242;242;242;48;2;19;124;57m \u001b[0m\u001b[38;2;242;242;242;48;2;19;124;57m3\u001b[0m\u001b[38;2;242;242;242;48;2;19;124;57m \u001b[0m\u001b[38;2;242;242;242;48;2;19;124;57m \u001b[0m\u001b[38;2;242;242;242;48;2;19;124;57mSucceeded \u001b[0m\u001b[38;2;242;242;242;48;2;19;124;57m \u001b[0m\u001b[38;2;242;242;242;48;2;19;124;57m \u001b[0m\u001b[38;2;242;242;242;48;2;19;124;57m(100.0%)\u001b[0m\u001b[38;2;242;242;242;48;2;19;124;57m \u001b[0m \u001b[38;2;19;124;57m│\u001b[0m\n", "\u001b[38;2;19;124;57m╰────────────────────────────────╯\u001b[0m\n" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
──────────────────────────────────────────── Succeeded in 0.03 seconds ────────────────────────────────────────────\n",
"\n"
],
"text/plain": [
"\u001b[38;2;19;124;57m──────────────────────────────────────────── \u001b[0m\u001b[38;2;19;124;57mSucceeded in 0.03 seconds\u001b[0m\u001b[38;2;19;124;57m ────────────────────────────────────────────\u001b[0m\n"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"session = pytask.build(\n",
" tasks=[task_create_first_file, task_merge_files, task_create_second_file]\n",
")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The information on the executed workflow can be found in the `session`."
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"Session(config={'pm': ────────────────────────────────────────────── Start pytask session ───────────────────────────────────────────────\n", "\n" ], "text/plain": [ "\u001b[39m────────────────────────────────────────────── \u001b[0mStart pytask session\u001b[39m ───────────────────────────────────────────────\u001b[0m\n" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
Platform: darwin -- Python 3.12.12, pytask 0.6.0, pluggy 1.6.0\n",
"\n"
],
"text/plain": [
"Platform: darwin -- Python 3.12.12, pytask 0.6.0, pluggy 1.6.0\n"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"Root: /Users/tobiasr/git/pytask\n", "\n" ], "text/plain": [ "Root: \u001b[35m/Users/tobiasr/git/\u001b[0m\u001b[95mpytask\u001b[0m\n" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "\n" ], "text/plain": [] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
Collected 3 tasks.\n",
"\n"
],
"text/plain": [
"Collected 3 tasks.\n"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"\n",
"\n"
],
"text/plain": [
"\n"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "859e802368444863ba691ca1474c1163",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"Output()"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"\n"
],
"text/plain": []
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"╭────────────────────────┬─────────╮\n",
"│ Task │ Outcome │\n",
"├────────────────────────┼─────────┤\n",
"│ create_file[0-path0] │ . │\n",
"│ create_file[100-path1] │ . │\n",
"│ create_file[200-path2] │ . │\n",
"╰────────────────────────┴─────────╯\n",
"\n"
],
"text/plain": [
"╭────────────────────────┬─────────╮\n",
"│\u001b[1m \u001b[0m\u001b[1mTask \u001b[0m\u001b[1m \u001b[0m│\u001b[1m \u001b[0m\u001b[1mOutcome\u001b[0m\u001b[1m \u001b[0m│\n",
"├────────────────────────┼─────────┤\n",
"│ \u001b]8;id=133063;file://None\u001b\\create_file[0-path0] \u001b]8;;\u001b\\ │ \u001b[38;2;19;124;57m. \u001b[0m │\n",
"│ \u001b]8;id=167889;file://None\u001b\\create_file[100-path1]\u001b]8;;\u001b\\ │ \u001b[38;2;19;124;57m. \u001b[0m │\n",
"│ \u001b]8;id=365664;file://None\u001b\\create_file[200-path2]\u001b]8;;\u001b\\ │ \u001b[38;2;19;124;57m. \u001b[0m │\n",
"╰────────────────────────┴─────────╯\n"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"\n",
"\n"
],
"text/plain": [
"\n"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"───────────────────────────────────────────────────────────────────────────────────────────────────────────────────\n",
"\n"
],
"text/plain": [
"\u001b[2m───────────────────────────────────────────────────────────────────────────────────────────────────────────────────\u001b[0m\n"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"╭─────────── Summary ────────────╮\n", "│ 3 Collected tasks │\n", "│ 3 Succeeded (100.0%) │\n", "╰────────────────────────────────╯\n", "\n" ], "text/plain": [ "\u001b[38;2;19;124;57m╭─\u001b[0m\u001b[38;2;19;124;57m──────────\u001b[0m\u001b[1;38;2;242;242;242m Summary \u001b[0m\u001b[38;2;19;124;57m───────────\u001b[0m\u001b[38;2;19;124;57m─╮\u001b[0m\n", "\u001b[38;2;19;124;57m│\u001b[0m \u001b[38;2;242;242;242m \u001b[0m\u001b[38;2;242;242;242m3\u001b[0m\u001b[38;2;242;242;242m \u001b[0m\u001b[38;2;242;242;242m \u001b[0m\u001b[38;2;242;242;242mCollected tasks\u001b[0m\u001b[38;2;242;242;242m \u001b[0m\u001b[38;2;242;242;242m \u001b[0m\u001b[38;2;242;242;242m \u001b[0m\u001b[38;2;242;242;242m \u001b[0m \u001b[38;2;19;124;57m│\u001b[0m\n", "\u001b[38;2;19;124;57m│\u001b[0m \u001b[38;2;242;242;242;48;2;19;124;57m \u001b[0m\u001b[38;2;242;242;242;48;2;19;124;57m3\u001b[0m\u001b[38;2;242;242;242;48;2;19;124;57m \u001b[0m\u001b[38;2;242;242;242;48;2;19;124;57m \u001b[0m\u001b[38;2;242;242;242;48;2;19;124;57mSucceeded \u001b[0m\u001b[38;2;242;242;242;48;2;19;124;57m \u001b[0m\u001b[38;2;242;242;242;48;2;19;124;57m \u001b[0m\u001b[38;2;242;242;242;48;2;19;124;57m(100.0%)\u001b[0m\u001b[38;2;242;242;242;48;2;19;124;57m \u001b[0m \u001b[38;2;19;124;57m│\u001b[0m\n", "\u001b[38;2;19;124;57m╰────────────────────────────────╯\u001b[0m\n" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
──────────────────────────────────────────── Succeeded in 0.03 seconds ────────────────────────────────────────────\n",
"\n"
],
"text/plain": [
"\u001b[38;2;19;124;57m──────────────────────────────────────────── \u001b[0m\u001b[38;2;19;124;57mSucceeded in 0.03 seconds\u001b[0m\u001b[38;2;19;124;57m ────────────────────────────────────────────\u001b[0m\n"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"session = pytask.build(tasks=tasks)"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [],
"source": [
"# Cleanup\n",
"for i in range(3):\n",
" Path(f\"output_{i}.txt\").unlink()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Configuring the build\n",
"\n",
"To configure the build, {func}`pytask.build` has many more options that are the same that you find on the commandline."
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\u001b[31mSignature:\u001b[39m\n",
"pytask.build(\n",
" *,\n",
" capture: \u001b[33m\"Literal['fd', 'no', 'sys', 'tee-sys'] | CaptureMethod\"\u001b[39m =