Skip to main content

Start a new project with Resonate

How to start a new project using Resonate.

Resonate provides a CLI to scaffold new projects using templates. There are several templates available depending on your use case and the programming language.

Install the Resonate CLI

The CLI and the Resonate Server are bundled together. But, you can use the CLI independently of the server — That is, don't need to run the server to get started. Choose a template that only uses local invocations (Runs), to get started without the server (do not choose an RPC template).

Install the CLI using brew or download a binary from the releases page

brew install resonatehq/tap/resonate

Choose a template

After the CLI is installed, list the available templates and their descriptions using the following command:

resonate projects list

The language of the template is indicated in the name and description. And the description will tell you if it uses the Resonate Server or not.

Scaffold a project from one of the listed templates.

resonate projects create --template <template_name> --name <your_project_name>

The CLI will create a new directory with the name you provided and scaffold the project files in that directory.

Resonate usage pattern

Regardless of the template you choose, the pattern of the project will be similar.

Any Worker or script that uses Resonate will need to import the Resonate SDK and initialize it.

from resonate import Resonate

# Initialize Resonate with a local promise store
# Great for local development.
resonate = Resonate.local()

# Initialize Resonate with a remote promise store
# Great for building production grade distributed applications.
resonate = Resonate.remote()

If you are using a template that requires the Resonate Server (anything that performs remote operations), you will need to run it in a separate terminal.

resonate serve

The Resonate Server acts as a remote promise store and message source, enabling you to durably invoke functions across different Workers or Application Nodes.

To give Resonate control over the execution of your functions, you will need to register the top-level function with Resonate.

Top-level function

A top-level function is the first function in the Durable Call Graph, invoked by resonate.run(), or resonate.rpc().

We call this the Ephemeral to Durable transition.

This is different from invoking a function from within a Durable function, which is a Durable to Durable transition, and is done using the Context object.

# using a decorator
@resonate.register
def foo(ctx, params):
# ...
return result

# or using the register method
def foo(ctx, params):
# ...
return result

resonate.register(foo)

Registered functions can then be invoked using the run or rpc methods.

# If the function is defined locally in the same Worker or Application Node
result = foo.run("promise-id", params)

# If the function is defined remotely in a different Worker or Application Node
result = resonate.options(target="<transport_plugin>://<unique_id>@<group>/<id>").rpc("foo", "promise-id", params)

If you need to ensure functions in a Worker / Application Node have access to a dependency, you can initialize the dependency and register it with Resonate.

db_connection = DatabaseConnection()
resonate.set_dependency("db_connection", db_connection)

def foo(ctx, params):
db = ctx.get_dependency("db_connection")
# ...
return result

From here, we recommend checking out our catalog of example applications to find something that matches your use case.

For details on specific features, refer to the feature development guides.

To learn more about Resonate concepts and functionality, check out the tutorials.