Daily scheduling in PagerDuty with weekly alternating between different teams

June 15, 2021

Recently I had a chat with two companies who asked for the same scheduling algorithm.

The solution was so easy, so I decided to use it to showcase how easy do custom scheduling for companies without using any external products, only by using one open-sourced library to interact with PagerDuty API.

Situation

Both clients have 2 teams located in different USA cities. The teams are working on different sides of the same product. So as a no-brainer, they used daily rotation. But because a lot of incidents were involved with their clients - incidents usually took a few days to resolve. And passing all information to the next on-call person inside your team is easy - just talk near a watercooler. But passing the same information to a different team was much more problematic.

Scheduling algorithm

The companies asked for scheduling when only developers from team A should be assigned if a week is even, and on odd weak - developers from team B. You cannot create this schedule in PagerDuty UI, it’s only possible with a use of the API. But working with the API is not so straightforward, it’s much easier to interact with a library pdscheduling where to create a schedule you just need to provide an array of assignments for every hour of the week. Take a look at full scheduling script:

import random
import datetime

from pdscheduling import PagerDuty

team1 = ['PIMHAAA', 'BBBBB', 'CCCCC', 'DDDDD', 'EEEEEE']
team2 = ['PIMHFFF', 'GGGGG', 'HHHHH', 'IIIII', 'JJJJJ']

pd = PagerDuty("token")
users = pd.get_users()

date = datetime.date.today()
_year, week_num, _day_of_week = date.isocalendar()

if week_num % 2:
    active_team = team1
else:
    active_team = team2

schedule = []
for day in range(7):
    user_index = (week_num * 7 + day) % len(active_team)
    user = active_team[user_index]
    for hour in range(24):
        schedule += [user]
pd.create_or_update_schedule(name="Rotated", hours=schedule)

It’s only 20 lines of code.

Is this enough for production use?

Almost… You can put the script in cron on Monday. But you need to handle properly notification. Because in the script we generate and apply a schedule on Monday. Developers would be not happy to get an alert without any prior notification. The simplest solution - run the same schedule algorithm for the next week and manually email it to users.