使用 Learner Lab - 使用 API Gateway 与 Lambda 上传图片到 S3
AWS Academy Learner Lab 是提供一个帐号让学生可以自行使用 AWS 的服务,让学生可以在 100 USD的金额下,自行练习所要使用的 AWS 服务,如何进入 Learner Lab 请参考 使用 Learner Lab - 学生,以下示范使用 API Gateway 与 Lambda 上传图片到 S3。
使用 S3 来存储照片可以很容易的建立一个无服务器的应用,只要结合 API Gateway 与 AWS Lambda 就可以让使用者在不需建置任何服务器的情况下,提供一个照片存放的功能,而 AWS Upload Image to S3 via ApiGateway & Lambda 与 Serverless web application for uploading files to S3 这两篇文章都有展示使用 JavasScript 为后端服务器的示例,而本示例是以 Python 为 AWS Lambda 的开发语言。
步骤 1. 创建 Lambda 函数
在 AWS 网页控制台 上方的搜寻图示中输入 Lambda ,单击 Lambda 服务,如下图所示。
图 1. AWS 网页控制台中找寻 Lambda 服务
单击 创建函数 服务,如下图所示。
图 2. 创建 Lambda 函数
设定 Lambda 函数如下
- 从头开始创作
基本信息 - 函数名称: API2Lambda
- 运行时: Python 3.8
- 架构: x86_64
权限 - 执行角色: 使用现有角色 LabRole (很重要、很重要、很重要)
图 3. 设定 Lambda 函数
步骤 2. 布署 Lambda 函数
因为这次代码的功能为读取用户透过 HTTP POST 请求所传递过来的图片,图片内容已经事先转换成 base64 格式,收到 base64 格式的字符串后,转换成图片,并上传到 S3 ,代码如下:
import json
import base64
import boto3
# base64 字符串转换后的图片
image_filename = '/tmp/inputimage.jpg'
# 存放图片的 S3 存储桶
output_bucket = 'lambda2s3image'
# 存放在 S3 存储桶中的档案名称
s3_key_value = 'apigateway2S3.jpg'
s3_client = boto3.client('s3')
def lambda_handler(event, context):
requestMethod = event['httpMethod']
# HTTP 请求方式为 POST 才做后续处理
if requestMethod=='POST':
# 将上传的 JSON 字符串转换成字典
requestBody = json.loads(event['body'])
# 将上传的 base64 字符串转换成字组,再转换成 binary 格式
image_64_decode = base64.decodebytes(requestBody['key'].encode())
# 暂存在 Lambda 的文件系统中
image_result = open(image_filename, 'wb')
image_result.write(image_64_decode)
image_result.close()
# 上传到 S3 存储桶
s3_client.upload_file(image_filename, output_bucket, s3_key_value,ExtraArgs={'ACL': 'public-read','ContentType':'image/jpeg'})
s3_url = 'https://' + output_bucket + '.s3.amazonaws.com/' + s3_key_value
return {
'statusCode': 200,
'body': s3_url
}
else:
# HTTP 请求方式非 POST 回传错误
return {
'statusCode': 200,
'body': 'method error'
}
修改完毕后单击 Deploy (布署),必须要先布署才算是将代码布署到云计算中。
步骤 3. 创建 S3 存储桶
在 AWS 网页控制台 上方的搜寻图示中输入 S3 ,单击 S3 服务,如下图所示。
图 4. AWS 网页控制台中找寻 S3 服务
单击创建存储桶
图 5. 创建一个存储桶
创建存储桶的配置如下:
常规配置
- 存储桶名称: lambda2s3image
- AWS 区域: us-east-1
对象所有权
- ACL 已启用
图 6. 存储桶名称与区域
此存储桶的“阻止公有访问”设置
- 清除勾选 阻止所有公开访问
- 勾选 我了解,当前设置可能会导致此存储桶及其中的对象被公开。
图 7. 存储桶公有访问”设置
其馀选项保留预设值,完成后单击 创建存储桶 按钮。
步骤 4. 添加 API Gateway 触发器
在 Lambda 主画面上方找到添加触发器按钮,如下图所示。
图 8. 在 Lambda 主画面中进行添加触发器
进入添加触发器画面,配置如下:
添加触发器
- 触发器配置: API Gateway
- Intent: Create a new API
- API type: HTTP API
- Security: Open
Additional settings - API name: API2Lambda-API
- Deployment stage: default
- 勾选 Cross-origin resource sharing (CORS)
图 9. 在添加触发器画面中进行 API Gateway 配置
添加触发器后可以在配置中查看触发器的结果,如下图所示。
图 10. 在配置中查看触发器
步骤 5. 使用 Postman 进行测试
接著使用常见的 API 测试软件来进行测试,在本机端打开 Postman,并输入相关的配置。
- URL 网址:将上图中的 API endpoint 输入
- 请求方法: POST
- Body: 选择 raw,格式为 JSON。
内容为部分是将 CSDN 的图示转换成 base64 的格式,Python 的相关代码是,可以在本地端运行。
# convert base64 to image
import base64
image = open('csdn-logo.jpg', 'rb')
image_read = image.read()
image_64_encode = base64.encodebytes(image_read)
print(image_64_encode)
将著将以下内容张贴到 Postman 中即可。
{
"key": "/9j/4AAQSkZJRgABAQEASABIAAD/2wBDAAYEBQYFBAYGBQYHBwYIChAKCgkJChQODwwQFxQYGBcU\nFhYaHSUfGhsjHBYWICwgIyYnKSopGR8tMC0oMCUoKSj/2wBDAQcHBwoIChMKChMoGhYaKCgoKCgo\nKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCj/wAARCABYAKADASIA\nAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQA\nAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3\nODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWm\np6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEA\nAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSEx\nBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElK\nU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3\nuLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD6pooo\noAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKK4j4mfEC08F2aRpGLvV7gf6P\nag/hubHIXP4noO5CbUVdlwhKpLlitTrtTv7bS9PuL6/lWG1t0MkkjdFA/wA9K5bwl8RdD8UXMFrY\nPIt3P5jJA4G4IhxubHC57DOe9fNPjDXfFviBnuNfbUPsxOREY2jgT0wvT8evvXMW/neen2bzPOz8\nvl53Z9sVzPEa6LQ9Wnli5Peep930V8yeCfiX4o8KvFH4it76+0fIUm5RhJGPVXYc/QnHpivpDSNS\ntNY023v9OnWe0nXfHIvQj+h7EdjW0KinsefiMNOg/e27luiiitDnCiobi7trbH2m4hhz08xwufzq\n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\nRQAUUUUAFFFFAH//2Q==\n"
}
接著点击送出 Send 就得到完整的请求信息响应 (Response),即为上传到 S3 的网址,因为设定的 ACL 是可以观看的,所以可以直接打开观看结果。
图 11. 在postman进行 API 测试
下图为在网页上观看 S3 存储桶中的图片。
图 12. 观看上传到 S3 的结果
感谢亚马逊云科技王向炜 Alan Wang 提供的协助。
参考资料
- AWS Upload Image to S3 via ApiGateway & Lambda, https://github.com/imran9m/aws-api-lambda-s3-image-upload
- Serverless web application for uploading files to S3, https://github.com/evanchiu/serverless-galleria/tree/master/uploader
- 使用 Learner Lab - 使用 Lambda 转换图片为 base64 格式, https://blog.csdn.net/m0_50614038/article/details/128075734
- 使用 Learner Lab - 使用 AWS Lambda 将图片写入 S3, https://blog.csdn.net/m0_50614038/article/details/128122934
- 使用 Learner Lab - 使用 API Gateway 触发 AWS Lambda, https://blog.csdn.net/m0_50614038/article/details/128155030