Python Forum
Object of type set is not JSON serializable - Printable Version

+- Python Forum (https://python-forum.io)
+-- Forum: Python Coding (https://python-forum.io/forum-7.html)
+--- Forum: General Coding Help (https://python-forum.io/forum-8.html)
+--- Thread: Object of type set is not JSON serializable (/thread-23276.html)



Object of type set is not JSON serializable - enigma619 - Dec-19-2019

Hi

I've a new problem with json / python.

My json is:
Output:
{ "domaine": { "name": { "service": ["service1", "service2"], "threshold": ["100", "200"] }, ...
On my python script, I'm trying to make a request post to my icinga configuration for monitoring.

#!/usr/bin/env python3
..
with open('/tmp/config.json') as json_file1:
            data1 = json.load(json_file1)
            for domaine, value in data1.items():
                    for name, value2 in value.items():
                            service = data1[domaine][name]['service']
                            threshold = data1[domaine][name]['threshold']

                            try:
                                url = "https://localhost:5665/v1/objects/hosts/"
                                request_url = url+hostname
                                headers = {
                                    'Accept': 'application/json',
                                    'X-HTTP-Method-Override': 'PUT'
                                }
                                data = {
                                    "templates": service,
                                    "attrs": {
                                                "address":"BLABLA",
                                                "zone":"BLIBLI",
                                                "vars": { threshold }
                                    }
                                }
                                r = requests.post(request_url,
                                    headers=headers,
                                    verify=False,
                                    auth=('admin', 'XXXXXXXXXXXXXXXXXX'),
                                data=json.dumps(data))
Result is:
Output:
"vars": { threshold } TypeError: unhashable type: 'list'
If I change
Output:
threshold = data1[domaine][name]['threshold'] to: threshold = tuple(data1[domaine][name]['threshold'])
My result is:
Output:
TypeError: Object of type set is not JSON serializable
I'm trying to change key, format, ... but i'm blocked with this point...

Thanks for help


RE: Object of type set is not JSON serializable - buran - Dec-19-2019

{ threshold } is a set with one element. if you pass list to set - it doesn't work because list is mutable, thus not hashable and cannot be element in a set. If you change it to tuple, the set works, but it's not seriazable, as the second error says (i.e. there is no respective type in json).
why you would like a set? what is required as per specifications? I think you misread your specs.

As a side note - fix your indentation and also, don't use spaces after/before braces/brackets i.e. {threshold}


RE: Object of type set is not JSON serializable - enigma619 - Dec-19-2019

I'm not sure about me for this point ...

In fact if I do my request with curl it works:
Output:
curl -vv -k -X PUT -u "admin:${PASSWORD_API_ADMIN}" -H 'Accept: application/json' -H 'Content-Type: application/json' -L "https://localhost:5665/v1/objects/hosts/hostname", -d "{\"templates\": [\"service1\",\"service2\"], \"attrs\": { \"address\": \"BLABLA\", \"zone\": \"BLIBLI\", \"vars\": {\"threshold1\":100, \"threshlod2\":200} } }"| python3.7 -m json.tool
So perhaps my json format is not good?
I'm a little lost with this json format

Output:
{ "domaine": { "name": { "service": ["service1", "service2"], "threshold": ["threshold1: 100", "threshold2: 200"] }, ...

Seems good.

I've changed my json config with:
Output:
"threshold": {"threshold1": "100", "threshold2": "200"}
and my python code sith:
Output:
"vars": threshold
and it works now


RE: Object of type set is not JSON serializable - buran - Dec-19-2019

in curls you have a dict, not set
so
#!/usr/bin/env python3
..
with open('/tmp/config.json') as json_file1:
    data1 = json.load(json_file1)
    for domaine, value in data1.items():
        for name, value2 in value.items():
            service = data1[domaine][name]['service']
            threshold1, threshold2 = data1[domaine][name]['threshold'] # unpack the list
            try:
                url = "https://localhost:5665/v1/objects/hosts/"
                request_url = url+hostname
                headers = {
                    'Accept': 'application/json',
                    'X-HTTP-Method-Override': 'PUT'
                }
                data = {
                    "templates": service,
                    "attrs": {
                                "address":"BLABLA",
                                "zone":"BLIBLI",
                                "vars": {'threshold1':threshold1, 'threshold2':threshold2}
                    }
                }
                r = requests.post(request_url,
                    headers=headers,
                    verify=False,
                    auth=('admin', 'XXXXXXXXXXXXXXXXXX'),
                        data=json.dumps(data))
note that in curl threshold1 and threshold2 are integers, you will read them as str, so you may need to explicitly convert them


RE: Object of type set is not JSON serializable - buran - Dec-19-2019

yeah, that's also possibility, if you can change the input json


RE: Object of type set is not JSON serializable - enigma619 - Dec-19-2019

Tanks for help! Have a good day!