# Core concepts

> **📝 Note**
>
> An LLM-optimized bundle of this entire section is available at [`section.md`](https://www.union.ai/docs/v1/union/user-guide/core-concepts/section.md).
> This single file contains all pages in this section, optimized for AI coding agent context.

Union.ai is a platform for building and orchestrating the execution of interconnected software processes across machines in a computer cluster.
In Union.ai terminology, the software processes are called *tasks* and the overall organization of connections between tasks is called a *workflow*.
The tasks in a workflow are connected to each other by their inputs and outputs. The output of one task becomes the input of another.

More precisely, a workflow in Union.ai is a *directed acyclic graph (DAG)* of *nodes* where each node is a unit of execution and the edges between nodes represent the flow of data between them.
The most common type of node is a task node (which encapsulates a task), though there are also workflow nodes (which encapsulate subworkflows) and branch nodes.
In most contexts we just say that a workflow is a DAG of tasks.

You define tasks and workflows in Python using the Union SDK. The Union SDK provides a set of decorators and classes that allow you to define tasks and workflows in a way that is easy to understand and work with.
Once defined, tasks and workflows are deployed to your Union.ai instance (we say they are *registered* to the instance), where they are compiled into a form that can be executed on your Union.ai cluster.

In addition to tasks and workflows, another important concept in Union.ai is the [*launch plan*](https://www.union.ai/docs/v1/union/user-guide/core-concepts/launch-plans/page.md).
A launch plan is like a template that can be used to define the inputs to a workflow.
Triggering a launch plan will launch its associated workflow with the specified parameters.

## Defining tasks and workflows

Using the Union SDK, tasks and workflows are defined as Python functions using the `@union.task` and `@union.workflow` decorators, respectively:

```python
import union

@union.task
def task_1(a: int, b: int, c: int) -> int:
    return a + b + c

@union.task
def task_2(m: int, n: int) -> int:
    return m * n

@union.task
def task_3(x: int, y: int) -> int:
    return x - y

@union.workflow
def my_workflow(a: int, b: int, c: int, m: int, n: int) -> int:
    x = task_1(a=a, b=b, c=c)
    y = task_2(m=m, n=n)
    return task_3(x=x, y=y)
```

Here we see three tasks defined using the `@union.task` decorator and a workflow defined using the `@union.workflow` decorator.
The workflow calls `task_1` and `task_2` and passes the results to `task_3` before finally outputting the result of `task_3`.

When the workflow is registered, Union.ai compiles the workflow into a directed acyclic graph (DAG) based on the input/output dependencies between the tasks.
The DAG is then used to execute the tasks in the correct order, taking advantage of any parallelism that is possible.
For example, the workflow above results in the following DAG:

![Workflow DAG](https://www.union.ai/docs/v1/union/_static/images/user-guide/core-concepts/workflow-dag.png)

### Type annotation is required

One important difference between Union.ai and generic Python is that in Union.ai all inputs and outputs *must be type annotated*.
This is because tasks are strongly typed, meaning that the types of the inputs and outputs are validated at deployment time.

See [Tasks are strongly typed](https://www.union.ai/docs/v1/union/user-guide/core-concepts/tasks/page.md#tasks-are-strongly-typed) for more details.

### Workflows *are not* full Python functions

The definition of a workflow must be a valid Python function, so it can be run locally as a normal Python function during development,
but only *a subset of Python syntax is allowed*, because it must also be compiled into a DAG that is deployed and executed on Union.ai.

*Technically then, the language of a workflow function is a domain-specific language (DSL) that is a subset of Python.*

See [Workflows](https://www.union.ai/docs/v1/union/user-guide/core-concepts/workflows/page.md) for more details.

## Registering tasks and workflows

### Registering on the command line with `union` or `uctl`

In most cases, workflows and tasks (and possibly other things, such as launch plans) are defined in your project code and registered as a bundle using `union` or `uctl` For example:

```shell
$ union register ./workflows --project my_project --domain development
```

Tasks can also be registered individually, but it is more common to register alongside the workflow that uses them.

See [Running your code](https://www.union.ai/docs/v1/union/user-guide/development-cycle/running-your-code/page.md).

### Registering in Python with `UnionRemote`

As with all Union.ai command line actions, you can also perform registration of workflows and tasks programmatically with [`UnionRemote`](), specifically, [`UnionRemote.register_script`](),
[`UnionRemote.register_workflow`](), and
[`UnionRemote.register_task`]().
<!-- TODO: Add link to API -->

## Results of registration

When the code above is registered to Union.ai, it results in the creation of five objects:

* The tasks `workflows.my_example.task_1`, `workflows.my_example.task_2`, and `workflows.my_example.task_3` (see [Task fundamentals](https://www.union.ai/docs/v1/union/user-guide/core-concepts/tasks/page.md) for more details).
* The workflow `workflows.my_example.my_workflow`.
* The default launch plan `workflows.my_example.my_workflow` (see [Launch plans](https://www.union.ai/docs/v1/union/user-guide/core-concepts/launch-plans/page.md) for more details).

Notice that the task and workflow names are derived from the path, file name and function name of the Python code that defines them: `<folder>.<file>.<function>`.
The default launch plan for a workflow always has the same name as its workflow.

## Changing tasks and workflows

Tasks and workflows are changed by altering their definition in code and re-registering.
When a task or workflow with the same project, domain, and name as a preexisting one is re-registered, a new version of that entity is created.

## Inspecting tasks and workflows

### Inspecting workflows in the UI

Select **Workflows** in the sidebar to display a list of all the registered workflows in the project and domain.
You can search the workflows by name.

Click on a workflow in the list to see the **workflow view**.
The sections in this view are as follows:

* **Recent Workflow Versions**: A list of recent versions of this workflow.
  Select a version to see the **Workflow version view**.
  This view shows the DAG and a list of all version of the task.
  You can switch between versions with the radio buttons.

* **All Executions in the Workflow**: A list of all executions of this workflow.
  Click on an execution to go to the [Execution view](https://www.union.ai/docs/v1/union/user-guide/core-concepts/workflows/viewing-workflow-executions/page.md).

* **Launch Workflow button**: In the top right of the workflow view, you can click the **Launch Workflow** button to run the workflow with the default inputs.

### Inspecting tasks in the UI

Select **Tasks** in the sidebar to display a list of all the registered tasks in the project and domain.
You can search the launch plans by name.
To filter for only those that are archived, check the **Show Only Archived Tasks** box.

Click on a task in the list to see the task view
The sections in the task view are as follows:

* **Inputs & Outputs**: The name and type of each input and output for the latest version of this task.

* **Recent Task Versions**: A list of recent versions of this task.
  Select a version to see the **Task version view**:
  This view shows the task details and a list of all version of the task.
  You can switch between versions with the radio buttons.
  See [Tasks](https://www.union.ai/docs/v1/union/user-guide/core-concepts/tasks/page.md) for more information.

* **All Executions in the Task**: A list of all executions of this task.
  Click on an execution to go to the execution view.

* **Launch Task button**: In the top right of the task view, you can click the **Launch Task** button to run the task with the default inputs.

### Inspecting workflows on the command line with `uctl`

To view all tasks within a project and domain:

```shell
$ uctl get workflows \
       --project <project-id> \
       --domain <domain>
```

To view a specific workflow:

```shell
$ uctl get workflow \
       --project <project-id> \
       --domain <domain> \
       <workflow-name>
       <workflow-version>
```

See [Uctl CLI](https://www.union.ai/docs/v1/union/api-reference/uctl-cli/page.md) for more details.

### Inspecting tasks on the command line with `uctl`

To view all tasks within a project and domain:

```shell
$ uctl get tasks \
       --project <project-id> \
       --domain <domain>
```

To view a specific task:

```shell
$ uctl get task \
       --project <project-id> \
       --domain <domain> \
       <task-name>
       <task-version>
```

See [Uctl CLI](https://www.union.ai/docs/v1/union/api-reference/uctl-cli/page.md) for more details.

### Inspecting tasks and workflows in Python with `UnionRemote`

Use the method [`UnionRemote.fetch_workflow`]() or [`UnionRemote.client.get_workflow`]() to get a workflow.
See [`UnionRemote`]() for more options and details.

Use the method [`UnionRemote.fetch_task`]() or [`UnionRemote.client.get_task`]() to get a task.
See [`UnionRemote`]() for more options and details.
<!-- TODO: Add links to API -->

## Running tasks and workflows

### Running a task or workflow in the UI

To run a workflow in the UI, click the **Launch Workflow** button in the workflow view.

You can also run individual tasks in the UI by clicking the **Launch Task** button in the task view.

### Running a task or workflow locally on the command line with `union` or `python`

You can execute a Union.ai workflow or task locally simply by calling it just like any regular Python function.
For example, you can add the following to the above code:

```python
if __name__ == "__main__":
    my_workflow(a=1, b=2, c=3, m=4, n=5)
```

If the file is saved as `my_example.py`, you can run it locally using the following command:

```shell
$ python my_example.py
```

Alternatively, you can run the task locally with the `union` command line tool:

To run it locally, you can use the following `union run` command:

```shell
$ union run my_example.py my_workflow --a 1 --b 2 --c 3 --m 4 --n 5
```

This has the advantage of allowing you to specify the input values as command line arguments.
For more details on running workflows and tasks, see [Development cycle](https://www.union.ai/docs/v1/union/user-guide/development-cycle/page.md).

### Running a task or workflow remotely on the command line with `union`

To run a workflow remotely on your Union.ai installation, use the following command (this assumes that you have your [UNION_CONFIG set up correctly](https://www.union.ai/docs/v1/union/user-guide/development-cycle/setting-up-a-project/page.md)):

```shell
$  union run --remote my_example.py my_workflow --a 1 --b 2 --c 3 --m 4 --n 5
```

### Running a task or workflow remotely in Python with `UnionRemote`

To run a workflow or task remotely in Python, use the method [`UnionRemote.execute`](). See [`UnionRemote`]() for more options and details.

<!-- TODO: Add links to API -->

## Subpages

- [Workflows](https://www.union.ai/docs/v1/union/user-guide/core-concepts/workflows/page.md)
- [Tasks](https://www.union.ai/docs/v1/union/user-guide/core-concepts/tasks/page.md)
  - Tasks are independently executable
  - Tasks are strongly typed
  - Tasks are containerized
  - Tasks are named, versioned, and immutable
  - Tasks are (usually) deterministic and cacheable
  - Workflows can contain many types of tasks
  - Mix and match task characteristics
  - Task configuration
- [Launch plans](https://www.union.ai/docs/v1/union/user-guide/core-concepts/launch-plans/page.md)
  - Default launch plan
  - Launch plans are versioned
  - Custom launch plans
  - Viewing launch plans for a workflow
  - Registering a launch plan
  - Registering a launch plan on the command line
  - Registering a launch plan in Python with `UnionRemote`
  - Results of registration
  - Changing a launch plan
- [Actors](https://www.union.ai/docs/v1/union/user-guide/core-concepts/actors/page.md)
  - `ActorEnvironment` parameters
  - Caching on Actor Replicas
  - When to Use `@actor_cache`
- [Artifacts](https://www.union.ai/docs/v1/union/user-guide/core-concepts/artifacts/page.md)
  - Versioning
  - Partitions
  - Queries
  - Lineage
- [App Serving](https://www.union.ai/docs/v1/union/user-guide/core-concepts/serving/page.md)
  - Example app
  - App declaration
  - Deploy the app
  - Viewing deployed apps
  - Stopping apps
- [Caching](https://www.union.ai/docs/v1/union/user-guide/core-concepts/caching/page.md)
  - Enabling and configuring caching
  - The `Cache` object
  - Enabling caching with the default configuration
  - Automatic version generation
  - Default cache policy
  - The `overwrite-cache` flag
  - Overwrite cache on the command line
  - Overwrite cache in the UI
  - Overwrite cache programmatically
  - How caching works
  - Explicit cache version
  - Node signature
  - Caching when running locally
  - Cache serialization
  - Enabling cache serialization
  - How does cache serialization work?
  - Caching of offloaded objects
  - How does caching of offloaded objects work?
- [Workspaces](https://www.union.ai/docs/v1/union/user-guide/core-concepts/workspaces/page.md)
  - Creating a workspace
  - Running a workspace
  - Filesystem persistence
  - Editing a workspace
  - The workspace detail view
  - Archiving a workspace
  - Workspace CLI commands
  - Create a workspace configuration
  - Create a workspace
  - Stop a workspace
  - Update a workspace
  - Get existing workspaces
  - Start a workspace
  - Customizing a workspace
  - Setting secrets
  - Setting CPU, memory, and GPU resources
  - Specifying custom `on_startup` commands
  - Specifying custom container images
  - Authenticating with GitHub
  - Sorting and filtering workspaces
  - Troubleshooting
- [Named outputs](https://www.union.ai/docs/v1/union/user-guide/core-concepts/named-outputs/page.md)
- [ImageSpec](https://www.union.ai/docs/v1/union/user-guide/core-concepts/image-spec/page.md)
  - Install Python or APT packages
  - Install Conda packages
  - Use different Python versions in the image
  - Import modules only in a specify imageSpec environment
  - Install CUDA in the image
  - Use Nvidia docker image
  - Install packages from extra index
  - Build an image in different architecture
  - Customize the tag of the image
  - Copy additional files or directories
  - Define ImageSpec in a YAML File
  - Build the image without registering the workflow
  - Force push an image
  - Getting source files into ImageSpec

---
**Source**: https://github.com/unionai/unionai-docs/blob/main/content/user-guide/core-concepts/_index.md
**HTML**: https://www.union.ai/docs/v1/union/user-guide/core-concepts/
