我想弄清楚如何通过 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])
这里有一个非常相似的问题(并在评论中回答)。
简短的回答是,要避免 CORS 并防止文件损坏,您需要:
非常好的例子 在 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 库),但这将帮助您入门。
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