HOWTO: How to get JSON from Python SDK

Hi all - hope you're doing well.
A quick tip for those of you working with the Python SDK (and likely the other SDKs) and running into a WTF moment with having objects returned to you that are not natively JSON Serializable (which, imo, is not great considering the API returns everything in JSON in the first place, but that's for another day).

I ran across several different articles (old ones) about it being on the backlog, etc. but then saw this one:
Python SDK get_users method not returning the output in a valid json format - #2 by John_Carnell (thanks for this direction) and wanted to make a short clear example to get those of you who may be having the same frustration up and running quickly.

While the SDK still does not return serializable (by json.dumps()) object, they have a utils. sanitize_for_serialization(obj) function: https://github.com/MyPureCloud/platform-client-sdk-python/blob/master/build/PureCloudPlatformClientV2/utils.py

Anyway, if I still have your attention at this point, here's some short — complete — demo code to get you moving along quickly.

btw. I'm using "keyring" to store my client_secret instead of in a plaintext file on my HD - you should check it out. not perfect, but a lot better.

You'll want to write some code that does an "import keyring" (after installing it with your fav python pkg manager) and then calls "keyring.set_password(service_id, name, unsecret)" where service_id is your app name that you use in the code below, name is whatever you use for the name in the .set config file, and unsecret is the client_secret. If you don't want to do all this, hardcode your client id and secret in the code below - but it's really pretty easy and much better imo.

import json
import PureCloudPlatformClientV2
from PureCloudPlatformClientV2.rest import ApiException
import keyring
import os.path

#defaults
page_number = 1 # int | Page number (optional) (default to 1)
page_size = 500 # int | Page size (optional) (default to 25)
sort_order = 'asc' # str | Note: results are sorted by name. (optional) (default to 'asc')
# Could use an enum here but it seems like overkill esp with the enum.name / enum.value stuff
c_QUEUE = 'QUEUE'
c_CLIENT = 'client'
c_SYSTEMS = 'systems'
c_NAME = 'name'
c_SOURCE = 'dev'
c_ID = 'id'
c_CRET = 'secret' # code pun?
c_SETTINGS_FILE = '.set'

#QUEUES
# Taken from some of my code that's generating a CSV of objects, in this case queues.
# left it in here because sample code /shrug
def getQueues(client):
    try:
        # create an instance of the API class
        routingApiSource = PureCloudPlatformClientV2.RoutingApi(client[c_CLIENT])
        retDict = {}
        
        api_response = routingApiSource.get_routing_queues(page_number=page_number, page_size=page_size, sort_order=sort_order)
        
        queues = api_response.entities
        
        for queue in queues:
            # serialize to JSON and then write to files.
            temp = PureCloudPlatformClientV2.utils.sanitize_for_serialization(queue)
            jsonString = json.dumps(temp, indent=4) #make it pretty for the file.
            
            # write to file (yes, i could be more careful with sanitizing the queue name, but again, sample code)
            with open(queue.name + '.json', 'w') as q_file:
                q_file.write(jsonString)
                
            # add it to my return dict so you have some console output
            retDict[queue.name] = queue.id
            
    except ApiException as e:
        print("Exception when calling RoutingApi->get_routing_queues: %s\n" % e)
        
    return retDict

# app namespace - this is what will be listed in your keyring
service_id = 'json sample'

with open(c_SETTINGS_FILE) as f:
    d = json.load(f)
    systems=d[c_SYSTEMS]
    
    # ensure these exist, just hacking away for now - hey, it's a free example
    for sys in systems:
        if sys[c_NAME] == c_SOURCE:
            source_sys = sys


print(f'source:{source_sys[c_NAME]}') # this is an f string, you should learn these if you don't know them.


# get client_secret - if you hardcode in the auth below you can comment this out.
source_sys[c_CRET] = keyring.get_password(service_id, source_sys[c_NAME]) # yes, should make sure it exists, again, sample code.

# set region
region = PureCloudPlatformClientV2.PureCloudRegionHosts.us_west_2 # LOOK <--- MAKE SURE YOU SET YOUR REGION HERE
PureCloudPlatformClientV2.configuration.host = region.get_api_host()

# auth up - add try/except
source_sys[c_CLIENT] = PureCloudPlatformClientV2.api_client.ApiClient().get_client_credentials_token(source_sys[c_ID], source_sys[c_CRET])

# do the queue stuff
source_queues = getQueues(source_sys)

# print out dict
for row in source_queues:
    print(row)

Anyway - happy coding, and let me know if you have any trouble. Sample ".set" file below:

{
    "systems": [
        {
            "name": "dev",
            "id": "your_client_id"
        },
        {
            "name": "prod",
            "id": "your_client_id"
        }
    ]
}

1 Like

Oh - also - this is using client credentials OAuth set up in Admin on GC. Make sure it has rights to view queues.

This topic was automatically closed 31 days after the last reply. New replies are no longer allowed.