Understanding the code
This is a simple “Hello, world!” example consisting of flat directory:
├── LICENSE
├── README.md
├── hello_world.py
├── pyproject.toml
└── uv.lock
Python code
The hello_world.py
file illustrates the essential components of a Flyte workflow:
# Hello World
import flytekit as fl
import os
image_spec = fl.ImageSpec(
# The name of the image. This image will be used by the `say_hello`` task.
name="say-hello-image",
# Lock file with dependencies to be installed in the image.
requirements="uv.lock",
# Image registry to to which this image will be pushed.
# Set the Environment variable FLYTE_IMAGE_REGISTRY to the URL of your registry.
# The image will be built on your local machine, so enure that your Docker is running.
# Ensure that pushed image is accessible to your Flyte cluster, so that it can pull the image
# when it spins up the task container.
registry=os.environ['FLYTE_IMAGE_REGISTRY']
)
@fl.task(container_image=image_spec)
def say_hello(name: str) -> str:
return f"Hello, {name}!"
@fl.workflow
def hello_world_wf(name: str = "world") -> str:
greeting = say_hello(name=name)
return greeting
ImageSpec
The ImageSpec
object is used to define the container image that will run the tasks in the workflow.
Here we have the simplest possible ImageSpec
object, which specifies:
-
The
name
of the image.- This name will be used to identify the image in the container registry.
-
The
requirements
parameter.- We specify that the requirements should be read from the
uv.lock
file.
- We specify that the requirements should be read from the
- The
registry
to which the image will be pushed.- Here we use the environment variable
FLYTE_IMAGE_REGISTRY
to hold the URL of the registry. - You must ensure that this environment variable is correctly set before you register the workflow.
- You must also ensure that when the image is pushed to the registry, it will be accesible to your Flyte cluster, so that it can pull the image when it spins up the task container.
- Here we use the environment variable
See ImageSpec for more information.
Tasks
The @fl.task
decorator indicates a Python function that defines a
task.
A task tasks some input and produces an output.
When deployed to Flyte cluster, each task runs in its own Kubernetes pod.
For a full list of task parameters, see
Task parameters.
Workflow
The @fl.workflow
decorator indicates a function that defines a
workflow.
This function contains references to the tasks defined elsewhere in the code.
A workflow appears to be a Python function but is actually a DSL that only supports a subset of Python syntax and semantics.
When deployed to Flyte, the workflow function is compiled to construct the directed acyclic graph (DAG) of tasks, defining the order of execution of task pods and the data flow dependencies between them.
@fl.task
and @fl.workflow
syntax- The
@fl.task
and@fl.workflow
decorators will only work on functions at the top-level scope of the module. - You can invoke tasks and workflows as regular Python functions and even import and use them in other Python modules or scripts.
- Task and workflow function signatures must be type-annotated with Python type hints.
- Task and workflow functions must be invoked with keyword arguments.
pyproject.toml
The pyproject.toml
is the standard project configuration used by uv
.
It specifies the project dependencies and the Python version to use.
The default pyproject.toml
file created by pyflyte init
from the flyte-simple
template looks like this
[project]
name = "flyte-simple"
version = "0.1.0"
description = "A simple Flyte project"
readme = "README.md"
requires-python = ">=3.9,<3.13"
dependencies = ["flytekit"]
(You can update the name
and description
to match the actual name of your project, my-project
, if you like).
The most important part of the file is the list of dependencies, in this case consisting of only one package, flytekit
.
See
uv > Configuration > Configuration files for details.
uv.lock
The uv.lock
file is generated from pyproject.toml
by uv sync
command.
It contains the exact versions of the dependencies required by the project.
The uv.lock
included in the init
template may not reflect the latest version of the dependencies, so you should update it by doing a fresh uv sync
.
See uv > Concepts > Projects > Locking and syncing for details.