The "Bulk update or create a Class" endpoint is a unique endpoint with specific behaviors that may need further understanding. This article is intended to give some guidance for data managers or integration specialists on how to use it effectively. This article will also demonstrate how to use this and the "Get all Classes" endpoint in order to build a complete solution.
This tutorial will use Python, the popular library Requests, and built-in data structures to demonstrate how to accomplish this goal.
Use Case
We want to select classes that have "Study Hall" in the name, and toggle its `archived` status. We will use this feature when running ManageBac reports, for ease in hiding them from the report builder. In this way, we have a mechanism that excludes classes from being reported on, in a way that directly addresses our specific requirements.
Steps
- The program will fetch all of the currently active classes from the "Get all Classes" endpoint
- It will loop over every class and identify whether this is a class whose status we would like to toggle
- It will send patch request to the "Bulk update or create a Class" endpoint with the body build in step 2
- Check the responses, and if necessary, reports errors
Code
Below is demonstrated the core part of the program that defines the variables and library, the main function, which simply calls some other functions. The variable "classes_url" and "set_archived_status_to" will be used later:
As we can see, the main function fetches active study hall classes, and passes the response to the set_status function. We get back the errors, which we process by calling process_errors with both the study halls and the errors.
Fetch study halls
The function fetch_active_study_hall_classes will use the API endpoint "Get all Classes" to find all classes.
The classes endpoint takes a query parameter "archived" that needs to be passed as "true" or "1" if the classes you are fetching are archived. By default, it responds with active classes. This line will build the GET request required, depending on the value of "set_archived_status_to":
That will build the following request:
GET https://api.managebac.com/v2/classes?page=1&archived=x
Where "x" will be the opposite of the value we will set the archived status to. In that way, if we want to set Study Hall classes to archived, it will fetch active classes.
Now that we have got the response from the endpoint, we loop through the classes in the body. We will only keep the classes properties that are required to update: The class ID and "archived" set to the intended value:
We now have a list of records, where each record has an ID and archived property. It will look like this:
[
{
"id": 1234567,
"archived": True
}, {
"id": 93223,
"archived": True
}, {
# etc
}
]
We will now reach out to the ManageBac endpoint that can perform the bulk update. According to the documentation, the payload body needs to have a "classes" property with the list above:
{
"classes": [
{
"id": 1234567,
"archived": True
}, {
"id": 93223,
"archived": True
}, {
# etc
}
]
}
We will now start to write the function that sends this data:
The "Bulk Update or Create" endpoint requires us to use the PATCH method at the same endpoint URL used previously. Since it is a different method, instead of returning with classes, it takes action on ManageBac and then returns individual responses for each action. We store the individual responses in the variable "all_responses".
Let's loop over the responses, and see if we can find any errors, and return them:
Finally, we implement the "process_errors" function:
Source Code
Please find the source code used in this article:
""" 1. The program will fetch all of the currently active classes from the "Get all Classes" endpoint 2. It will loop over every class and identify whether this is a class whose status we would like to toggle 3. It will send patch request to the "Bulk update or create a Class" endpoint with the body build in step 2 4. Check the responses, and if necessary, reports errors """ import requests set_archived_status_to = True # change this to whether you want Study Hall classes to be archived (True) or not (False) top_level_domain = 'com' # change to cn or eu or us as appropriate classes_url = f'https://api.managebac.{top_level_domain}/v2/classes'
def fetch_active_study_hall_classes() - list: """ Fetch active classes with 'Study Hall' in the name""" page = 1 classes = [] while True: # api request here: params are the query parameters on this endpoint response = requests.get(classes_url, params={'page': page, 'archived': not set_archived_status_to}) response.raise_for_status() # parse the body body_json: dict = response.json() body_meta: dict = body_json.get('meta', {}) body_classes: list = body_json.get('classes', []) # loop through the classes key provided in the response for class_ in body_classes: id_ = class_.get('id') name = class_.get('name') if 'Study Hall' in name: # add dictionary with two elements that is needed for bulk update classes.append( { 'id': id_, 'archived': set_archived_status_to } ) page = body_meta.get('next_page') if not page: # no more pages break return classes
def set_status(classes) - list: """ Use the "Bulk Update or Create" endpoint and return any individual responses that are errors """ payload = { 'classes': classes } response = requests.patch(classes_url, json=payload) response.raise_for_status() all_responses = response.json() errors = [] for individual_response in all_responses: status = individual_response.get('status') if not status == 'ok': errors.append(individual_response) return errors def process_errors(classes: list, errors: list) - None: for error in errors: index: int = error.get('index') class_that_errored = classes[index] print(class_that_errored)
def main(): study_halls = fetch_active_study_hall_classes() errors = set_status(study_halls) process_errors(study_halls, errors) # ... define functions here main()