Python function in AWS Lambda

Asked

Viewed 220 times

1

I am needing to run the following function below on AWS Lambda:

def subset_sum(numbers, target, partial=[]):
    s = sum(partial)

# check if the partial sum is equals to target
if s == target:
    print("sum(%s)=%s" % (partial, target))
if s >= target:
    return  # if we reach the number why bother to continue

for i in range(len(numbers)):
    n = numbers[i]
    remaining = numbers[i + 1:]
    subset_sum(remaining, target, partial + [n])

if __name__ == "__main__":
    subset_sum([1,2,3], 5)

Yet this one comes along and I can’t fix it:

{
  "errorMessage": "'>=' not supported between instances of 'int' and 'LambdaContext'",
  "errorType": "TypeError",
  "stackTrace": [
    [
      "/var/task/lambda_function.py",
      7,
      "subset_sum",
      "if s >= target:"
    ]
  ]
}

The original function has more values that take a long time so I’m trying to run on Lambda. The function returns the combination of numbers that result in the sum of the defined value (in case 5)

On the computer using py subset_sum.py works normally and returns 2 and 3 (which combined is equal to 5).

UPDATING

I made the modification as Tom replies. Now reports another error.

def lambda_handler(event, context):

    s = sum(event['partial'])

    if s == 5:
        print("sum(%s)=%s" % (event['partial'], 5))
        exit()
    if s >= 5:
        return

    for i in range(len(event['numbers'])):
        n = event['numbers'][i]
        remaining = event['numbers'][i + 1:]
        dict = {'numbers' : remaining, 'partial' : event['partial'] + [n]}
        lambda_handler(dict)

if __name__ == "__main__":
    dict = {'numbers' : [1,2,3], 'partial' : []}
    lambda_handler(dict)

Output from the Lambda

{
  "errorMessage": "'partial'",
  "errorType": "KeyError",
  "stackTrace": [
    [
      "/var/task/lambda_function.py",
      5,
      "lambda_handler",
      "s = sum(event['partial'])"
    ]
  ]
}

Print(Event) output at the very beginning of Handler

START RequestId: f3a45f36-b1fc-11e7-8f6d-d5a3a428a4fd Version: $LATEST
{'key3': 'value3', 'key2': 'value2', 'key1': 'value1'}
'partial': KeyError
Traceback (most recent call last):
  File "/var/task/lambda_function.py", line 7, in lambda_handler
    s = sum(event['partial'])
KeyError: 'partial'
END RequestId: f3a45f36-b1fc-11e7-8f6d-d5a3a428a4fd
  • Tip: There are tools that simulate a lambda environment on your machine (eg serveless framework), use them to test your code locally and after testing deploy the code on lambda, this helps a lot to find errors before they go to Amazon (I’ve suffered enough with this).

1 answer

0


If you set the function subset_sum Like Handler of your Lambda Function, the parameters that are passed are different from your test subset_sum([1,2,3], 5).

Handler invoke takes the parameters:

  • Event - Event responsible for running the Lambda Function (API Gateway, Cloudwatch, etc);
  • context - Information of Runtime.

The error happens by comparing what you are doing between an int and a Lambdacontext object.

The parameters should be accessed through the event, ex:

def my_handler(event, context):
    partial = event['partial']
    target = event['target']

    print(partial)
    print(target)

Documentation: http://docs.aws.amazon.com/lambda/latest/dg/python-programming-model-handler-types.html

EDIT


To set the test event values through the console:

Lambda -> (Select your Lambda Function) -> Select a test Event -> Configure test Events

aws lambda

  • Fantastic Tom! Thank you so much! I got it right. Now you are still making a mistake to run: "errorMessage": "'partial'", "errorType": "Keyerror". I am investigating.

  • Place an Event print to see the data structure that is coming into your Handler and see the log in Cloudwatch. Where are you calling the Lambda function? API Gateway ? CLI ? Cron in Cloudwatch ?

  • I did an update on the @tom-Melo question. I’m actually testing the function first by clicking "Test" directly on the AWS Lambda.

  • put a print(Event) right at the beginning of Handler, will appear the log in Cloudwatch,

  • Show, Tom. I put an update in the reply. Thank you for the support, it is very important to resolve this issue.

  • By the log there is no Key "partial", there is only Dict: {'key3': 'value3', 'Key2': 'value2', 'key1': 'value1'}, in your test you must pass the JSON you expect in your code: { "partial": [], "Numbers": [1, 2, 3] }

  • I understand... The funny thing is that I call him, look: if name == "main": Dict = {'Numbers' [1,2,3], 'partial' []} lambda_handler(Dict)

  • No, I say "test by console", when the core of AWS Lambda invokes its Lambda Function it does not pass by the if name == 'main', it calls only its Handler function by injecting the filling and the context. It in the aws console of an "Edit and test" and puts the correct input(json).

  • Perfect, Tom. Now I get it... And where do I set the starting values of Event? Apologies for the simple questions. I tried to set inside Environment. I need it to be {'Numbers' [1,2,3], 'partial' : []}.

  • I edited the answer, see if you can find it on the aws console.

  • Tom... It worked out!!! It’s people like you who make a difference!!! I’m going to detail the answer here and in Stackoverflow US. There had not been an answer like yours. Now I understand the time/memory/cpu to run the function with the amount of terms I need. Success!

Show 6 more comments

Browser other questions tagged

You are not signed in. Login or sign up in order to post.