---
title: "Migrating From Mantra"
page-category: "searchable"
---
This guide covers core differences between Mantra and Conductor, and sets expectations for code 

## Workflow API

Mantra defines a custom API for writing workflows that uses the same syntax as Netflix's [Metaflow](https://github.com/Netflix/metaflow/blob/master/metaflow/tutorials/00-helloworld/helloworld.py).
This workflow is then serialized and executed as a AWS StepFunctions DAG.

Conductor, by constrast, does not have its own workflow API, instead using Airflow's DAG API directly, and executing on the native Airflow scheduler.
This allows you to directly leverage the suite of production features and open source libraries within the Airflow ecosystem.


## Code Execution
In Mantra, every DAG step is executed within an ECS task using a container that is built with all of the code and dependencies in your project.
This makes it straightforward to run arbitrary Python code in any DAG step, like so:
```python
class Workflow(BaseWorkflow):
    @classmethod
    def dag_name(cls):
        return os.path.splitext(os.path.basename(__file__))[0]

    def __init__(self, profile_params):
        super().__init__(profile_params)

    @step
    def task1(self):  # Arbitrary python code can go in here.
        def slow_fib(n):
            if n <= 1:
                return n
            return slow_fib(n-1) + slow_fib(n-2)
        print(slow_fib(10))

    def task2(self):  # Call any function in your project.
       import my_func from my_module
       my_func(1,2,3) 
    
    @workflow
    def assemble_dag(self):
        return ("task1", "task2")
```

Airflow tasks work differently: their `execute` method is called directly by a Python process in the Airflow worker environment.
In this mode of execution, lightweight tasks such as making `SQL` queries or using AWS APIs can run much more quickly than in Mantra.
However, dependencies and helper functions must be installed within the Airflow environment in order to be imported and called.
While it's crucial to be able to execute custom Python logic in workflows, it is impractical to install every custom helper function for every one of your projects onto the Airflow environment.

To solve this problem, Conductor provides the ability to execute arbitrary code via the `SageMakerProcessingOperator`.
Just like Mantra, Conductor builds a Docker container with all of the code and dependencies in your project, and this container is used by default in the Conductor `SageMakerProcessingOperator`, routing the container execution to a supplied `Callable` entrypoint.

The previous custom fibonacci example looks like this when written with Conductor:

```python
# module.py
def slow_fib(n):
    if n <= 1:
        return n
    return slow_fib(n-1) + slow_fib(n-2)

# dag.py
from module import slow_fib
train_data_check = c.operators.SageMakerProcessingOperator(
    task_id="train-data-check",
    entrypoint=slow_fib,
    mode="training",
    model_version="1",
)
```


## Hooks
Mantra hooks are simply python utility functions that provide much easier interfaces to external resources, via the AWS API for example.
As a result, you can use Mantra hooks in Conductor simply by adding Mantra as a utility library with `poetry add mantra`.

Conductor (and Airflow!) has its own set of hooks, but Mantra currently has more implemented hooks, and the behavior of comparable hooks may be slightly different.
It may be easier to port a Mantra project to Conductor by taking a dependency to Mantra for the initial migration.

Combining all of the the above, the quickest way to refactor an existing Mantra project into a Conductor project is to replace every step of your Mantra DAG with a Conductor `SageMakerProcessingOperator`, using the contents of each `@step` method in your Mantra DAG as the `entrypoint` argument for Conductor `SageMakerProcessingOperator` in the Conductor Airflow DAG.
