AWS Lambda Python 3 句柄 POST 文件

AWS Lambda Python 3 handle POST file

提问人:Jérémie RPK 提问时间:3/20/2020 最后编辑:Jérémie RPK 更新时间:11/17/2023 访问量:2794

问:

我正在 AWS Lambda 上使用 Python 3.8,我想处理发布的文件,就像使用 Django 一样。但使用 AWS Lambda 是不可能的。我想把这个文件放在 S3 中:requests.files

s3.put_object(
    Body=fileAsString,
    Bucket=MY_BUCKET,
    Key='my-file.jpg'
)

当我直接返回收到的事件时,文件:

enter image description here

第一次尝试 : 与 : 我是我的处理程序:cgi.parse_multipart

c_type, c_data = parse_header(event['headers']['Content-Type'])
boundary = c_data['boundary'].encode('latin1')
body = event['body'].encode('utf8')

fp = BytesIO(body)
pdict = {
    'boundary': boundary,
    'CONTENT-LENGTH': str(len(body))
}
form_data = parse_multipart(fp, pdict)
fileBytes: bytes = form_data['file'][0]
return ({'statusCode': 200, 'body': json.dumps(str(fileBytes))}

我收到:我也尝试过,但我收到:enter image description hereenter image description here我总是有“?form_data['file'][0].decode('utf-8')

我应该得到这个,因为它是原始图像,在版本中打开:enter image description here

第二次尝试:我按照本教程:https://medium.com/swlh/upload-binary-files-to-s3-using-aws-api-gateway-with-aws-lambda-2b4ba8c70b8e

所以,我试了:

file_content = base64.b64decode(event['body'])

但我得到:

string argument should contain only ASCII characters

(与) 当我尝试将 body 加载为 dict 时:validate=False

body2 = json.loads(event['body'])

我得到:

loads failed : Expecting value: line 1 column 1 (char 0)

我尝试在 API 的设置中将“image/png”和“image/*”添加到“二进制媒体类型”中,但没有更改。

有什么想法吗?

python amazon-web-services 文件 aws-lambda

评论

0赞 Alex Montoya 4/18/2020
你找到解决方案了吗?
0赞 Jérémie RPK 5/19/2020
不,我放弃了......

答:

0赞 msc 6/17/2020 #1

当您使用 时,它将以多部分形式上传图像。这是一次上传多个内容类型文件的标准方法,但您需要在收到时对其进行解析。 如果您的应用程序对 content-type 不敏感,只需使用 enc/dec 来发布和接收,如下所示的伪代码:requests.filesbase64

上传者:

import json
import requests
import base64

with open("/path/to/your/file/image.png", "rb") as image_file:
        encoded_string = base64.b64encode(image_file.read())

    payload = {
                'name': 'image.png',
                'file': encoded_string.decode('utf-8')
                }

    url = 'https://api_url/upload'
    r = requests.post(url, data = json.dumps(payload), headers = {})

Lambda 侧:

import json
import boto3
import base64

def upload(event, context):
    body = json.loads(event['body'])

    s3 = boto3.client("s3", region_name='us-east-1')

    decodedFile = base64.b64decode(body['file'])
    rs = s3.put_object(
                        Bucket='bucket_name',
                        Key=body['name'],
                        Body=decodedFile
                        )

    response = {
        "statusCode": 200,
    }

    return response
3赞 redPanda 10/30/2020 #2

这是一个旧帖子,但我疯狂地试图解决它。

事实证明,我的解决方案是将所有二进制类型添加到 API 网关中,如下所示:AWS API Gateway settings

我的问题是我的代码适用于 .png 文件,但不适用于 .jpg 文件。 添加正确的MIME类型后,“image/jpeg”一切正常,错误

string argument should contain only ASCII characters

走了。 注意:此更改后需要重新部署 API(不是即时的)

底线:此代码是我的工作代码:

import json
import boto3
import base64
  
s3 = boto3.client('s3')

def lambda_handler(event, context):
if event['httpMethod'] == 'POST' : 
    fileName = event['multiValueQueryStringParameters']['fileName']
    bodyData = event['body']
    decodedFile = base64.b64decode(bodyData)
    s3.put_object(Bucket=<BUCKET_NAME>, Key=fileName[0], Body=decodedFile)
    return {'statusCode': 200, 
        'body': json.dumps({'message': 'file saved successfully'}), 
        'headers': {'Access-Control-Allow-Origin': '*'}}

评论

1赞 Sumant Agnihotri 2/11/2021
要在此处添加,在我的情况下,POST 请求 Content-Type 标头设置为 form-data。因此,将 multipart/form-data添加到二进制媒体类型,解决了我的问题。但是,当网关转换为二进制时,所有其他表单数据都将丢失。
0赞 user1773219 2/20/2021 #3
upload_file = request.files['file']
img = re.sub(b"\xef\xbf\xbd", b'', upload_file.stream.read())

当我上传到烧瓶时,AWS Lambda 添加了 UTF-8 BOM,这只是清理 UTF-8 BOM 字节的技巧,它对我来说效果很好。

拆分函数添加 xef-xbb-xbf-n-to-my-list

评论

0赞 hivert 2/21/2021
你能补充一些解释吗?
0赞 Sebgenie 11/17/2023 #4

我的解决方案是:

event['body'] = str(event['body']).encode('utf-8)