I have a basic lambda function which accepts a JSON, and transforms to XML and uploads the same to s3 bucket. I am running the test through the lambda console and the xml is getting generated and uploaded to s3 as well. Issue happens when I run the test through API Gateway, and there I get the error:
"message": "Internal server error" and Status: 502. The error also points out where is the code issue:
{"errorMessage": "'header'", "errorType": "KeyError", "stackTrace": [" File \"/var/task/sample.py\", line 21, in printMessage\n b1.text = event['header']['echoToken']\n"]}
The same code is working when running through lambda console. Below is the code snippet with the line that throws the error:
def printMessage(event, context):
print(event)
#event = json.loads(event['header'])
root = ET.Element("Reservation")
m1 = ET.Element("header")
root.append(m1)
b1 = ET.SubElement(m1, "echoToken")
b1.text = event['header']['echoToken'] #this line throws error
I got a similar question here:
AWS Lambda-API gateway "message": "Internal server error" (502 Bad Gateway). Below is the print of event object.
{'header': {'echoToken': '907f44fc-6b51-4237-8018-8a840fd87f04', 'timestamp': '2018-03-07 20:59:575Z'}, 'reservation': {'hotel': {'uuid': '3_c5f3c903-c43d-4967-88d1-79ae81d00fcb', 'code': 'TASK1', 'offset': '+06:00'}, 'reservationId': 12345, 'confirmationNumbers': [{'confirmationNumber': '12345', 'source': 'ENCORA', 'guest': 'Arturo Vargas'}, {'confirmationNumber': '67890', 'source': 'NEARSOFT', 'guest': 'Carlos Hernández'}], 'lastUpdateTimestamp': '2018-03-07 20:59:541Z', 'lastUpdateOperatorId': 'task.user'}}
As per the solution in the link, if I try to do : header = json.loads(event['header'])
I get the below error:
"errorMessage": "the JSON object must be str, bytes or bytearray, not dict",
This is a task that I need to complete, and I have tried few things, but is always failing when tested through API Gateway and POSTMAN. So, my question is: I don't want to change my complete code for XML transformation, and is there any way that I load the complete event object in python, so that it works both through lambda console and API gateway?
Thanks in Advance!!
The problem is similar to the one discussed here
Below code will fix the line causing the issue.
eventDict = json.loads(event)
b1Text = json.dumps(eventDict['header']['echoToken'])
print(b1Text)
Related
I am calling deployed sagemaker Endpoint from lambda for load testing and lambda is getting called from api gateway integration when I am making call using gate POST rest api(with API Proxy Integration Enabled) from client side. But always rest api with lambda returning 200 even when invoke_endpoint doesn't return anything due to traffic load on SageMaker Endpoint.
#logger.inject_lambda_context(correlation_id_path=correlation_paths.API_GATEWAY_REST)
#tracer.capture_lambda_handler
def lambda_handler(event: dict, context: LambdaContext) -> dict:
# return app.resolve(event, context)
try:
print("Received event: " + json.dumps(event, indent=2))
print(type(event), '--> ', event)
payload = event['data']
print(payload)
response = runtime_client.invoke_endpoint(EndpointName=ENDPOINT_NAME,
ContentType='application/json',
Body=json.dumps(payload),
Accept='Accept')
print(response)
print(response.keys())
# if "errorMessage" in str(respone.text):
# return
if "errorMessage" in response.keys() and "502 Bad Gateway" in str(response):
return {'statusCode': 502,'body': response}
elif "errorMessage" in response.keys():
return {'statusCode': 504,'body': response}
result = json.loads(response['Body'].read().decode())
return result
except Exception as e:
print(e)
exception_handler(e)
I enabled API Integration proxy while creating api method in api gateway and using aws-lambda-powertools to resolve the error but still client is getting 200 response always event my SageMaker Endpoint is not responding in the code due to load.
Error example with 200 code is below:
{"errorMessage":"2023-01-16T15:23:25.132Z c1bf04bf-12f7-46ab-b9a3-ffb1865eed26 Task timed out after 3.01 seconds"}
status_code: 200
Can anyone help me out here. Thanks in advance.
PS: I am very new to lambda.
Increase your lambda timeout limit.
I'm following a tutorial on setting up AWS API Gateway with a Lambda Function to create a restful API. I have the following code:
import json
def lambda_handler(event, context):
# 1. Parse query string parameters
transactionId = event['queryStringParameters']['transactionid']
transactionType = event['queryStringParameters']['type']
transactionAmounts = event['queryStringParameters']['amount']
# 2. Construct the body of the response object
transactionResponse = {}
# returning values originally passed in then add separate field at the bottom
transactionResponse['transactionid'] = transactionId
transactionResponse['type'] = transactionType
transactionResponse['amount'] = transactionAmounts
transactionResponse['message'] = 'hello from lambda land'
# 3. Construct http response object
responseObject = {}
responseObject['StatusCode'] = 200
responseObject['headers'] = {}
responseObject['headers']['Content-Type'] = 'application/json'
responseObject['body'] = json.dumps(transactionResponse)
# 4. Return the response object
return responseObject
When I link the API Gateway to this function and try to call it using query parameters I get the error:
{
"message":"Internal server error"
}
When I test the lambda function it returns the error:
{
"errorMessage": "'transactionid'",
"errorType": "KeyError",
"stackTrace": [
" File \"/var/task/lambda_function.py\", line 5, in lambda_handler\n transactionId = event['queryStringParameters']['transactionid']\n"
]
Does anybody have any idea of what's going on here/how to get it to work?
I recommend adding a couple of diagnostics, as follows:
import json
def lambda_handler(event, context):
print('event:', json.dumps(event))
print('queryStringParameters:', json.dumps(event['queryStringParameters']))
transactionId = event['queryStringParameters']['transactionid']
transactionType = event['queryStringParameters']['type']
transactionAmounts = event['queryStringParameters']['amount']
// remainder of code ...
That way you can see what is in event and event['queryStringParameters'] to be sure that it matches what you expected to see. These will be logged in CloudWatch Logs (and you can see them in the AWS Lambda console if you are testing events using the console).
In your case, it turns out that your test event included transactionId when your code expected to see transactionid (different spelling). Hence the KeyError exception.
just remove ['queryStringParameters']. the print event line shows the event i only a array not a key value pair. I happen to be following the same tutorial. I'm still on the api gateway part so i'll update once mine is completed.
Whan you test from the lambda function there is no queryStringParameters in the event but it is there when called from the api gateway, you can also test from the api gateway where queryStringParameters is required to get the values passed.
The problem is not your code. It is the Lambda function intergration setting. Please do not enable Lambda function intergration setting . You can still attach the Lambda function without it. Leave this unchecked.
It's because of the typo in responseObject['StatusCode'] = 200.
'StatusCode' should be 'statusCode'.
I got the same issue, and it was that.
I have written the below code and have deployed in AWS Lambda using deployment package :
from flask import Flask,jsonify,request
app = Flask(__name__)
books = [
{'id': 0,
'title': 'A Fire Upon the Deep',
'author': 'Vernor Vinge',
'first_sentence': 'The coldsleep itself was dreamless.',
'year_published': '1992'},
{'id': 1,
'title': 'The Ones Who Walk Away From Omelas',
'author': 'Ursula K. Le Guin',
'first_sentence': 'With a clamor of bells that set the swallows soaring, the Festival of Summer came to the city Omelas, bright-towered by the sea.',
'published': '1973'},
{'id': 2,
'title': 'Dhalgren',
'author': 'Samuel R. Delany',
'first_sentence': 'to wound the autumnal city.',
'published': '1975'}
]
#app.route("/listbooks",methods=['GET'])
def hello():
return jsonify(books)
#app.route("/getbookbyid",methods=['GET'])
def getBybookid(event,context):
if 'id' in request.args:
id=int(request.args['id'])
results=[]
for book in books:
if book['id']==id:
results.append(book)
return jsonify(results)
I have configured API Gateway to hit the lambda function for a GET request.
When i am trying to hit the endpoint using postman I am getting :
Working outside of request context error
Any pointers
The error message "Working outside of request context" is a Flask error, not an API Gateway or Lambda error. It happens when your Flask app tries to access request, or anything that uses it, outside of a request context.
As #BSQL suggests, this seems to be because of the incorrect indentation of your code.
Please add the below line. It will solve your error.
app.app_context().push()
-Prasanna.K
I am unable to get AWS Config aggregated discovered resources using Python3 and boto3.
Python=3.7
Boto3=1.9.42
Using AWS SAM to locally test Lambda function but I have the same problem when I run the Lambda within AWS.
client = master_session.client('config', region_name=my_region)
response = client.list_aggregate_discovered_resources(
ConfigurationAggregatorName=aggregator,
ResourceType="AWS::EC2::Instance")
Returns error:
{
"errorType": "AttributeError",
"errorMessage": "'ConfigService' object has no attribute 'list_aggregate_discovered_resources'",
"stackTrace": [
" File \"/var/task/app.py\", line 41, in lambda_handler\n r = client.list_aggregate_discovered_resources(\n",
" File \"/var/runtime/botocore/client.py\", line 563, in __getattr__\n self.__class__.__name__, item)\n"
]
}
I am however able to run other requests using this client.
This works:
response = client.describe_configuration_aggregators()
print("Response: {}".format(response))
You can see that the attribute list_aggregated_discovered_resources is not supported in the boto3 1.9.42 from below reference.
ConfigService - Boto3 1.9.42
If you want to use the attribute, then recent version of boto3 is required.
I am trying to analyze a video via Emotion API by Microsoft using Python 3.2
I am encountering the following error:
b'{ "error": { "code": "Unauthorized", "message": "Access denied due to invalid subscription key. Make sure you are subscribed to an API you are trying to call and provide the right key." } }'
I am using Emotion API subscription key (i have also used the Face API key, and computer vision key just in case).
Code:
import http.client, urllib.request, urllib.parse, urllib.error, base64
headers = {
# Request headers
'Ocp-Apim-Subscription-Key': '{subscription key}',
}
params = urllib.parse.urlencode({
})
try:
conn = http.client.HTTPSConnection('westus.api.cognitive.microsoft.com')
conn.request("GET", "/emotion/v1.0/operations/{oid}?%s" % params, "{body}", headers)
response = conn.getresponse()
data = response.read()
print(data)
conn.close()
except Exception as e:
print("[Errno {0}] {1}".format(e.errno, e.strerror))
Your code works. Just make sure you wait 10 minutes after generating the API key so that it starts working (it says so in the Azure Portal).
Also, in general for Cognitive Services, make sure that the API key you have corresponds to the region you're trying to hit (West US, etc.)