Home > Enterprise >  "string indices must be integers" error when parsing JSON
"string indices must be integers" error when parsing JSON

Time:09-16

I have the following JSON and I would like to extract all the email's within it. The json is exported from AWS cognito and I have no control over how it is structured.

expected_value = """{
  "Users": [
    {
      "Username": "testUserName1",
      "Attributes": [
        {
          "Name": "testName1",
          "Value": "[email protected]"
        }
      ],
      "UserCreateDate": "2021-09-13T11:16:02.627000 01:00",
      "UserLastModifiedDate": "2021-09-13T11:16:02.627000 01:00",
      "Enabled": true,
      "UserStatus": "UNCONFIRMED"
    },
    {
      "Username": "testUsername2",
      "Attributes": [
        {
          "Name": "testEmail2",
          "Value": "[email protected]"
        }
      ],
      "UserCreateDate": "2021-02-19T11:52:52.465000 00:00",
      "UserLastModifiedDate": "2021-02-19T11:52:52.465000 00:00",
      "Enabled": true,
      "UserStatus": "UNCONFIRMED"
    }
  ]
}"""

I have the following code where I am feeding in the json for now as expected value:

def lambda_handler(event, context):
    data = json.dumps(expected_value)
    y = json.loads(data)
    email = y['Users'][0]['Attributes'][0]['Value']

But I get the following error:

{
  "errorMessage": "string indices must be integers",
  "errorType": "TypeError",
  "requestId": "622258cc-8248-4901-8a39-fc6e0a24229c",
  "stackTrace": [
    "  File \"/var/task/lambda_function.py\", line 145, in lambda_handler\n    email = y['Users'][0]['Attributes'][0]['Value']\n"
  ]
}

I can't figure out what I am doing wrong.

As requested, a REPREX which still throws the error:

CodePudding user response:

user_list = []
for item in json:
    users_list.append(item['Users'][0]['Attributes'][0]['Value'])

because 'Attributes' here is a list of dictionaries

CodePudding user response:

would like to extract all the email's within it

The lambda event should already be JSON, IIRC

As the error says, you'll need to index the lists using numbers, or use a for-each loop over the whole list

emails = []
for user in event.get('Users', []):  # assuming event is already a dict
    for a in user.get('Attributes', []):
        # probably also want to get the Name field and check the property is actually an email 
        v = a.get('Value')
        if v:
            emails.append(v)
print(emails)

CodePudding user response:

The following works for me. Note I removed the dumping and reloading of the data you currently have in your question.

import json


def lambda_handler(event, context):
    data = json.loads(event)
    email = data['Users'][0]['Attributes'][0]['Value']
    print(f'{email=}')  # -> email='[email protected]'


event = '''
{
  "Users": [
    {
      "Username": "testUserName1",
      "Attributes": [
        {
          "Name": "testName1",
          "Value": "[email protected]"
        }
      ],
      "UserCreateDate": "2021-09-13T11:16:02.627000 01:00",
      "UserLastModifiedDate": "2021-09-13T11:16:02.627000 01:00",
      "Enabled": true,
      "UserStatus": "UNCONFIRMED"
    },
    {
      "Username": "testUsername2",
      "Attributes": [
        {
          "Name": "testEmail2",
          "Value": "[email protected]"
        }
      ],
      "UserCreateDate": "2021-02-19T11:52:52.465000 00:00",
      "UserLastModifiedDate": "2021-02-19T11:52:52.465000 00:00",
      "Enabled": true,
      "UserStatus": "UNCONFIRMED"
    }
  ]
}
'''

lambda_handler(event, None)

CodePudding user response:

Lookking at the code that has been shown, the value of the expected_value variable is already a JSON-formatted string. When json.dumps() is applied to it, the value is "embedded" in another (redundant) JSON "layer".

So either remove the """ triple quotation marks from you expected_value or remove json.dumps() from you function; in the latter case the expected_value should be passed directly to json.loads():

def lambda_handler(event, context):
    y = json.loads(expected_value)
    email = y['Users'][0]['Attributes'][0]['Value']
  • Related