Getting Started

Newcomers introduction to create your first application with Dispatch

In this tutorial, you will create a Dispatch account and use the Python SDK to write your first Functions.

Setup

Create a Dispatch account either through the console or via the CLI. We recommend the CLI because it gives you access to local development features.

First, install the Dispatch CLI. Via Homebrew:

brew tap stealthrocket/dispatch
brew install dispatch

or directly with Go:

go install github.com/stealthrocket/dispatch@latest

Then login to create an account:

dispatch login

The login command will open a new browser window to create a new account. It will also automatically create an API key and generate your ~/.dispatch.toml configuration file.

You are now ready to start writing your first durable cloud application with Dispatch!

Your first function

In this tutorial, we will use Python as an example to write a program that sends HTTP requests to a remote endpoint and retries if the requests fail.

Installing dependencies

Before we can dive into the code, we need to install the Dispatch SDK for Python, and a few dependencies that we will use in this guide.

The SDK is published on PyPI as the dispatch-py package.

pip install dispatch-py[fastapi]

The Dispatch Python SDK currently requires Python >= 3.8.

Declaring functions

Functions are exposed to the Dispatch platform over HTTP. In this example, we use FastAPI integration to construct a simple HTTP server.

The first step is constructing the Dispatch instance, which installs the necessary routes to run functions. In a file named main.py, we will write the following code:

from fastapi import FastAPI
from dispatch.fastapi import Dispatch

app = FastAPI()
dispatch = Dispatch(app)

We can now declare functions using the Dispatch instance. This is done with the dispatch.function decorator on any Python function. In our example, we declare a publish function that posts a payload to a URL passed as the first argument.

import httpx

@dispatch.function
def publish(url):
    r = httpx.post(url, data={'hello': 'world'})
    r.raise_for_status()

Finally, we configure a route to handle GET requests on the HTTP server. This request handler will submit the call to publish, which will be driven by the Dispatch platform, including being retried in the event of a failure.

@app.get('/')
def root():
    publish.dispatch('https://httpstat.us/200')
    return "OK"

Run your function locally

The Dispatch CLI gives you a simple way to run functions locally and handles the communication with the Dispatch scheduler:

dispatch run -- uvicorn main:app

You can now interact with your HTTP server and see Dispatch orchestrating the execution of your functions:

curl http://localhost:8000/

The server output should look something like this:

As we can see, the server handled two requests. Our curl command sent the first request to the root function, which dispatched the call to publish. The second request was sent to execute the publish call asynchronously, which sent the payload to the provided URL!

Remember how we wanted to make sure the operation would be retried if it encountered a failure? This is what the r.raise_for_status() call is for! If the HTTP request fails, an exception will be raised, and the stateful function will report the issue to the Dispatch platform, which will then schedule it at a different time.

Multi-step workflows

When using .dispatch , you trigger the orchestration of your application by Dispatch but we can go further with async functions.

Using the @dispatch.function decorator on async Python functions, you can pause them at await points waiting for asynchronous operations to complete, allowing you to build durable workflows.

Let's update our code with the following:

@dispatch.function
async def publish_and_report(url):
    resp = await publish(url)
    await report(resp)

@dispatch.function
def publish(url):
    r = requests.post(url, data={'hello': 'world'})
    r.raise_for_status()
    return r

@dispatch.function
def report(response):
    print("Response:", response)
    
@app.get('/')
def root():
    publish_and_report.dispatch('https://httpstat.us/200')
    return "OK"

With this update, the publish_and_report function is creating a pipeline by having Dispatch orchestrate the execution of publish and then report. This simple example demonstrates how we can create fully dynamic and durable workflows.

Check out our examples to see more advanced use cases.

Next up

Now that you have the basics covered, here are a few next steps to consider:

  • Deploy your application to your infrastructure!

  • You can visit the to familiarize yourself with the Dispatch SDKs and protocol.

  • Invite colleagues to your organization to start building together (Settings -> Collaborators).

Last updated

©️ Stealth Rocket, Inc. All rights reserved.