-
Notifications
You must be signed in to change notification settings - Fork 125
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Clean up and move user guide Python files (#1584)
* example-ize advanced composition files Signed-off-by: nikki everett <[email protected]> * example-ize basics files Signed-off-by: nikki everett <[email protected]> * example-ize customizing dependencies files Signed-off-by: nikki everett <[email protected]> * example-ize data types and i/o files Signed-off-by: nikki everett <[email protected]> * example-ize development lifecycle files Signed-off-by: nikki everett <[email protected]> * example-ize extending files Signed-off-by: nikki everett <[email protected]> * example-ize testing files Signed-off-by: nikki everett <[email protected]> * example-ize productionizing files Signed-off-by: nikki everett <[email protected]> * example-ize raw containers file Signed-off-by: nikki everett <[email protected]> * move examples that should not be processed out of the way of the docs build Signed-off-by: nikki everett <[email protected]> * delete user guide files from examples since they've been moved to example_code Signed-off-by: nikki everett <[email protected]> * add README Signed-off-by: nikki everett <[email protected]> * linter's mad Signed-off-by: nikki everett <[email protected]> * update dataclass example Signed-off-by: nikki everett <[email protected]> * update test wf paths Signed-off-by: nikki everett <[email protected]> * fix formatting Signed-off-by: nikki everett <[email protected]> * ignore module level import not at top of file errors Signed-off-by: nikki everett <[email protected]> * rename directory Signed-off-by: nikki everett <[email protected]> --------- Signed-off-by: nikki everett <[email protected]>
- Loading branch information
Showing
138 changed files
with
2,352 additions
and
7,207 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
[flake8] | ||
max-line-length = 180 | ||
extend-ignore = E203, E266, E501, W503, E741 | ||
extend-ignore = E203, E266, E402, E501, W503, E741 | ||
exclude = .svn,CVS,.bzr,.hg,.git,__pycache__,venv/*,src/*,.rst,build | ||
max-complexity=16 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
# Flytesnacks example code | ||
|
||
A repository of runnable example code for Flyte. |
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
# Advanced Composition | ||
|
||
These examples introduce the advanced features of the Flytekit Python SDK. | ||
They cover more complex aspects of Flyte, including conditions, subworkflows, | ||
dynamic workflows, map tasks, gate nodes and more. |
File renamed without changes.
49 changes: 49 additions & 0 deletions
49
example_code/advanced_composition/advanced_composition/chain_entities.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
from flytekit import task, workflow | ||
|
||
|
||
@task | ||
def t2(): | ||
print("Running t2") | ||
return | ||
|
||
|
||
@task | ||
def t1(): | ||
print("Running t1") | ||
return | ||
|
||
|
||
@task | ||
def t0(): | ||
print("Running t0") | ||
return | ||
|
||
|
||
# Chaining tasks | ||
@workflow | ||
def chain_tasks_wf(): | ||
t2_promise = t2() | ||
t1_promise = t1() | ||
t0_promise = t0() | ||
|
||
t0_promise >> t1_promise | ||
t1_promise >> t2_promise | ||
|
||
|
||
# Chaining subworkflows | ||
@workflow | ||
def sub_workflow_1(): | ||
t1() | ||
|
||
|
||
@workflow | ||
def sub_workflow_0(): | ||
t0() | ||
|
||
|
||
@workflow | ||
def chain_workflows_wf(): | ||
sub_wf1 = sub_workflow_1() | ||
sub_wf0 = sub_workflow_0() | ||
|
||
sub_wf0 >> sub_wf1 |
42 changes: 42 additions & 0 deletions
42
example_code/advanced_composition/advanced_composition/checkpoint.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
from flytekit import current_context, task, workflow | ||
from flytekit.exceptions.user import FlyteRecoverableException | ||
|
||
RETRIES = 3 | ||
|
||
|
||
# Define a task to iterate precisely `n_iterations`, checkpoint its state, and recover from simulated failures. | ||
@task(retries=RETRIES) | ||
def use_checkpoint(n_iterations: int) -> int: | ||
cp = current_context().checkpoint | ||
prev = cp.read() | ||
|
||
start = 0 | ||
if prev: | ||
start = int(prev.decode()) | ||
|
||
# Create a failure interval to simulate failures across 'n' iterations and then succeed after configured retries | ||
failure_interval = n_iterations // RETRIES | ||
index = 0 | ||
for index in range(start, n_iterations): | ||
# Simulate a deterministic failure for demonstration. Showcasing how it eventually completes within the given retries | ||
if index > start and index % failure_interval == 0: | ||
raise FlyteRecoverableException(f"Failed at iteration {index}, failure_interval {failure_interval}.") | ||
# Save progress state. It is also entirely possible to save state every few intervals | ||
cp.write(f"{index + 1}".encode()) | ||
return index | ||
|
||
|
||
# Create a workflow that invokes the task. | ||
# The task will automatically undergo retries in the event of a FlyteRecoverableException. | ||
@workflow | ||
def checkpointing_example(n_iterations: int) -> int: | ||
return use_checkpoint(n_iterations=n_iterations) | ||
|
||
|
||
# The local checkpoint is not utilized here because retries are not supported. | ||
if __name__ == "__main__": | ||
try: | ||
checkpointing_example(n_iterations=10) | ||
except RuntimeError as e: # noqa : F841 | ||
# Since no retries are performed, an exception is expected when run locally | ||
pass |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
59 changes: 59 additions & 0 deletions
59
example_code/advanced_composition/advanced_composition/decorating_tasks.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
import logging | ||
from functools import partial, wraps | ||
|
||
from flytekit import task, workflow | ||
|
||
# Create a logger to monitor the execution's progress. | ||
logger = logging.getLogger(__file__) | ||
|
||
|
||
# Using a single decorator | ||
def log_io(fn): | ||
@wraps(fn) | ||
def wrapper(*args, **kwargs): | ||
logger.info(f"task {fn.__name__} called with args: {args}, kwargs: {kwargs}") | ||
out = fn(*args, **kwargs) | ||
logger.info(f"task {fn.__name__} output: {out}") | ||
return out | ||
|
||
return wrapper | ||
|
||
|
||
# Create a task named `t1` that is decorated with `log_io`. | ||
@task | ||
@log_io | ||
def t1(x: int) -> int: | ||
return x + 1 | ||
|
||
|
||
# Stacking multiple decorators | ||
def validate_output(fn=None, *, floor=0): | ||
@wraps(fn) | ||
def wrapper(*args, **kwargs): | ||
out = fn(*args, **kwargs) | ||
if out <= floor: | ||
raise ValueError(f"output of task {fn.__name__} must be a positive number, found {out}") | ||
return out | ||
|
||
if fn is None: | ||
return partial(validate_output, floor=floor) | ||
|
||
return wrapper | ||
|
||
|
||
# Define a function that uses both the logging and validator decorators | ||
@task | ||
@log_io | ||
@validate_output(floor=10) | ||
def t2(x: int) -> int: | ||
return x + 10 | ||
|
||
|
||
# Compose a workflow that calls `t1` and `t2` | ||
@workflow | ||
def decorating_task_wf(x: int) -> int: | ||
return t2(x=t1(x=x)) | ||
|
||
|
||
if __name__ == "__main__": | ||
print(f"Running decorating_task_wf(x=10) {decorating_task_wf(x=10)}") |
Oops, something went wrong.