Petesta
Petesta

Reputation: 1775

Serverless and uploading image from Lambda endpoint to S3

I'm using the Serverless framework with Python. What I'm trying to accomplish is have an HTTP endpoint setup by Serverless and have that endpoint upload an image to S3. The client, Android, would upload an image from their phone and hit the endpoint with the image. I've been able to successfully upload to S3 but when I click on download for the image and try to open it, it appears to be corrupted.

enter image description here

I'm using the file_uploadobj function and it expects a file like object as its first argument. It should be noted that the type of event['body'] is unicode.

Here is the code that I'm using to accomplish this upload.

import boto3

def upload_image(event, context):
    headers, body = event['headers'] ,event['body']
    client = boto3.client('s3', region_name='us-west-2')
    filename = event['queryStringParameters']['filename']
    tmp_filename = '/tmp/' + filename
    file__ = open(tmp_filename, 'wb')
    file__.write(body)
    # file__.write(body.encode('utf-8'))
    # file__.write(body.encode('base64'))
    file__.close()
    with open(tmp_filename, 'rb') as file_data:
        client.upload_fileobj(file_data, 'bucket', filename, ExtraArgs={'ContentType': 'image/jpeg'})
    return {
        'statusCode': 200,
        'body': {'path': filename}
    }

Does anyone have any ideas as to what I'm doing wrong?

I've also tried the following using upload_file.

import base64

def upload_image(event, context):
    headers, body = event['headers'] ,event['body']
    client = boto3.client('s3', region_name='us-west-2')
    filename = event['queryStringParameters']['filename']
    tmp_filename = '/tmp/' + filename
    with open(tmp_filename, 'wb') as file_descriptor:
        file_descriptor.write(base64.b64decode(data))
    client.upload_file(tmp_filename, 'bucket', filename, ExtraArgs={'ContentType': 'image/jpeg'})
    return {
        'statusCode': 200,
        'body': {'path': filename}
    }

Upvotes: 4

Views: 2517

Answers (1)

Suraj Kulkarni
Suraj Kulkarni

Reputation: 181

I have uploaded the image to s3 Bucket. In "Lambda Test Event", I have created one json test event which contains BASE64 of Image to be uploaded to s3 Bucket and Image Name. Lambda Test JSON Event as fallows ======>

        { 
            "ImageName": "Your Image Name",
            "img64":"BASE64 of Your Image"
        }

Following is the code to upload an image or any file to s3 ======>

import boto3
import base64
def lambda_handler(event, context):
    s3 = boto3.resource(u's3')
    bucket = s3.Bucket(u'YOUR-BUCKET-NAME')
    path_test = '/tmp/output'         # temp path in lambda.
    key = event['ImageName']          # assign filename to 'key' variable
    data = event['img64']             # assign base64 of an image to data variable 
    data1 = data
    img = base64.b64decode(data1)     # decode the encoded image data (base64)
    with open(path_test, 'wb') as data:
        #data.write(data1)
        data.write(img)
        bucket.upload_file(path_test, key)   # Upload image directly inside bucket
        #bucket.upload_file(path_test, 'FOLDERNAME-IN-YOUR-BUCKET /{}'.format(key))    # Upload image inside folder of your s3 bucket.
    print('res---------------->',path_test)
    print('key---------------->',key)

    return {
        'status': 'True',
   'statusCode': 200,
   'body': 'Image Uploaded'
  }

Upvotes: 1

Related Questions