We have an AWS Lambda function that makes a call to the OpenAI API to generate page_content
for a Page
based on a transcript
. Once a response is received, the respective Page
element in a DynamoDB table is updated.
import boto3
import json
import openai
def lambda_handler(event, context):
dynamodb = boto3.client('dynamodb')
openai.api_key = "XXXXX"
d = json.loads(event['body'])
pageId = d['page_id']
transcript = d['transcript']
conversation = [
{"role": "system", "content": "Assistant"},
{"role": "user", "content": transcript},
{"role": "system", "content":"Provide a blog post for the content above."}
]
response = openai.ChatCompletion.create(
model="gpt-3.5-turbo",
messages=conversation,
temperature=1,
max_tokens=2000,
top_p=1,
frequency_penalty=0,
presence_penalty=0
)
page_content = response['choices'][0]['message']['content']
state = "COMPLETE"
response = dynamodb.update_item(
TableName='Pagedb-XXXXXX-dev',
Key={'id': {'S': pageId}},
UpdateExpression='SET content = :val1, contentState = :val2',
ExpressionAttributeValues={
':val1': {'S': page_content},
':val2': {'S': state}
},
)
return {
'statusCode': 200,
'headers': {
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Headers': 'Content-Type',
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'OPTIONS,POST,GET'
}
}
This Lambda function is invoked through API Gateway from a React application.
const response = await axios.post(
'https://XXXX.execute-api.us-east-2.amazonaws.com/default/generate-content',
{page_id: page.id, transcript: page.transcript},
);
The Issue: Most of our calls exceed the 30 second maximum timeout for API Gateway and will cause an error, despite the Lambda function going to successful completion. To work around this, we made the call asynchronous by disabling "Use Lambda Proxy Integration" and adding an HTTP Header X-Amz-Invocation-Type
mapped from 'Event'
. This allows our Lambda function to run beyond 30 seconds, however we cannot pass details through 'event'
of the handler function anymore, as lambda proxy allowed for this.
Question: How can we pass details from our React application to the Lambda function through API Gateway if Lambda Proxy integration is disabled?
Update - Implemented Fix With Mark's feedback, I setup a Mapping Template for the Integration Request of my method in API Gateway doing the following:
#set($allParams = $input.params())
{
"method" : "$context.httpMethod", ## API method
"authcontext" : "$context.authorizer.stringkey", ## Optional output from Lambda Authorizers
## passthrough body
"body" : $input.json('$'),
## passthrough headers, querystrings and path parameters
"params" : {
#foreach($type in $allParams.keySet())
#set($params = $allParams.get($type))
"$type" : {
#foreach($paramName in $params.keySet())
"$paramName" : "$util.escapeJavaScript($params.get($paramName))"
#if($foreach.hasNext),#end
#end
}
#if($foreach.hasNext),#end
#end
}
}
pageId = event['body']['page_id']
transcript = event['body']['transcript']
When you disabled the proxy integration, you also disabled the default proxy request mapping. You need to enable integration passthrough request mapping to get that request data showing up in the Lambda function's event
parameter again.