Skip to content

Commit 8e88ed2

Browse files
committed
finished off the workflow tutorial for now
1 parent a8ed05e commit 8e88ed2

File tree

1 file changed

+86
-8
lines changed

1 file changed

+86
-8
lines changed

new-docs/source/tutorial/workflow.ipynb

Lines changed: 86 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,22 @@
44
"cell_type": "markdown",
55
"metadata": {},
66
"source": [
7-
"# Workflow design"
7+
"# Workflow design\n",
8+
"\n",
9+
"In Pydra, workflows are DAG of component tasks to be executed on specified inputs.\n",
10+
"Workflow specifications are dataclasses, which interchangeable with Python and shell tasks\n",
11+
"specifications and executed in the same way."
812
]
913
},
1014
{
1115
"cell_type": "markdown",
1216
"metadata": {},
1317
"source": [
14-
"Given two task specifications, `Add` and `Mul`"
18+
"## Constructor functions\n",
19+
"\n",
20+
"Workflows are typically defined using the `pydra.design.workflow.define` decorator on \n",
21+
"a \"constructor\" function that generates the workflow. For example, given two task\n",
22+
"specifications, `Add` and `Mul`."
1523
]
1624
},
1725
{
@@ -47,7 +55,7 @@
4755
"outputs": [],
4856
"source": [
4957
"@workflow.define\n",
50-
"def MyTestWorkflow(a, b):\n",
58+
"def BasicWorkflow(a, b):\n",
5159
" add = workflow.add(Add(a=a, b=b))\n",
5260
" mul = workflow.add(Mul(a=add.out, b=b))\n",
5361
" return mul.out"
@@ -72,7 +80,7 @@
7280
"from fileformats import image, video\n",
7381
"\n",
7482
"@workflow.define\n",
75-
"def MyTestShellWorkflow(\n",
83+
"def ShellWorkflow(\n",
7684
" input_video: video.Mp4,\n",
7785
" watermark: image.Png,\n",
7886
" watermark_dims: tuple[int, int] = (10, 10),\n",
@@ -209,7 +217,7 @@
209217
" return float(value)\n",
210218
"\n",
211219
"@workflow.define\n",
212-
"class MyLibraryWorkflow(WorkflowSpec[\"MyLibraryWorkflow.Outputs\"]):\n",
220+
"class LibraryWorkflow(WorkflowSpec[\"MyLibraryWorkflow.Outputs\"]):\n",
213221
"\n",
214222
" a: int\n",
215223
" b: float = workflow.arg(\n",
@@ -248,7 +256,7 @@
248256
" return sum(x)\n",
249257
"\n",
250258
"@workflow.define\n",
251-
"def MySplitWorkflow(a: list[int], b: list[float]) -> list[float]:\n",
259+
"def SplitWorkflow(a: list[int], b: list[float]) -> list[float]:\n",
252260
" # Multiply over all combinations of the elements of a and b, then combine the results\n",
253261
" # for each a element into a list over each b element\n",
254262
" mul = workflow.add(Mul()).split(x=a, y=b).combine(\"x\")\n",
@@ -271,7 +279,7 @@
271279
"outputs": [],
272280
"source": [
273281
"@workflow.define\n",
274-
"def MySplitThenCombineWorkflow(a: list[int], b: list[float], c: float) -> list[float]:\n",
282+
"def SplitThenCombineWorkflow(a: list[int], b: list[float], c: float) -> list[float]:\n",
275283
" mul = workflow.add(Mul()).split(x=a, y=b)\n",
276284
" add = workflow.add(Add(x=mul.out, y=c)).combine(\"Mul.x\")\n",
277285
" sum = workflow.add(Sum(x=add.out))\n",
@@ -301,7 +309,7 @@
301309
"outputs": [],
302310
"source": [
303311
"@workflow.define\n",
304-
"def MyConditionalWorkflow(\n",
312+
"def ConditionalWorkflow(\n",
305313
" input_video: video.Mp4,\n",
306314
" watermark: image.Png,\n",
307315
" watermark_dims: tuple[int, int] | None = None,\n",
@@ -371,6 +379,76 @@
371379
"placeholders see [Conditional construction](../explanation/conditional-lazy.html)"
372380
]
373381
},
382+
{
383+
"cell_type": "markdown",
384+
"metadata": {},
385+
"source": [
386+
"## Typing\n",
387+
"\n",
388+
"Pydra utilizes Python type annotations to implement strong type-checking, which is performed\n",
389+
"when values or upstream outputs are assigned to task specification inputs.\n",
390+
"\n",
391+
"Task input and output fields do not need to be assigned types, since they will default to `typing.Any`.\n",
392+
"However, if they are assigned a type and a value or output from an upstream node conflicts\n",
393+
"with the type, a `TypeError` will be raised at construction time.\n",
394+
"\n",
395+
"Note that the type-checking \"assumes the best\", and will pass if the upstream field is typed\n",
396+
"by `Any` or a super-class of the field being assigned to. For example, an input of\n",
397+
"`fileformats.generic.File` passed to a field expecting a `fileformats.image.Png` file type,\n",
398+
"because `Png` is a subtype of `File`, where as `fileformats.image.Jpeg` input would fail\n",
399+
"since it is clearly not the intended type.\n"
400+
]
401+
},
402+
{
403+
"cell_type": "code",
404+
"execution_count": 10,
405+
"metadata": {},
406+
"outputs": [],
407+
"source": [
408+
"from fileformats import generic\n",
409+
"\n",
410+
"Mp4Handbrake = shell.define(\n",
411+
" \"HandBrakeCLI -i <in_video:video/mp4> -o <out|out_video:video/mp4> \"\n",
412+
" \"--width <width:int> --height <height:int>\",\n",
413+
")\n",
414+
"\n",
415+
"\n",
416+
"QuicktimeHandbrake = shell.define(\n",
417+
" \"HandBrakeCLI -i <in_video:video/quicktime> -o <out|out_video:video/quicktime> \"\n",
418+
" \"--width <width:int> --height <height:int>\",\n",
419+
")\n",
420+
"\n",
421+
"@workflow.define\n",
422+
"def TypeErrorWorkflow(\n",
423+
" input_video: video.Mp4,\n",
424+
" watermark: generic.File,\n",
425+
" watermark_dims: tuple[int, int] = (10, 10),\n",
426+
") -> video.Mp4:\n",
427+
"\n",
428+
" add_watermark = workflow.add(\n",
429+
" shell.define(\n",
430+
" \"ffmpeg -i <in_video> -i <watermark:image/png> \"\n",
431+
" \"-filter_complex <filter> <out|out_video:video/mp4>\"\n",
432+
" )(\n",
433+
" in_video=input_video,\n",
434+
" watermark=watermark, # Type is OK because generic.File is superclass of image.Png\n",
435+
" filter=\"overlay={}:{}\".format(*watermark_dims),\n",
436+
" ),\n",
437+
" name=\"add_watermark\",\n",
438+
" )\n",
439+
"\n",
440+
" try:\n",
441+
" handbrake = workflow.add(\n",
442+
" QuicktimeHandbrake(in_video=add_watermark.out_video, width=1280, height=720),\n",
443+
" ) # This will raise a TypeError because the input video is an Mp4\n",
444+
" except TypeError:\n",
445+
" handbrake = workflow.add(\n",
446+
" Mp4Handbrake(in_video=add_watermark.out_video, width=1280, height=720),\n",
447+
" ) # The type of the input video is now correct\n",
448+
"\n",
449+
" return handbrake.output_video"
450+
]
451+
},
374452
{
375453
"cell_type": "markdown",
376454
"metadata": {},

0 commit comments

Comments
 (0)