I'm currently have the following setup: 1. S3 Bucket 2. API Gateway with GET/POST resource 3. Two Lambda Functions (one for getting data from s3, one for storing data to s3)
For example the GET Resource, i pass a key parameter, which is used in the lambda function to get the object from s3 bucket. then i want to return the retrieved object to api gateway and to client as a binary.
In the POST resource, i want to send a binary payload, eg.: pdf or zip file, save it to s3 and return generated key.
So on one hand i want my api gateway and lambda to be able return binary data in GET request, on the other hand i want it to accept binary payload in POST request.
In api gateway settings, i've set Binary-Media-Types to application/octet-stream
. Also i have lambda proxy integration activated.
My question is: How can I process binary data in api gateway/lambda?
I tried messing around with Headers and Content-Types but more or less i didn't know what I was doing :(
Example store-luggage lambda for storing data from POST request in S3
import boto3
import json
import uuid
import logging
from botocore.exceptions import ClientError
def lambda_handler(event, context):
#data = <binary data from POST request>?
logger = logging.getLogger()
logger.setLevel(logging.INFO)
bucket = 'bucket1'
uniqueid = str(uuid.uuid4())
logger.info("Generated UUID: " + uniqueid)
s3 = boto3.resource('s3')
logger.info("Trying to save file '" + uniqueid + "' to bucket '" + bucket + "'")
savedObj = None
try:
savedObj = s3.Bucket(bucket).put_object(Key=uniqueid, Body=<here should be my binary payload from POST request>)
except ClientError as e:
logger.error("Saving of object has failed: " + str(e.response['Error']['Message']))
if savedObj is None:
return {
'statusCode': 500,
'body': json.dumps({
'message': 'Saving of object has failed!'
})
}
return {
'statusCode': 200,
'body': json.dumps({
'token': uniqueid
})
}
get-luggage lambda for retrieving object from s3 by given key and return binary payload in response
import boto3
import json
from pprint import pprint
from botocore.exceptions import ClientError
import logging
def lambda_handler(event, context):
logger = logging.getLogger()
logger.setLevel(logging.INFO)
bucket = 'bucket1'
token = event["queryStringParameters"]["token"]
s3 = boto3.client('s3')
objectFromS3 = None
try:
objectFromS3 = s3.get_object(Bucket=bucket, Key=token)
except ClientError as ex:
if ex.response['Error']['Code'] == 'NoSuchKey':
logger.info('No object found - returning empty')
else:
raise ex
if objectFromS3 is None:
return {
'statusCode': 404,
'body': json.dumps({
'message': 'Cannot retrieve object from storage!'
})
}
pprint(objectFromS3)
#ContentType application/octet-stream
return {
'statusCode': 200,
'body' : <binary data from retrieved s3 object here?>,
'headers': {
'content-type': 'application/octet-stream'
},
'isBase64Encoded': True
}
I expected to retrieve binary payload in GET response and expected api gateway to pass binary payload from POST request to lambda, but none of this was achieved with the stuff i tried.
I hope i descriped my problem well enough, if any clearification is needed let me know.
best wishes, an aws noob