Apps depending on other environments

The depends_on parameter allows you to specify that one app depends on another app (or task environment). When you deploy an app with depends_on, Flyte ensures that all dependencies are deployed first.

Basic usage

Use depends_on to specify a list of environments that this app depends on:

app1_env = flyte.app.AppEnvironment(name="backend-api", ...)

app2_env = flyte.app.AppEnvironment(
    name="frontend-app",
    depends_on=[app1_env],  # Ensure backend-api is deployed first
    # ...
)

When you deploy app2_env, Flyte will:

  1. First deploy app1_env (if not already deployed)
  2. Then deploy app2_env
  3. Make sure app1_env is available before app2_env starts

Example: App calling another app

Here’s a complete example where one FastAPI app calls another:

app_calling_app.py
"""Example of one app calling another app."""

import httpx
from fastapi import FastAPI
import pathlib
import flyte
from flyte.app.extras import FastAPIAppEnvironment

image = flyte.Image.from_debian_base(python_version=(3, 12)).with_pip_packages(
    "fastapi", "uvicorn", "httpx"
)

app1 = FastAPI(
    title="App 1",
    description="A FastAPI app that runs some computations",
)

env1 = FastAPIAppEnvironment(
    name="app1-is-called-by-app2",
    app=app1,
    image=image,
    resources=flyte.Resources(cpu=1, memory="512Mi"),
    requires_auth=False,
)

app2 = FastAPI(
    title="App 2",
    description="A FastAPI app that proxies requests to another FastAPI app",
)

env2 = FastAPIAppEnvironment(
    name="app2-calls-app1",
    app=app2,
    image=image,
    resources=flyte.Resources(cpu=1, memory="512Mi"),
    requires_auth=False,
    depends_on=[env1],  # Depends on backend-api
)

@app1.get("/greeting/{name}")
async def greeting(name: str) -> str:
    return f"Hello, {name}!"

@app2.get("/app1-endpoint")
async def get_app1_endpoint() -> str:
    return env1.endpoint  # Access the backend endpoint

@app2.get("/greeting/{name}")
async def greeting_proxy(name: str):
    """Proxy that calls the backend app."""
    async with httpx.AsyncClient() as client:
        response = await client.get(f"{env1.endpoint}/greeting/{name}")
        response.raise_for_status()
        return response.json()

if __name__ == "__main__":
    flyte.init_from_config(root_dir=pathlib.Path(__file__).parent)
    deployments = flyte.deploy(env2)
    print(f"Deployed FastAPI app: {deployments[0].env_repr()}")


When you deploy env2, Flyte will:

  1. Deploy env1 first (backend-api)
  2. Wait for env1 to be ready
  3. Deploy env2 (frontend-api)
  4. env2 can then access env1.endpoint to make requests

Dependency chain

You can create chains of dependencies:

app1_env = flyte.app.AppEnvironment(name="service-1", ...)
app2_env = flyte.app.AppEnvironment(name="service-2", depends_on=[app1_env], ...)
app3_env = flyte.app.AppEnvironment(name="service-3", depends_on=[app2_env], ...)

# Deploying app3_env will deploy in order: app1_env -> app2_env -> app3_env

Multiple dependencies

An app can depend on multiple environments:

backend_env = flyte.app.AppEnvironment(name="backend", ...)
database_env = flyte.app.AppEnvironment(name="database", ...)

api_env = flyte.app.AppEnvironment(
    name="api",
    depends_on=[backend_env, database_env],  # Depends on both
    # ...
)

When deploying api_env, both backend_env and database_env will be deployed first (they may be deployed in parallel if they don’t depend on each other).

Using AppEndpoint for dependency URLs

When one app depends on another, you can use AppEndpoint to get the URL:

backend_env = flyte.app.AppEnvironment(name="backend-api", ...)

frontend_env = flyte.app.AppEnvironment(
    name="frontend-app",
    depends_on=[backend_env],
    inputs=[
        flyte.app.Input(
            name="backend_url",
            value=flyte.app.AppEndpoint(app_name="backend-api"),
        ),
    ],
    # ...
)

The backend_url input will be automatically set to the backend app’s endpoint URL. You can get this value in your app code using flyte.app.get_input("backend_url").

Deployment behavior

When deploying with flyte.deploy():

# Deploy the app (dependencies are automatically deployed)
deployments = flyte.deploy(env2)

# All dependencies are included in the deployment plan
for deployment in deployments:
    print(f"Deployed: {deployment.env.name}")

Flyte will:

  1. Build a deployment plan that includes all dependencies
  2. Deploy dependencies in the correct order
  3. Ensure dependencies are ready before deploying dependent apps

Task environment dependencies

You can also depend on task environments:

task_env = flyte.TaskEnvironment(name="training-env", ...)

serving_env = flyte.app.AppEnvironment(
    name="serving-app",
    depends_on=[task_env],  # Can depend on task environments too
    # ...
)

This ensures the task environment is available when the app is deployed (useful if the app needs to call tasks in that environment).

Best practices

  1. Explicit dependencies: Always use depends_on to make app dependencies explicit
  2. Circular dependencies: Avoid circular dependencies (app A depends on B, B depends on A)
  3. Dependency order: Design your dependency graph to be a DAG (Directed Acyclic Graph)
  4. Endpoint access: Use AppEndpoint to pass dependency URLs as inputs
  5. Document dependencies: Make sure your app documentation explains its dependencies

Example: A/B testing with dependencies

Here’s an example of an A/B testing setup where a root app depends on two variant apps:

app_a = FastAPI(title="Variant A")
app_b = FastAPI(title="Variant B")
root_app = FastAPI(title="Root App")

env_a = FastAPIAppEnvironment(name="app-a-variant", app=app_a, ...)
env_b = FastAPIAppEnvironment(name="app-b-variant", app=app_b, ...)

env_root = FastAPIAppEnvironment(
    name="root-ab-testing-app",
    app=root_app,
    depends_on=[env_a, env_b],  # Depends on both variants
    # ...
)

The root app can route traffic to either variant A or B based on A/B testing logic, and both variants will be deployed before the root app starts.

Limitations

  • Circular dependencies are not supported
  • Dependencies must be in the same project/domain
  • Dependency deployment order is deterministic but dependencies at the same level may deploy in parallel