Bulk Actions using the Webex API
March 27, 2019
Let’s say we need to make multiple similar requests to the Webex API. Maybe you want to send the same message to multiple Spaces or edit the same attribute of various users in your org. Currently, you’ll need to make those requests one at a time. This post will walk through both editing and deleting multiple users in an organization, and removing a list of rooms as well, to show you how to loop through a list of items to achieve a bulk action. You can then use this method to handle the majority of bulk actions with some relatively minor changes.
Since we’re first discussing editing and deleting multiple users from an organization, you’ll need to have admin privileges in order to run this particular portion of the example. If you modify the code for less restricted actions, like deleting rooms in the second portion, admin privileges won’t be needed. Also note that once a user is deleted, there is no way to restore that user, so a new user will need to be created if you delete any users by mistake (probably best to run this on a test org before implementing it on your real org).
This demo uses the requests library for python, so you may need to install that if you have not done so already.
One of the examples below is written for Python 2, and the other for Python 3, so keep that in mind as you go along. Really, the only difference is how the quote function is imported. In Python 2, use from urllib import quote
or in Python 3, it's from urllib.parse import quote
.
anchorUpdating a List of Webex Users
anchorWe’ll start by editing a list of people. Let’s say the email domain of your company is changing, so you want to update all of your user accounts to reflect this. This example assumes that you have all of the email addresses that need to be changed, in a single column CSV file, like this example CSV.
Note that the first row, where headers typically go, is intentionally left empty.
This tutorial refers to the EditDeletePeople sample application found on GitHub. You might want to open that repository and follow along. We'll note the correct line numbers as we go.
There are several scripts in the sample application. This portion of the tutorial focuses on edit_people_emails_from_csv.py
.
Configuration
The code requires four small changes to configure your application. (lines 20 through 23 if viewing from the GitHub repo). The changes required are:
bearer = "ADMIN_TOKEN" # A Oauth token for a Webex Admin user
filepath = "/full/path/to/people_emails.csv"
from_domain = "@domone.com"
to_domain = "@domtwo.com"
bearer must be an OAuth token for a Webex admin user.
If you are an admin, for testing purposes you can sign in to the developer portal and copy your token from the section, “Your Personal Access Token,” found here
Note the developer portal token currently only lasts 12 hours, so if you want this to be a more permanent solution you can run without manually updating the token each time you run it, you want to build an integration
filepath must be either a full/absolute filepath or a relative filepath to the CSV from the location of the python script on your machine.
from_domain is the current domain of the user email addresses. For example, if the new email looks like
john@oldcorp.com
you would enter@oldcorp.com
.to_domain is the desired domain of the user email addresses. For example, if the new email looks like
john@newcorp.com
you would enter@newcorp.com
.
How it works
Starting at line 25, we read the emails in the file here:
lines = []
with open(filepath, 'r') as f:
lines = f.readlines()
then in line 32 we loop over each email in the .csv file:
for line in lines[1:]:
For each email address, we look up the person details from Webex with the sendGET function. This also gives us the personId, which we need to make any changes to a person. Then in line 50, we edit the email address to use the new domain and update the person detail dictionary:
data.update({"emails":[new_email]})
Then we tell Webex to update the person with the sendPUT function. The bulk of this effort takes place between lines 39 and 54.
new_email = person_email.replace(from_domain, to_domain)
data = person_details[0]
data.update({"emails":[new_email]})
result = sendPUT(edit_url.format(person_id), data)
The example code also handles API throttling responses in the bottom third of the code. More details about that can be found in our Retry-After handler code sample.
anchorDeleting a List of Webex Users
anchorNow let’s say we have people we want to delete from Webex. Assuming we have a CSV file setup in the same way as above, our code will look very similar, and even a little shorter. We’ll trade out our sendPUT function for sendDELETE.
Take a look at the script delete_people_from_csv.py
. Note the differing import of the quote function, so that this code will work for Python 2 instead.
This time, you’ll only need to edit bearer and filepath on lines 20 and 21.
In summary, this code is almost the same as the code to edit people. We still have to look up the personId using the email address and our sendGET function. Then we use that ID to delete the person with our sendDELETE function.
anchorDeleting a List of RoomIds from Webex
anchorWhat if you already have a list of IDs? We can simplify this even further and show how you could use the same process to delete a list of rooms. Assuming your roomIds are in a CSV in the same format as the emails from the previous example, we can run the following (also found in delete_rooms_from_csv.py
:
import requests
def sendDELETE(url):
response = requests.delete(url,
headers={"Accept" : "application/json",
"Content-Type":"application/json",
"Authorization": "Bearer "+bearer})
return response
bearer = "BEARER_TOKEN" #your bearer token
filepath = "rooms.csv" #each roomId on a new line.
lines = []
with open(filepath, 'r') as f:
lines = f.readlines()
delete_url = 'https://api.ciscospark.com/v1/rooms/{0}'
failure = False
for line in lines[1:]:#basically, this is 'for every ID in the list'
room_id = line.strip('\r\n')
print("RoomId to delete is: {0}".format(room_id)) #we'll just print this roomId.
print("Deleting room...")
result = sendDELETE(delete_url.format(room_id))
print("Delete result (204 is success): {0}".format(result.status_code))
Once again the bearer and filepath will need to be changed, but otherwise, this code is even shorter than the others. It doesn’t require a sendGET at all, because we’re starting with the IDs. That means we can go right into the delete action.
Since we’re using a list of IDs, this could be easily translated to pretty much any Webex API endpoint, whether it be deleting rooms, memberships, or people. All that would really need to be changed is the delete_url.
anchorThe code
anchorThe full code and sample CSVs for everything discussed in this post can be found in our Webex Samples GitHub repository.