1
votes

I have the following code from a blog which gets the bitcoin price for today. I could access this Lambda function from the AWS Lex console and test the bot to get the price for today.

"""
Lexbot Lambda handler.
"""
from urllib.request import Request, urlopen
import json

def get_bitcoin_price(date):
    print('get_bitcoin_price, date = ' + str(date))
    request = Request('https://rest.coinapi.io/v1/ohlcv/BITSTAMP_SPOT_BTC_USD/latest?period_id=1DAY&limit=1&time_start={}'.format(date))
    request.add_header('X-CoinAPI-Key', 'E4107FA4-A508-448A-XXX')
    response = json.loads(urlopen(request).read())
    return response[0]['price_close']

def lambda_handler(event, context):
    print('received request: ' + str(event))
    date_input = event['currentIntent']['slots']['Date']
    btc_price = get_bitcoin_price(date_input)
    response = {
        "dialogAction": {
            "type": "Close",
            "fulfillmentState": "Fulfilled",
            "message": {
              "contentType": "SSML",
              "content": "Bitcoin's price was {price} dollars".format(price=btc_price)
            },
        }
    }
    print('result = ' + str(response))
    return response

But when I test the function from the AWS Lex console, I get the following error:

 Response:
{
  "errorMessage": "'currentIntent'",
  "errorType": "KeyError",
  "stackTrace": [
    [
      "/var/task/lambda_function.py",
      18,
      "lambda_handler",
      "date_input = event['currentIntent']['slots']['Date']"
    ]
  ]
}

Request ID:
"2488187a-2b76-47ba-b884-b8aae7e7a25d"

Function Logs:
START RequestId: 2488187a-2b76-47ba-b884-b8aae7e7a25d Version: $LATEST
received request: {'Date': 'Feb 22'}
'currentIntent': KeyError
Traceback (most recent call last):
  File "/var/task/lambda_function.py", line 18, in lambda_handler
    date_input = event['currentIntent']['slots']['Date']
KeyError: 'currentIntent'

How do I test the function in the AWS Lambda console? 'lambda_handler' function, what format would be the 'event' and 'context' be? Also, what would be the 'context' here?

What should I pass as 'event' and 'context' in my case?

1

1 Answers

3
votes

Your code is failing because the event object is filled in with {'Date': 'Feb 22'} but your code expects much more than this. Therefore, it fails when you try to parse this JSON by trying to access currentIntent:

date_input = event['currentIntent']['slots']['Date']

You cannot pass any context to your Lambda when testing from the console as it is automatically populated by AWS. Also, the context is only used in very specific occasions, so I would not worry about it for now.

You can, however, pass the event as argument and there are many ways to do it. The simplest way to do it manually is to go to AWS's Lambda Console, click on Test and, if you haven't configured any Test Event yet, the following screen will pop up

enter image description here

Now, on the dropdown, you can select your event and AWS will fill it in for you, like this:

enter image description here

You can now customise the event the way you want it.

Once you save it and click on Test, the event object will be populated with the provided JSON.

Another option is to check Sample Events Published By Event Sources, so you can simply grab any JSON event you'd like and tailor it accordingly.

I have grabbed the Lex Sample Event for you, which looks like this:

{
  "messageVersion": "1.0",
  "invocationSource": "FulfillmentCodeHook or DialogCodeHook",
  "userId": "user-id specified in the POST request to Amazon Lex.",
  "sessionAttributes": { 
     "key1": "value1",
     "key2": "value2",
  },
  "bot": {
    "name": "bot-name",
    "alias": "bot-alias",
    "version": "bot-version"
  },
  "outputDialogMode": "Text or Voice, based on ContentType request header in runtime API request",
  "currentIntent": {
    "name": "intent-name",
    "slots": {
      "slot-name": "value",
      "slot-name": "value",
      "slot-name": "value"
    },
    "confirmationStatus": "None, Confirmed, or Denied
      (intent confirmation, if configured)"
  }
}

Use that as your event and you'll be able to test it accordingly.