如何使用AWS Lambda将文件写入S3(Python)?

51
我尝试使用Lambda函数将文件写入S3,测试显示“成功”,但是在我的S3存储桶中没有出现任何东西。 发生了什么? 有人可以给我一些建议或解决方案吗? 非常感谢。 这是我的代码。

我尝试使用lambda函数将文件写入S3,测试结果显示为“成功”,但是在我的S3存储桶中没有出现任何内容。发生了什么?是否有人能够给我一些建议或解决方案?非常感谢。以下是我的代码。

import json
import boto3

def lambda_handler(event, context):

string = "dfghj"

file_name = "hello.txt"
lambda_path = "/tmp/" + file_name
s3_path = "/100001/20180223/" + file_name

with open(lambda_path, 'w+') as file:
    file.write(string)
    file.close()

s3 = boto3.resource('s3')
s3.meta.client.upload_file(lambda_path, 's3bucket', s3_path)
3个回答

77

我已经成功地将数据流式传输到S3,为了做到这一点,它必须进行编码:

import boto3

def lambda_handler(event, context):
    string = "dfghj"
    encoded_string = string.encode("utf-8")

    bucket_name = "s3bucket"
    file_name = "hello.txt"
    s3_path = "100001/20180223/" + file_name

    s3 = boto3.resource("s3")
    s3.Bucket(bucket_name).put_object(Key=s3_path, Body=encoded_string)
如果数据在文件中,您可以读取此文件并发送它:
with open(filename) as f:
    string = f.read()

encoded_string = string.encode("utf-8")

1
非常感谢。我的代码也是有效的,我忘记重新加载S3存储桶了。 我也尝试了你的方法,它也有效。非常感谢。 - Rick.Wang
12
我发现S3路径不应该有前导的/,否则会创建一个空文件夹,实际上变成了//100001,所以我认为这行代码应该写成:s3_path = "100001/20180223/" + file_name - Robert Swift
3
请注意,这不是流式传输,而是将数据缓存到磁盘中,然后再发送。 - Matt Klein
这个解决方案非常完美。我需要写一个 csv 文件,所以实际上我写了一个 io.StringIO,并将缓冲区内容编码为 utf-8 并保存到 S3 文件中。 - acaruci
2
为什么需要一个 Lambda 路径变量? - user3821178
显示剩余2条评论

14
我的回答与Tim B非常相似,但最重要的部分是:
1. 前往S3存储桶并创建您想要写入的存储桶。
2. 按照以下步骤进行操作,否则您的Lambda将由于权限/访问问题而失败。我已经将链接内容复制粘贴在这里,以防他们更改URL或将其移动到其他页面。
a. 在IAM控制台中打开角色页面
b. 选择创建角色。
c. 创建具有以下属性的角色。
- 受信任实体 - AWS Lambda。
- 权限 - AWSLambdaExecute。
- 角色名称 - lambda-s3-role。
AWSLambdaExecute策略具有函数所需的权限,以管理Amazon S3中的对象并将日志写入CloudWatch Logs。
  1. Copy and past this into your Lambda python function

    import json, boto3,os, sys, uuid
    from urllib.parse import unquote_plus
    
    s3_client = boto3.client('s3')
    
    def lambda_handler(event, context):
        some_text = "test"
        #put the bucket name you create in step 1
        bucket_name = "my_buck_name"
        file_name = "my_test_file.csv"
        lambda_path = "/tmp/" + file_name
        s3_path = "output/" + file_name
        os.system('echo testing... >'+lambda_path)
        s3 = boto3.resource("s3")
        s3.meta.client.upload_file(lambda_path, bucket_name, file_name)
    
        return {
            'statusCode': 200,
            'body': json.dumps('file is created in:'+s3_path)
        }
    

0
from os import path
import json, boto3, sys, uuid
import requests
s3_client = boto3.client('s3')

def lambda_handler(event, context):
    bucket_name = "mybucket"
    url = "https://i.imgur.com/ExdKOOz.png"
    reqponse = requests.get(url)
    filenname = get_filename(url)
    img = reqponse.content
    s3 = boto3.resource("s3")
    s3.Bucket(bucket_name).put_object(Key=filenname, Body=img)
    
    return {'statusCode': 200,'body': json.dumps('file is created in:')}

def get_filename(url):
    fragment_removed = url.split("#")[0]
    query_string_removed = fragment_removed.split("?")[0]
    scheme_removed = query_string_removed.split("://")[-1].split(":")[-1]
    if scheme_removed.find("/") == -1:
       return ""
    return path.basename(scheme_removed)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接