Skip to main content

Execution Environments

Execution environments in this SDK provide a declarative way to define the infrastructure and runtime settings required for your code. By using specific environment classes, you can control container images, compute resources, secrets, and deployment dependencies for both discrete tasks and long-running applications.

The Base Environment

The Environment class in flyte._environment serves as the foundation for all execution settings. While you typically do not instantiate Environment directly, its attributes define the core infrastructure capabilities shared by tasks and apps.

Core Infrastructure Settings

Every environment supports the following primary configurations:

  • Image: Defined via the image parameter, which accepts a string URI, an Image object, or "auto".
  • Resources: Managed through a Resources object to specify CPU, memory, GPU, and disk requirements.
  • Secrets: Injected via SecretRequest to provide secure access to credentials.
  • Pod Templates: Advanced Kubernetes configuration (like sidecars or volumes) can be applied using a PodTemplate object or a string reference to a named template.
  • Environment Variables: A dictionary of strings passed to the container at runtime.

Name Validation and Registry

Environments must have a name that follows snake_case or kebab-case formatting, validated by _validate_name. Upon instantiation, every environment is automatically added to a global _ENVIRONMENT_REGISTRY in flyte._environment, which the deployment system uses to discover and register infrastructure requirements.

Task Environments

The TaskEnvironment class in flyte._task_environment is designed for executing discrete Flyte tasks. It introduces the @env.task decorator, which binds a Python function to the environment's infrastructure settings.

Configuration Hierarchy

Task configuration follows a three-level hierarchy where the most specific setting wins:

  1. TaskEnvironment: Sets the default infrastructure for all tasks defined within it.
  2. @env.task Decorator: Overrides settings for a specific task (e.g., cache, retries, timeout).
  3. task.override(): Overrides settings at invocation time (e.g., resources, env_vars).

Defining Tasks

Tasks are defined by decorating an async or sync function with the environment's .task method. The task's fully-qualified name (FQN) is automatically generated as <env_name>.<function_name>.

import flyte

# Define the environment defaults
env = flyte.TaskEnvironment(
name="data-processing",
image="ghcr.io/org/image:latest",
resources=flyte.Resources(cpu="2", memory="4Gi"),
)

# Bind a task to this environment
@env.task(cache="auto")
async def process_data(input_path: str) -> str:
# Task logic here
return f"Processed {input_path}"

Container Reuse and Plugins

TaskEnvironment supports specialized execution modes:

  • Reusable Containers: Controlled by the reusable parameter (a ReusePolicy). When enabled, the environment can maintain warm containers to reduce startup latency. Note that if reusable is set, plugin_config cannot be used.
  • Plugins: The plugin_config parameter allows the environment to support custom task types like Ray or Spark.

App Environments

For long-running services such as APIs, dashboards, or model servers, the SDK provides AppEnvironment in flyte.app._app_environment.

Lifecycle Hooks

Unlike tasks, apps use decorators to define their lifecycle:

  • @env.on_startup: Runs initialization logic before the server starts.
  • @env.server: Defines the main entry point for the application process.
  • @env.on_shutdown: Handles cleanup after the server stops.
app_env = flyte.app.AppEnvironment(
name="my-api-service",
port=8080,
scaling=flyte.app.Scaling(replicas=(1, 5)),
)

@app_env.server
def run_server():
import uvicorn
from fastapi import FastAPI
app = FastAPI()
uvicorn.run(app, host="0.0.0.0", port=8080)

Scaling and Networking

AppEnvironment includes specific settings for service availability:

  • Scaling: A Scaling object defines the minimum and maximum replicas for autoscaling.
  • Ports: The port parameter (default 8080) defines the service endpoint. Note that ports 8012, 8022, 8112, 9090, and 9091 are reserved by the platform and will raise a ValueError if used.
  • Authentication: The requires_auth boolean (default True) controls whether the app endpoint is public or protected.

Connector Environments

The ConnectorEnvironment in flyte.app._connector_environment is a specialized version of AppEnvironment used for building custom Flyte connectors.

It simplifies the deployment of connector code by automatically handling module discovery. The include parameter accepts a list of file paths or directories, which the environment automatically converts into dotted Python module names passed to the connector runtime via the --modules argument.

connector = flyte.app.ConnectorEnvironment(
name="batch-job-connector",
image="my-connector-image:v1",
include=["my_connector"],
)

Advanced Configuration Patterns

Cloning Environments

To avoid repeating complex infrastructure configurations, environments provide a .clone_with() method. This creates a new instance inheriting all settings from the original while allowing specific overrides.

base_env = flyte.TaskEnvironment(
name="base-env",
image="my-image:latest",
resources=flyte.Resources(cpu="1", memory="2Gi"),
)

# Create a specialized GPU environment from the base
gpu_env = base_env.clone_with(
name="gpu-env",
resources=flyte.Resources(gpu="1", memory="16Gi")
)

Deployment Dependencies

Environments can depend on one another using the depends_on parameter or the .add_dependency() method. This ensures that when a primary environment is deployed, its dependencies (such as a required ConnectorEnvironment) are also provisioned.

File Inclusion

The include parameter allows you to bundle extra files (config files, HTML templates, etc.) with the environment's code. Relative paths in include are resolved against the "declaring file"—the specific Python file where the environment was instantiated—using the internal _get_declaring_file logic.