wxcadm

Welcome to the documentation home of wxcadm, a Python 3 library to simplify the API calls to Webex in order to manage and report on users of Webex Calling.

Although the primary focus is Webex Calling, many of the other Webex admin functions are included. This library is not meant to be an interface to the Meetings and Messaging capabilities of Webex….there are plenty of other modules that provide that.

This project is not affiliated with or supported by Cisco, although the APIs that are used by the project are, for the most part, the public Webex APIs available at https://developer.webex.com.

Status

The main branch version is stable and available for use and the current PyPI PIP Package is built from that branch.

There are still enhancements being made and I am addressing any issues as they are reported. New features can also be discussed in the discussions page.

Installation

wxcadm is available as a PIP package.

$ python3 -m pip install wxcadm

Quickstart

By creating a Webex instance with a valid API Access Token, the module will pull the Webex Organization information as well as all the People within the Organization. The Org instance will contain all People, whether they have the Webex Calling service or not. An Org method get_webex_people() makes it easy to get only the People that have Webex Calling.

You can obtain a 12-hour access token by logging into https://developer.webex.com and visiting the Getting Started page. If you want a more permanent access method, you can create a Webex Integration.

Once you have the access token, the following will initialize the API connection and pull data

import wxcadm

access_token = "Your API Access Token"
webex = wxcadm.Webex(access_token)

Since most administrators only have access to a single Webex Organization, you can access that Organization with the org attribute. If the administrator has access to more than one Organization, they can be accessed using the orgs attribute, which is a list of the organizations that can be managed. See the “Regarding Multiple Organizations” section below for further information.

You can see all the attributes with

vars(webex.org)

Note that, by default, all the People are pulled when the Org is initialized. For large organizations, this may take a while, but then all the People are stored as Person objects.

To iterate over the list of people, simply loop through the people attribute of the Org. For example:

for person in webex.org.people:
    # Print all of the attributes of the Person
    print(vars(person))
    # Or access the attributes directly
    email = person.email

About API Scopes

Most of the API calls that the wxcadm methods use are supported by the “public” Webex API found at developer.webex.com. The 12-hour token that can be obtained by logging in there includes all of the necessary scopes to perform all of the API calls that wxcadm supports. As mentioned in the Getting Started with XSI section, you need to have XSI enabled for your Org, however.

Integrations

The 12-hour token from developer.webex.com is useful for testing, and for running one-time scripts, but logging in every 12 hours isn’t feasible for a full-featured middleware that provides administrative access to Webex, such as a bot or management portal. To obtain a longer-lived token, which also includes a refresh token to make the access permanent, a developer should create an Integration. As specified in the developer documentation, an Integration must includes the authorization scopes that are required to perform all of the specified functions. Where possible, this documentation lists the required scopes for each method or property, however an Integration created with the following scopes should have access to nearly everything that wxcadm can do:

  • spark-admin:resource_groups_read

  • analytics:read_all

  • spark-admin:people_write

  • spark-admin:organizations_read

  • spark-admin:workspace_metrics_read

  • spark-admin:places_read

  • spark-admin:devices_read

  • spark-admin:workspace_locations_write

  • spark-admin:telephony_config_read

  • spark-admin:telephony_config_write

  • spark-admin:devices_write

  • spark-admin:workspaces_write

  • spark:calls_write

  • spark-admin:roles_read

  • spark-admin:xsi

  • spark-admin:workspace_locations_read

  • spark-admin:workspaces_read

  • spark-admin:resource_group_memberships_read

  • spark-admin:resource_group_memberships_write

  • spark-admin:call_qualities_read

  • spark:kms

  • audit:events_read

  • spark-admin:places_write

  • spark-admin:licenses_read

  • spark-admin:people_read

  • spark:xsi (if enabled)

Note that not all of these are required for all functions, but this provides access to almost all of the functions that wxcadm supports.

The CP-API

In some cases, the public Webex API does not provide the full functionality available in Webex Control Hub. Cisco continues to enhance the Webex API, but, for operations that are not yet available via that API, wxcadm also takes advantage of the CP-API, which is the API that is used by Webex Control Hub directly.

Unfortunately, the authorization scopes required by the CP-API are different than the scopes that can be defined for an Integration. In these cases, the only API Access Tokens that have the required scopes are the 12-hour token from developer.webex.com and the “native” Control Hub token that is used when signing into Control Hub.

Methods that require a token with the CP-API scope are noted in the documentation with the following:

Warning

This method or attribute requires the CP-API access scope.

Regarding Multiple Organizations

Most Webex admins only have access to a single Org, but Webex does allow a single admin to manage multiple Orgs. When the Webex instance is created, it creates the Webex.org attribute when only one Org is present. If there are multiple, the orgs attribute contains a list of all the Orgs. orgs is created whether there is one Org or multiple, so Webex.org is equivalent to Webex.orgs[0]. For example:

import wxcadm

access_token = "Your API Access Token"
webex = wxcadm.Webex(access_token)
for org in webex.orgs:
    print(org.name)

It is recommended to take action on only one Org at a time, although the design allows for more flexibility. For example, to enable VM-to-Email across all users of every Org, the following is supported:

for org in webex.orgs:
    for person in org.people:
        person.enable_vm_to_email()

The get_org_by_name() method is provided to allow the selection of the desired org by name.

my_org = webex.get_org_by_name("My Company")
for people in my_org.people:
    person.enable_vm_to_email()

Usage Reference

The following examples show many of the common use cases supported by wxcadm:

import wxcadm

access_token = "Your API Access Token"
webex = wxcadm.Webex(access_token)

# Get all of the Locations within the org
locations = webex.org.get_locations()

# Get a list of all of the People who have Webex Calling
wxc_people = webex.org.get_wxc_people()
# Or iterate over the list directly
for person in webex.org.get_wxc_people():
    print(f"Name: {person.display_name}")
    print(f"Email: {person.email}")

One of the more useful methods is the get_person_by_email() method, which takes an email address and returns the Person instance of that user. This is especially useful if processing an external list of email addresses for bulk processing.

email_list = ['user1@company.com', 'user2@company.com', 'user3@company.com']
for email in email_list:
    person = webex.get_person_by_email(email)
    print(person.display_name)

Common Webex Use Cases

These are some commonly-requested changes that most Webex Calling admins have to deal with.

Organization and Location Numbers

In order to create users, or sometimes to report on them, it is useful to pull the numbers associated with an Org. The Org.numbers attribute provides a list of numbers, along with the Location each is assigned to. If a number is assigned to a Person, then the person instance will be included.

import wxcadm

access_token = "Your API Access Token"
webex = wxcadm.Webex(access_token)

for number in webex.org.numbers:
   if "owner" in number:
      # The number is assigned
      print(f"{number['number']} is assigned to {number['owner'].email}")
   else:
      # The number is not assigned
      print(f"{number['number']} is not assigned")

Assign Webex Calling to an Existing User

In order to assign Webex Calling, you must know the Location instance and provide either the phone number, the extension, or both.

import wxcadm

access_token = "Your API Access Token"
user = "user@domain.com"
location_name = "Location Name"
phone_number = "+18185552345"

webex = wxcadm.Webex(access_token, fast_mode=True)

user_location = webex.org.get_location_by_name(location_name)
person = webex.org.get_person_by_email(user)
if person is None:
    print(f"Could not find user {user}")
else:
    success = person.assign_wxc(location=user_location, phone_number=phone_number)
    if success:
        print("Succeeded")
    else:
        print("Failed")

Change the user’s phone number

import wxcadm

access_token = "Your API Access Token"
webex = wxcadm.Webex(access_token)
# Find the Person that you want to change
person = webex.org.get_person_by_email("user@domain.com")
# Call the `change_phone_number()` method for the user
success = person.change_phone_number(new_number="8185551234", new_extension="1234")
# The Person instance will reflect the change
if success:
    print(person.numbers)

Get the Hunt Groups and Call Queues the user is an Agent for

The hunt_groups and call_queues attributes hold all of the instances of each that the user is assigned to as an “agent”. Of course, this would be more useful if there were methods for those Classes, but that’s coming soon. For now, it makes it easy to find all of the places the user is being used.

import wxcadm

access_token = "Your API Access Token"
webex = wxcadm.Webex(access_token)
# Find the person you want the details for
person = webex.org.get_person_by_email("user@domain.com")
for hunt_group in person.hunt_groups:
    hg_name = hunt_group.name
    # And anything else you want to do
for call_queue in person.call_queues:
    cq_name = call_queue.name
    # etc...

Workspaces

The Webex Calling functionality that is exposed to Workspaces is limited. At this time, the Workspaces and their associated Workspace Locations can be obtained with the get_workspaces() method of the Org instance. This will populate the Org.workspaces and Org.workspace_locations attributes, which contain the information. As the API is enhanced to provide capabilities, new methods will be added to wxcadm.

Logging

wxcadm supports the standard Python logging module, using the wxcadm logger name. The INFO and DEBUG logging levels are useful to see the interaction with the Webex API.

Data Structure Note

At the moment, the module works in two ways. In one way, it populates attributes based on the data from Webex. In another, it stores the JSON representation directly from Webex. The latter is very handy for pushing data back to Webex, but it requires some knowledge of the API structure, and doesn’t abstract it well. Not to mention that the Webex API doesn’t do anything in a standard way.

The purpose of this module is to simplify that so the user doesn’t have to have detailed knowledge of the Webex API, so we are faced with a decision: keep the flexibility provided by the raw data or simplify it, at the cost of compatibility when the Webex API is changed.

Nearly every instance of all classes has a :py:attr`config` attribute that contains the JSON configuration from Webex. Properties are exposed for most commonly-used attributes.

Full Reference

Indexes and tables