2

I have a dataset in JSON that looks like this:

>>> finalJSON
'"company": {"name": "Micro inc.", "founders": {"name": "Jim D", "name": "Susan A"}, 
 "company": {"name": "Vitacore", "founders": {"name": "Billy B", "name": "Sally Q", "name": "Mark G"}'
.....

I need to loop through and send each of these items:

'"company": {"name": "Micro inc.", "founders": {"name": "Jim D", "name": "Susan A"},

to a POST Request like this:

d = []
for company in FinalJSON:
    p = requests.post((url + '/ratio'), json=company, headers=headers)
    if(p.status_code == 200):
            print p.text
            d.append(p.text)
    else:
            print(p.status_code)
            print "Error"

Edit/Update

Hopefully this is a more complete example of what I'm exactly trying to do. I have a Pandas DataFrame that contains company names and employees like this:

>>> print name_frame
... 
               name    name    name    name        name
Micro inc.      NaN    Jim D  Susan A      NaN       NaN
Vitacore    Billy B      NaN  Sally Q   Mark G       NaN

What I need to do is convert this to a JSON format like this:

finalJSON = { 
    "company":{
        "name": "Micro inc.",
        "founders": {
            "name": "Jim D",
            "name": "Susan A",
            }
    }
    "company":{
        "name": "Vitacore",
        "founders": {
            "name": "Billy B",
            "name": "Sall Q", 
            "name":"Mark G",
        }

In a previous question I asked I was advised to try this out to get the desired JSON formate:

finalJSON = []
for company, names in df.iterrows():
    names = ['"{0}"'.format(name) for name in names.dropna().tolist()]
    names_json_str = ('"name": ' if names else '') + ', "name": '.join(names)
    finalJSON.append('"company": {"name": "' + company + '", "founders": {' + names_json_str + '}')
finalJSON = ', '.join(finalJSON)

>>> finalJSON
'"company": {"name": "Micro inc.", "founders": {"name": "Jim D", "name": "Susan A"}, 
 "company": {"name": "Vitacore", "founders": {"name": "Billy B", "name": "Sally Q", "name": "Mark G"}'

So now I'm working with integrating the conversion with the post request:

for company, names in name_frame.iterrows():
    names = ['"{0}"'.format(name) for name in names.dropna().tolist()]
    names_json_str = ('"name": ' if names else '') + ', "name": '.join(names)
    payload = '"company": {"name": "' + company + '", "founders": {' + names_json_str + '}'
    p = requests.post((url), json=payload, headers=headers)
    if(p.status_code == 200):
            print p.text
            d.append(p.text)
    else:
            print(p.status_code)
            print "Error"

Though the payload is in fact not considered to be JSON serializable

TypeError: set([' + names_json_str + ']) is not JSON serializable
cgclip
  • 292
  • 1
  • 3
  • 14
  • 3
    `finalJSON` is not, in fact, a valid JSON value. Further, as a string, `company` is just assigned to one character from that string at a time. – chepner Jul 13 '17 at 21:26
  • @chepner is this because of the duplicate keys? That's valid JSON format, though odd. Do you have any ideas on how to select the items I specified? – cgclip Jul 13 '17 at 21:41
  • 2
    You need to change how you construct `finalJSON`. You probably want a list of strings, with each string containing the JSON data for 1 company. Note that currently each company entry is missing a closing brace. – PM 2Ring Jul 13 '17 at 21:45
  • @PM2Ring is this properly formatted: {"company": {"name": " A company", "founders": {"name": "Joe"}}} – cgclip Jul 13 '17 at 22:18
  • Yes, that looks fine. But looking at the other stuff in your question, it's not a good idea to have repeated keys inside a JSON object like `{"name": "Jim D", "name": "Susan A"}`. JSON permits it, but when the JSON object is converted to a Python dict it's a pain to handle it correctly. – PM 2Ring Jul 13 '17 at 22:21
  • If the site you're posting the JSON to expects the data to be in that format with the repeated keys, then I guess you have no option. BUt if you _do_ have a choice it'd make life a lot easier if you put those names into a list, eg `{"company": {"name": "A company", "founders": ["Jim D", "Susan A"]}}` – PM 2Ring Jul 13 '17 at 22:32
  • @PM2Ring Yeah I've double checked and there isn't much of an option. I'm going to try and run it with just one company and one name just because I'm short on time and something is better than nothing. And I am going to need to output the results of the request into a dict and then into a csv file. – cgclip Jul 13 '17 at 22:38

2 Answers2

0

How you format your json string depends entirely on the requirements of the server.

If the server accepts the company json string as:

{"company": {"name": "Micro inc.", "founders": ["Jim D", "Susan A"]}}

You can do something like:

finalJSON = []
rows = [('Micro inc.', ('Jim D', 'Susan A')),
        ('Vitacore', ('Billy B', 'Sally Q', 'Mark G'))]

for company_name, founders in rows: 
    # replace rows with real data, e.g. df.iterrows() 
    founders = ', '.join('"{}"'.format(founder) for founder in founders)
    json_str = '{{"company": {{"name": "{}", "founders": [{}]}}}}'.format(company_name, founders)
    finalJSON.append(json_str)

for company in finalJSON:
    print(company)
    # do stuff with company
azalea
  • 11,402
  • 3
  • 35
  • 46
  • I just updated my question to give the full context of what I'm trying to do. I think there's just something a bit off with how I'm transforming the pandas DataFrame object into an entry for the request. – cgclip Jul 13 '17 at 22:14
  • I tried the code you recommended and unfortunately company in the loop isn't accepted by the API when used in a post request – cgclip Jul 14 '17 at 00:21
  • @cgclip that's expected. As a user of the API, you are supposed to know the format requirement. I only provide an example. – azalea Jul 14 '17 at 01:06
0

So basically this:

 payload = '"company": {"name": "' + company + '", "founders": {' + names_json_str + '}'

was formatted wrong for the API, fixing it resolved the issue

cgclip
  • 292
  • 1
  • 3
  • 14