Skip to main content

Defining Task Signatures: The Native Interface

When you define a task in flyte-sdk, the framework needs to understand its inputs and outputs to ensure type safety, enable serialization, and facilitate validation across different execution environments. This understanding is encapsulated by the task's signature.

The flyte-sdk uses the NativeInterface class to represent this signature. It acts as a bridge, translating Python function definitions into a structured format that Flyte can process. Complementing NativeInterface is the _has_default marker class, which signals the presence of a default value for an input, particularly when the actual value isn't immediately available.

Core Functionality of NativeInterface

The NativeInterface class, defined in models.py, is a frozen dataclass that stores comprehensive information about a task's signature:

@dataclass(frozen=True)
class NativeInterface:
inputs: Dict[str, Tuple[Type, Any]]
outputs: Dict[str, Type]
docstring: Optional[Docstring] = None
_remote_defaults: Optional[Dict[str, literals_pb2.Literal]] = field(default=None, repr=False)
has_default: ClassVar[Type[_has_default]] = _has_default
  • inputs: A dictionary where keys are input parameter names (strings) and values are tuples. Each tuple contains the Python type of the input (Type) and its default value (Any). If an input has no default, inspect.Parameter.empty is used. For remote tasks with default values, the special NativeInterface.has_default marker might be used instead of the actual value.
  • outputs: A dictionary mapping output names (strings) to their corresponding Python types (Type).
  • docstring: An optional Docstring object, capturing the task's documentation.
  • _remote_defaults: An optional dictionary used to store default values for remote tasks. These values are typically flyteidl.core.literals_pb2.Literal objects, which are the Flyte IDL representation of literal values.
  • has_default: A class variable set to _has_default. This marker is used internally to indicate that an input has a default value, but the value itself might be resolved externally (e.g., from _remote_defaults).

Defining Interfaces from Python Functions (from_callable)

For most flyte-sdk users, the primary way to define a task's interface is by writing a standard Python function with type hints and, optionally, default values. flyte-sdk then introspects this function to automatically construct the NativeInterface.

Consider a typical Flyte task definition:

from flytekit import task
from typing import List, Optional

@task
def process_data(input_id: int, data_source: str = "default_source", filters: Optional[List[str]] = None) -> str:
"""
Processes data based on an input ID and optional filters.
"""
if filters:
return f"Processing \{input_id\} from \{data_source\} with filters: \{