如何使用 Aws Lambda(python)接收文件

问题描述 投票:0回答:2

我想弄清楚如何通过 Python 中的 API 调用接收浏览器发送的文件。

Web 客户端可以发送任何类型的文件(比如 .txt、.docx、.xlsx 等)。我不知道我是否应该使用二进制文件。

想法是在 S3 之后保存文件。现在我知道可以使用像 Aws Amplify 这样的 js 库并生成一个临时 url,但我对该解决方案不太感兴趣。

任何帮助表示赞赏,我已经在 Python 中广泛搜索了一个解决方案,但我找不到任何实际工作的东西!

我的 API 是私有的,我正在使用无服务器进行部署。

files_post:
  handler: post/post.post
  events:
    - http:
        path: files
        method: post
        cors: true
        authorizer: 
          name: authorizer
          arn: ${cf:lCognito.CognitoUserPoolMyUserPool}

编辑

我有一个适用于文本文件但不适用于 PDF、XLSX 或图像的半解决方案,如果有人有我会非常高兴

from cgi import parse_header, parse_multipart
from io import BytesIO
import json


def post(event, context):


    print event['queryStringParameters']['filename']
    c_type, c_data = parse_header(event['headers']['content-type'])
    c_data['boundary'] = bytes(c_data['boundary']).encode("utf-8")

    body_file = BytesIO(bytes(event['body']).encode("utf-8"))
    form_data = parse_multipart(body_file, c_data)

    s3 = boto3.resource('s3')
    object = s3.Object('storage', event['queryStringParameters']['filename'])
    object.put(Body=form_data['upload'][0])
python angular amazon-web-services aws-lambda
2个回答
0
投票

这里有一个非常相似的问题(并在评论中回答)。

简短的回答是,要避免 CORS 并防止文件损坏,您需要:

    使用 AWS SDK 在 S3 中创建一个空对象
  1. 将该对象的预签名 URL 返回给前端
  2. PUT 文件到那个预签名的 URL
AWS 实际上维护了一个

非常好的例子 在 Go 中实现这个场景。

在 Python 中,一个简单的实现是这样的:

import boto3 import os import csv s3 = boto3.client('s3') # Upload the empty file to S3 s3.put_object(Bucket='foobucket', Key='somekey', Body='') # Generate a pre-signed URL for the empty file url = s3.generate_presigned_url( ClientMethod='get_object', Params={ 'Bucket': 'foobucket', 'Key': 'somekey' } )
您可能需要使用 

io.BytesIO

 来流式传输您的文件。

写它只需使用

Client.put_object

方法:

s3.put_object(Bucket=bucket_name, Key=object_key, Body=<IN MEMORY FILE STREAM>, ContentType='<YOUR FILE TPYE>')
其中棘手的部分将适合您的逻辑以支持高效上传多种文件类型(每种文件类型可能需要不同的 Python 库),但这将帮助您入门。


-1
投票
您正在使用 API 网关,因此您的 lambda 事件将映射到类似这样的内容(来自

Amazon Docs):

{ "resource": "Resource path", "path": "Path parameter", "httpMethod": "Incoming request's method name" "headers": {String containing incoming request headers} "multiValueHeaders": {List of strings containing incoming request headers} "queryStringParameters": {query string parameters } "multiValueQueryStringParameters": {List of query string parameters} "pathParameters": {path parameters} "stageVariables": {Applicable stage variables} "requestContext": {Request context, including authorizer-returned key-value pairs} "body": "A JSON string of the request payload." "isBase64Encoded": "A boolean flag to indicate if the applicable request payload is Base64-encode" }

您可以在正文中将文件作为 base64 值传递,并在您的 lambda 函数中对其进行解码。采用以下 Python 片段

def lambda_handler(event, context): data = json.loads(event['body']) # Let's say we user a regular <input type='file' name='uploaded_file'/> encoded_file = data['uploaded_file'] decoded_file = base64.decodestring(encoded_file) # now save it to S3
    
© www.soinside.com 2019 - 2024. All rights reserved.