skip to Main Content

I am working on a lambda code for an API in AWS. I am passing a json data within my body which is
shown like this when I print my event within the lambda.

    'body': '{rn  "STTN": "415263",rn  "Account": "22568758"rn}rn',

Here is how I am validating within the lambda

    try:
        eventJson['body']['STTN'] 
    except Exception:       
        returnValidateConditional  = False
        validationResponse['apiStatus'] = "failed" 
        validationResponse['apiErrorCode'] ="1"
        validationResponse['apiDescription'] = "STTN is required" 
        statusCode = 415
        return [returnValidateConditional, validationResponse, statusCode] 
        
    try:
        eventJson['body']['Account'] 
    except Exception:       
        returnValidateConditional  = False
        validationResponse['apiStatus'] = "failed" 
        validationResponse['apiErrorCode'] ="1"
        validationResponse['apiDescription'] = "Account is required" 
        statusCode = 415
        return [returnValidateConditional, validationResponse, statusCode] 
        
        

My validation fails all the time despite the fact that STTN and Account are not empty. They have values
that exist in the body request. All I get is STTN is required

How can I validate json items in the body sent as a request?

2

Answers


  1. I can notice a few immediate issues with the code:

    • Your 'body' value is of type str (string), so it won’t work if you subscript it.
    • When you use try: ... except Exception: ... you are masking the actual error, which is TypeError. I would suggest better error handling, such as printing (or logging) the actual exception/error message. A good start would be except Exception as e:, followed by something like print(e).
    • a try/except block is not a good idea for this use case, where it looks like you just need to check if required keys exist in the request dict object. I would suggest using the in operator instead.

    Repro’d example in REPL:

    >>> event = {'body': '{rn  "STTN": "415263",rn  "Account": "22568758"rn}rn'}
    >>> event['body']
    '{rn  "STTN": "415263",rn  "Account": "22568758"rn}rn'
    >>> type(event['body'])
    <class 'str'>
    >>> event['body']['STTN']
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    TypeError: string indices must be integers, not 'str'
    

    Solution: you can use json.loads on the str value to convert it to a dict object

    from json import loads
    
    event = {'body': '{rn  "STTN": "415263",rn  "Account": "22568758"rn}rn'}
    
    
    def main():
        # body = event['body']
        body = loads(event['body'])
    
        print(type(body))   # <class 'dict'>
        try:
            print(body.get('STTN'))  # 415263
    
            for required_field in ('STTN', 'Account'):
                if required_field not in body:
                    validation_response = {'apiStatus': 'failed', 'apiErrorCode': '1',
                                          'apiDescription': f'{required_field} is required'}
                    status_code = 415
                    return [False, validation_response, status_code]
    
        except Exception as e:
            print(f'caught a {type(e).__name__}: {e}')
            raise
    
    
    if __name__ == '__main__':
        main()
    
    Login or Signup to reply.
  2. eventJson['body'] is a string. You need to parse it first

    try:
        body = json.loads(eventJson['body'].strip().replace(r'rn', '')) 
        if not ('STTN' in body and 'Account' in body):
            raise ValueError('Missing STTN or Account fields')
    except Exception:
        ... 
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search