Webex with Python

While sending requests to Webex is straightforward, automating tasks programmatically requires careful consideration. Python offers convenient libraries, such as requests and urllib, but merely constructing queries is insufficient for robust automation. Challenges arise, including handling pagination for large datasets and managing response codes indicating congestion, which may warrant retries rather than immediate failure.

To address these complexities, this lab introduces an exceptional Software Development Kit (SDK) named wxc_sdk, accessible at https://pypi.org/project/wxc-sdk/. Initially designed for Webex Calling-specific APIs, this SDK has evolved to encompass a range of Webex APIs, organized as individual 'packages' within the SDK.

Now you can perform the same user lookup using Python. As with all Webex API interactions in this lab, you will use the wxc_sdk to simplify the task.

  1. Access your VS Code instance: https://dev1.pod6.col.lab:8443
  2. Click the Explorer icon at left, and you see a list of folders and files.
  3. Navigate to expand the examples folder and click to open wxc_enable_user.py. You now have the file open for editing.

  4. Here is a basic Python skeleton that you will use to execute basic Webex API requests using the wxc_sdk. The Python environment has been installed, as well as the wxc_sdk using the pip tool. To use the SDK in this program, import the WebexSimpleApi. Paste the following into your file:

  5. The wxc_sdk documentation shows that the API is instantiated using the WebexSimpleApi class, which can take a tokens parameter. For our example this will be a personal access token.

  6. Access any one of the API requests from the Webex developer documentation such as the List People API you executed previously. If necessary, sign in with pod6wbxuser@collab-api.com and password C1sco.123
  7. In the Authorization section, next to Bearer, click the copy icon then click OK on the box that appears.

  8. Switch back to VS Code and paste the personal access token you just copied to the personal_access_token line (replace ___PASTE_YOUR_PERSONAL_ACCESS_TOKEN_HERE___ and make sure it is still surrounded by the single quotes)

  9. Add the following line to instantiate the WebexSimpleApi object as "api" with this access token.

  10. You have an API object, but what can you do with it? In the Webex Documentation, you saw the Full API Reference section with all available APIs. A number of those will have a direct mapping to an API subpackage and method implemented in the SDK.

    The People API section in the Webex documentation has a corresponding PeopleApi subpackage in the wxc_sdk. This class has the methods list(), create(), details(), delete_person, update() and me(), each one corresponding to a Webex API method.

    Now repeat the GET List People query using an email address. Since the SDK was initialized as api in the previous step, you can perform the exact same query with api.people.list() and pass the email address as a parameter.

    Replace the email address in the email_to_search variable to pod6wbxuser@collab-api.com (make sure it is enclosed with quotes):

  11. Query the Webex API for people with that email address. You can store the result in a list variable called webex_user_list. Even though querying for a single email address should only yield at most a single result (because email addresses in Webex must be unique), a list is always returned.

    If you look carefully at the list() method in the documentation, the data type returned is technically a Generator. While generators have some advantages that are outside the scope of this lab, they can always be changed to a list, and we will do so in the lab to simplify the discussion.

    It is worth spending a minute looking at this line in VSCode. If you hover over any portion of the api.people.list command, you will see the documentation and possible options. If you typed this command in manually, you would also get command-line completion.

  12. Try generating a query from the machine running your Python script to the Webex cloud by clicking the Run and Debug button in the left column.
  13. Make sure the preconfigured configuration for running this script, called Python: wxc_enable_user.py is selected:

  14. Click the green Start Debugging button left of the Python: wxc_enable_user.py text. Doing so launches a Terminal with the complete logging output at the bottom. If you scroll up a bit in that Terminal (you may need to resize to make it more visible) you will notice the debug level output from the SDK. This provides visibility into all the headers and raw data being exchanged sent and received.

  15. The logging.getLogger('wxc_sdk.rest').setLevel(logging.DEBUG) command in the script is what can adjust this logging level. If you changed this to logging.INFO, you would not see any of this output. We are therefore relying on the logging in the wxc_sdk instead of requiring explicit log statements.

  16. The next task is to go over each item in the webex_user_list (there should only ever be at most one) and log some data to the console using log.info(). Each individual item of this list is assigned to webex_user. This webex_user is not a simple Python datastructure, but rather a custom one called Person, that was created by the SDK. Try to simply print it out. Add the following line:

  17. Click Start Debugging

    The output is not the most readable. Although you can identify some things that look familiar based on the Webex Documentation, the fields do not exactly match what is in the API. The key is in the wxc_sdk documentation.

    This webex_user object is of a Person class, which gives it attributes like "person_id", "emails", "phone_numbers", etc. What this means, is that if, for example, you need to retrieve this object's display name, you would use webex_user.display_name
  18. Try printing just the object's display name. Replace the log.info(webex_user) line with:

  19. Click Start Debugging

    You should see a line with "INFO __main__ User information found for" with the display name of the queried email address.

  20. If you want to print all user data in a readable format (or pass the data to some other system that does not understand these custom Python classes, the class has a method called model_dump_json() that converts everything to simpler JSON, with its simpler data formats, effectively the same thing you would receive from running the API query from the Webex documentation.

    Add the following to your code:

    The Python logging capability is used for generating output instead of a simple print() because it allows us to control the level of output of not just our own code, but also see information from the underlying SDK, which uses the same logging facility. In fact, we have set the logging level for the underlying REST calls to DEBUG level, giving greater visibility into what is being sent and received.

  21. Click Start Debugging and examine the Terminal window output.

    If you look carefully, the data structure printed matches the Response Properties from the List People method in the Webex API specification exactly (including the keys "id", "emails", "phoneNumbers", "displayName", etc.).
  22. This gives you a lot of information about a particular user, however to get all the settings, you need to use the api.people.details() method.

    As seen in the documentation above, this method requires a person_id parameter. If you look at the output of your script, the webex_user that you populated earlier, being an instance of the Person class, has a person_id attribute. Therefore, you can pass the webex_user.person_id as the person_id parameter. Some additional information may be returned if you set the calling_data flag. To be sure, add this as follows:

  23. Click Start Debugging and examine the Terminal window output.

This will look basically the same as the previous user dump because although you specified calling_data=True, there really isn't any calling data at this time.