Forum Discussion

roryvanvuuren's avatar
2 years ago

Python SDK - JSON

Hi All,

Apologies if this is a simple question, however I cannot find any documentation that can assist.

My goal here is to have severity 3 alerts in a JSON file, however I am unable to convert this list ‘alerts’ to JSON and I cannot find any documentation in the SDK v3 that could address this.

# create an instance of the API class
api_instance = logicmonitor_sdk.LMApi(logicmonitor_sdk.ApiClient(configuration))
id = 138 # Integer |
size = 1000 # Integer | (optional)
offset = 0 # Integer | (optional)
filter = f'severity:3,cleared:true,startEpoch>:{startEpoch},endEpoch<:{endEpoch}' # String | (optional)

#Loop shiznit
alerts = []
end_found = False

while not end_found:
current = api_instance.get_alert_list_by_device_group_id(id, size=size, offset=offset, filter=filter).items
alerts += current
offset += len(current)
end_found = len(current) != size

#Print and encode result to json. This allows you to use this variable later in an API Put.
with open('./customer/json/cleared_sev3_alerts.json', 'w') as content_output_json:
result_encoded = json.JSONEncoder(sort_keys=False, indent =4).encode(alerts)
content_output_json.write(str(alerts))
content_output_json.close()

print(len(alerts))

Whenever I try to encode this I get the following alert. 

TypeError: Object of type Alert is not JSON serializable

Doing a jsonDump gives us the same output and I’ve scoured stackoverflow for a way to fix this, but no luck.

Does anyone know how I can get around this? 

Thank you so much

  • Anonymous's avatar
    Anonymous
    2 years ago

    It’s because the `alerts` list, contains a custom object of type “logicmonitor_sdk.models.alert.Alert”. It’s not a dictionary or list or other python native type that json.JSONEncoder().encode() expects. You can verify this by doing this:

    print(alerts[0].__class__)

    So, you have to convert each item in the list to a dictionary before you can pass it to the encoder. List comprehension comes in pretty handy here. You can split it out if you want or just do it like this:

    # create an instance of the API class
    api_instance = logicmonitor_sdk.LMApi(logicmonitor_sdk.ApiClient(configuration))
    id = 138 # Integer |
    size = 1000 # Integer | (optional)
    offset = 0 # Integer | (optional)
    filter = f'severity:3,cleared:true,startEpoch>:{startEpoch},endEpoch<:{endEpoch}' # String | (optional)

    #Loop shiznit
    alerts = []
    end_found = False

    while not end_found:
    current = api_instance.get_alert_list_by_device_group_id(id, size=size, offset=offset, filter=filter).items
    alerts += current
    offset += len(current)
    end_found = len(current) != size

    #Print and encode result to json. This allows you to use this variable later in an API Put.
    with open('./customer/json/cleared_sev3_alerts.json', 'w') as content_output_json:
    result_encoded = json.JSONEncoder(sort_keys=False, indent =4).encode([x.to_dict() for x in alerts])
    content_output_json.write(str(alerts))
    content_output_json.close()

    print(len(alerts))

    This takes advantage of the SDK’s .to_dict() method that takes LM SDK custom classes and converts them into simple dictionaries.

  • Anonymous's avatar
    Anonymous

    It’s because the `alerts` list, contains a custom object of type “logicmonitor_sdk.models.alert.Alert”. It’s not a dictionary or list or other python native type that json.JSONEncoder().encode() expects. You can verify this by doing this:

    print(alerts[0].__class__)

    So, you have to convert each item in the list to a dictionary before you can pass it to the encoder. List comprehension comes in pretty handy here. You can split it out if you want or just do it like this:

    # create an instance of the API class
    api_instance = logicmonitor_sdk.LMApi(logicmonitor_sdk.ApiClient(configuration))
    id = 138 # Integer |
    size = 1000 # Integer | (optional)
    offset = 0 # Integer | (optional)
    filter = f'severity:3,cleared:true,startEpoch>:{startEpoch},endEpoch<:{endEpoch}' # String | (optional)

    #Loop shiznit
    alerts = []
    end_found = False

    while not end_found:
    current = api_instance.get_alert_list_by_device_group_id(id, size=size, offset=offset, filter=filter).items
    alerts += current
    offset += len(current)
    end_found = len(current) != size

    #Print and encode result to json. This allows you to use this variable later in an API Put.
    with open('./customer/json/cleared_sev3_alerts.json', 'w') as content_output_json:
    result_encoded = json.JSONEncoder(sort_keys=False, indent =4).encode([x.to_dict() for x in alerts])
    content_output_json.write(str(alerts))
    content_output_json.close()

    print(len(alerts))

    This takes advantage of the SDK’s .to_dict() method that takes LM SDK custom classes and converts them into simple dictionaries.