-3

I ask advice. I need to create a JSON object with the same keys. This is necessary to send a request to zabbix for host.create . https://www.zabbix.com/documentation/3.0/ru/manual/api/reference/host/create If you specify more than one group, it accepts only

{"groupid": "2", "groupid": "8"}

Does not understand:

{"groupid": ["2","8"]}

I suppose to use a structure.

[("groupid","2"),("groupid","8")]

I solved the problem in this way, but I do not understand how to convert to JSON, because the keys are not strings

import json
from json import JSONEncoder


class SameKeys(JSONEncoder):
    def __init__(self, name):
        self.name = name

    def __repr__(self):
        return json.dumps(self.name)


data = [("groupid", "2"), ("groupid", "8")]

a = {SameKeys("groupid"): "2", SameKeys("groupid"): "8"}
print(a)

But I can not understand how to do it better so as not to make crutches, there may already be a ready solution, but having spent time I did not find anything suitable. Thank you for any advice

3 Answers3

1

Is it valid JSON?

Yes, {"groupid": "2", "groupid": "8"} is valid JSON and I do not understand what made you think otherwise. RFC8259 says

the names within an object SHOULD be unique

because if they are not then

the behavior of software that receives such an object is unpredictable

But it is not mandatory.

Do you need it?

I read the docs you linked and I did not find anything suggesting that you need an object with several members named "groupid". In the example there is an object with a member "groups" whose value is an array:

{
    ...
    "params": {
        ...
        "groups": [
            {
                "groupid": "50"
            }
        ],
        ...
    },
    ...
}

As I see it, in order to add the host to several groups you are expected to include all the groups in the array.

{
    ...
    "params": {
        ...
        "groups": [
            {
                "groupid": "2"
            },
            {
                "groupid": "8"
            }
        ],
        ...
    },
    ...
}

Unfortunately I did not have a chance to test it.

How to do it

Whatever, it looks like you want to convert a list of items like

data = [("groupid","2"),("groupid","8")]

into a JSON object with the corresponding members. Well a JSON object is just text, all you have to do is build the string as you iterate over the items.

obj = '{' + ', '.join('"{}": "{}"'.format(k, v) for k, v in data) + '}'
print(obj)

will print

{"groupid": "2", "groupid": "8"}
Community
  • 1
  • 1
Stop harming Monica
  • 12,141
  • 1
  • 36
  • 56
  • Good afternoon. Many thanks for your response. I just thought and did it already. The fact is that Zabbix accepts inquiries and so {"groupid": "2", "groupid": "8"} and so {"groupid": "2"},{ "groupid": "8"}. It's strange, and confused me, because Colleges said what exactly is needed and that's how they do all their life as {"groupid": "2", "groupid": "8"}. – Константин Велопокатуновичь Feb 03 '18 at 06:58
0

You could use a defaultdict as an intermediate structure for your data:

import json
from collections import defaultdict

src=[("groupid", "2"), ("groupid", "8")]

dst = defaultdict(list)

for k,v in src:
    dst[k].append(v)

print(dst)

print(json.dumps(dst))

Outputs:

defaultdict(<class 'list'>, {'groupid': ['2', '8']})
{"groupid": ["2", "8"]}

Now that you can shift json <-> defaultdict, you can also translate defaultdict <-> other, where other may suit your current application.

quamrana
  • 37,849
  • 12
  • 53
  • 71
0

Assuming ID values cannot be the same, why not inverse the dictionary. E.g.

a = {"2": "groupid", "8": "groupid"}

A dictionary cannot have the same key, but all the values can be the same.