2017-06-24 1 views
0

J'essaye d'écrire un back-end sans serveur pour une application avec AWS Lambda, et je cours dans l'erreur dans le titre. L'erreur se produit lors du test avec l'intégration du proxy API Gateway, mais la fonction fonctionne correctement lorsqu'elle est testée dans la console Lambda.Réponse proxy mal formée de Lambda: les index de chaîne doivent être des entiers

Voici l'erreur:

{ 
    "errorMessage":"string indices must be integers", 
    "errorType":"TypeError", 
    "stackTrace":[ 
     [ 
     "/var/task/auth_login.py", 
     17, 
     "lambda_handler", 
     "response = get_user(payload)" 
     ], 
     [ 
     "/var/task/shifty_utils/__init__.py", 
     22, 
     "get_user", 
     "table = dynamo.Table(user['company'] + '_users')" 
     ] 
    ] 
} 

Voici contexte où il se produit:

def lambda_handler(event, context): 
    payload = event['body'] 
    response = get_user(payload) 

def get_user(user): 
    try: 
     table = dynamo.Table(user['company'] + '_users') 
     response = table.get_item(
      Key={ 
       'userId': user['userId'], 
       'position': user['position'] 
      } 
     ) 
    except ClientError as e: 
     print(e.response['Error']['Message']) 
     return {'message': e.response['Error']['Message']} 
    else: 
     return response 

intégration Fondamentalement proxy semble lire dans l'objet de l'événement en tant que chaîne au format JSON, par opposition à un dict, mais voici ce qui se passe si j'ajuste mon code pour cela:

{ 
    "errorMessage":"the JSON object must be str, bytes or bytearray, not 'dict'", 
    "errorType":"TypeError", 
    "stackTrace":[ 
     [ 
     "/var/task/auth_login.py", 
     15, 
     "lambda_handler", 
     "payload = json.loads(event)" 
     ], 
     [ 
     "/var/lang/lib/python3.6/json/__init__.py", 
     348, 
     "loads", 
     "'not {!r}'.format(s.__class__.__name__))" 
     ] 
    ] 
} 

Je ne peux pas gagner. Toute aide est appréciée.

Répondre

3

Vous avez identifié le problème. Cependant, vous essayez de convertir un dict en dict.

C'est ce que vous avez:

json.loads(event) # event is a dict 

La partie du corps que vous avez identifié à juste titre est ce qui devient en tant que str.

C'est ce que vous devriez avoir:

json.loads(event['body']) 

Une étape est de rendre le client agnostique.

if isinstance(event['body'], (unicode, str)): 
    body = json.loads(event['body']) 
1

Lorsque vous traitez avec JSON, python fournit 2 fonctions std:

https://docs.python.org/3/library/json.html#json.dumps

Serialize obj to a JSON formatted str using this conversion table. The arguments have the same meaning as in dump().

https://docs.python.org/3/library/json.html#json.loads

Deserialize s (a str, bytes or bytearray instance containing a JSON document) to a Python object using this conversion table.

Qu'est-ce que vous avez besoin ici est la dernière:

import json 
payload = json.loads(event['body'] 

event['body'] est probablement un JSON str donc pour accéder vous des valeurs d'une manière poing devrez convertir en un obj python via `json.loads