Quickstart: build your first workflow

In this quickstart, you scaffold a workflows project with the Mistral CLI, add a workflow with one activity, run a worker on your machine, and start an execution that returns a greeting. It takes about 15 minutes. For what workflows, activities, and workers are, see Workflows.

Before you begin

Before you begin

1. Create the project

1. Create the project

Scaffold a workflows project with mistral workflows init, the same command as mistral init --preset workflow:

mistral workflows init my-workflow
cd my-workflow

If you created my-workflow in the Mistral CLI quickstart, go to that directory instead.

The project contains a Python worker in apps/worker, with the Workflows SDK already configured. Open the generated .env file and set MISTRAL_API_KEY to your API key: the worker reads it to connect to Mistral. Git ignores .env, so the key stays out of the repository.

2. Add a workflow

2. Add a workflow

Create apps/worker/src/worker/workflows/hello.py:

from pydantic import BaseModel

import mistralai.workflows as workflows


class HelloInput(BaseModel):
    name: str = "World"


@workflows.activity()
async def greet(name: str) -> str:
    """A simple activity that returns a greeting."""
    return f"Hello, {name}! Welcome to Mistral Workflows."


@workflows.workflow.define(
    name="hello-world",
    workflow_display_name="Hello World",
    workflow_description="A minimal hello-world workflow.",
)
class HelloWorkflow:
    @workflows.workflow.entrypoint
    async def run(self, input: HelloInput) -> str:
        return await greet(input.name)

The workflow is registered as hello-world and takes a name. Its only step, greet, is an activity: if the worker stops during an execution, the platform resumes from the last completed activity instead of starting over.

You don't need to register the workflow by hand. The worker entrypoint, apps/worker/src/worker/entrypoints/worker.py, discovers every workflow in the workflows package:

workflow_classes = workflows.discover_all_workflows_in_package("worker.workflows")
await workflows_client.run_worker(workflow_classes)
3. Start the worker

3. Start the worker

From the root of the project, start the worker with mistral dev:

mistral dev

The worker connects to Mistral, registers hello-world, and waits for executions. Keep this terminal open: an execution runs only while a worker is running.

4. Start an execution

4. Start an execution

In a second terminal, start an execution of hello-world. With wait_for_result, the call returns when the execution completes:

import os

from mistralai.client import Mistral

client = Mistral(api_key=os.environ["MISTRAL_API_KEY"])

execution = client.workflows.execute_workflow(
    workflow_identifier="hello-world",
    input={"name": "Ada"},
    wait_for_result=True,
)
print(execution.model_dump_json(indent=2))
You should see

You should see

The response holds the value that the workflow returned:

{
  "workflow_name": "hello-world",
  "execution_id": "<execution-id>",
  "result": {
    "result": "Hello, Ada! Welcome to Mistral Workflows."
  }
}

In the console, the execution of hello-world appears in the Executions tab with the same result. The worker terminal logs the execution.

If the call waits and then times out, check that the worker from step 3 is still running, in the workspace of your API key.

Clean up

Clean up

To stop the worker, press Ctrl+C in its terminal. Keep the project if you want to deploy it in the next quickstart.

Going further

Going further