Skip to content

Getting started

Dispatch makes it easy to work with rate limited or unreliable servers, like the one we’ve prepared for this guide. We’re hosting a server that serves random cat facts, but it’s very unreliable and fails with 500 quite often.

cat-facts.dispatch.run

Imagine our application is critically dependant on that crucial cat knowledge. Normally, we’d have to implement retries on request errors or even push this work into a queue. But with Dispatch, all we have to do is wrap the function with a @dispatch.function decorator and we’ll fetch our cat facts reliably no matter what.

Let’s see how simple it is to build reliable systems with Dispatch and maybe learn a thing or two about cats.

Install Dispatch CLI

CLI is the fastest way to create a Dispatch account and set up local development environment.

It can be installed via Homebrew:

Terminal window
brew tap stealthrocket/dispatch && \
brew install dispatch

Or with Go:

Terminal window
go install github.com/dispatchrun/dispatch@latest

Next, log in to create an account:

Terminal window
dispatch login

login command will open a browser to create a Dispatch account, create an API key and save it on your machine.

Install dependencies

Before we can dive into the code, we need to install a few dependencies:

  • dispatch-py — Dispatch SDK to make functions resumable.
  • fastapi — Web framework for building APIs.
  • httpx — HTTP client to fetch the cat facts.
  • uvicorn — HTTP server for a FastAPI application.

Run this command to install them:

Terminal window
pip install "dispatch-py[fastapi]" fastapi httpx

Create a basic application

Put Dispatch aside for now and create a simple HTTP server that fetches a cat fact from https://cat-facts.dispatch.run and prints it. Create an cat_facts.py file and paste the following code:

from fastapi import FastAPI
import httpx
app = FastAPI()
async def fetch_cat_fact():
async with httpx.AsyncClient() as client:
response = await client.get("https://cat-facts.dispatch.run")
# Raise an exception when request has failed
response.raise_for_status()
cat_fact = response.text
print(cat_fact)
@app.get("/")
async def index():
await fetch_cat_fact()
return "OK"

Start the application:

Terminal window
uvicorn cat_facts:app

Send a request to / to confirm it’s working:

Terminal window
curl http://localhost:8000

If it hasn’t failed right away, try sending a few more requests to stumble upon a failure in the cat facts API.

httpx.HTTPStatusError: Server error '500 Internal Server Error' for url 'https://cat-facts.dispatch.run/'

This means that fetch_cat_fact function raised an exception and now the application is left without a cat fact.

Make the application reliable

Fortunately, Dispatch can be added to make any Python function retry on failure, limit the execution rate and resume from the last successfull await statement.

First, import a Dispatch SDK along with its built-in FastAPI integration and initialize a Dispatch instance with a reference to the FastAPI server.

from fastapi import FastAPI
import httpx
from dispatch.fastapi import Dispatch
app = FastAPI()
dispatch = Dispatch(app)
async def fetch_cat_fact():
async with httpx.AsyncClient() as client:
response = await client.get("https://cat-facts.dispatch.run")
# Raise an exception when request has failed
response.raise_for_status()
cat_fact = response.text
print(cat_fact)
@app.get("/")
async def index():
await fetch_cat_fact()
return "OK"

Next, wrap a fetch_cat_fact function with a @dispatch.function decorator and use dispatch method on that function to execute it.

from fastapi import FastAPI
import httpx
from dispatch.fastapi import Dispatch
app = FastAPI()
dispatch = Dispatch(app)
@dispatch.function
async def fetch_cat_fact():
async with httpx.AsyncClient() as client:
response = await client.get("https://cat-facts.dispatch.run")
# Raise an exception when request has failed
response.raise_for_status()
cat_fact = response.text
print(cat_fact)
@app.get("/")
async def index():
await fetch_cat_fact()
await fetch_cat_fact.dispatch()
return "OK"

That’s all it took to make fetch_cat_fact retry on request errors and asynchronously execute in background.

Restart the application, but this time use Dispatch CLI:

Terminal window
dispatch run -- uvicorn cat_facts:app

Now, try sending a few more GET / requests to this server and see how failures are automatically retried.

This is the magic of Dispatch. It ensures that fetch_cat_fact is executed successfully no matter what, whether HTTP requests fail or your server has suddenly rebooted.

Under the hood, when fetch_cat_fact.dispatch is called, fetch_cat_fact is not executed immediately. Instead, Dispatch schedules the execution of fetch_cat_fact and pings back our server when it’s the time to do so. That way, fetch_cat_fact is executed asynchronously in background. Whenever a failure happens, Dispatch is notified and retries the execution again.