通过 Chalice API 调用将文件上传到 AWS S3

Uploading file to AWS S3 through Chalice API call

我正在尝试通过 Chalice 将文件上传到我的 S3 存储桶(我目前正在尝试使用它,对此还是很陌生)。但是,我好像不太对劲。

我正确设置了 AWS,成功完成了本教程 returns 给我一些消息。然后我尝试做一些 upload/download,但问题出现了。

s3 = boto3.resource('s3', region_name=<some region name, in this case oregon>)
BUCKET= 'mybucket'
UPLOAD_FOLDER = os.path.abspath('')  # the file I wanna upload is in the same folder as my app.py, so I simply get the current folder name

@app.route('/upload/{file_name}', methods=['PUT'])
def upload_to_s3(file_name):
    s3.meta.client.upload_file(UPLOAD_FOLDER+file_name, BUCKET, file_name)
    return Response(message='upload successful',
                    status_code=200,
                    headers={'Content-Type': 'text/plain'}
    )

请不要担心我是如何设置文件路径的,当然,除非那是问题所在。

我收到错误日志:

No such file or directory: ''

在这种情况下 file_name 只是 mypic.jpg

我想知道为什么 UPLOAD_FOLDER 部分没有被提取。另外,作为参考,使用绝对路径似乎会对 Chalice 造成麻烦(在测试时,我看到代码被移动到 /var/task/

有人知道如何正确设置吗?

编辑:

完整脚本

from chalice import Chalice, Response

import boto3

app = Chalice(app_name='helloworld')  # I'm just modifying the script I used for the tutorial 
s3 = boto3.client('s3', region_name='us-west-2')
BUCKET = 'chalicetest1'

@app.route('/')
def index():
    return {'status_code': 200,
            'message': 'welcome to test API'}

@app.route('/upload/{file_name}, methods=['PUT'], content_types=['application/octet-stream'])
def upload_to_s3(file_name):
    try:
        body = app.current_request.raw_body
        temp_file = '/tmp/' + file_name
        with open(temp_file, 'wb') as f:
            f.write(body)
        s3.upload_file(temp_file, BUCKET, file_name)
        return Response(message='upload successful',
                        headers=['Content-Type': 'text/plain'],
                        status_code=200)
    except Exception, e:
        app.log.error('error occurred during upload %s' % e)
        return Response(message='upload failed',
                        headers=['Content-Type': 'text/plain'],
                        status_code=400)

我明白了 运行 这对我来说是 AWS Chalice project 中的 app.py:

from chalice import Chalice, Response
import boto3

app = Chalice(app_name='helloworld')

BUCKET = 'mybucket'  # bucket name
s3_client = boto3.client('s3')


@app.route('/upload/{file_name}', methods=['PUT'],
           content_types=['application/octet-stream'])
def upload_to_s3(file_name):

    # get raw body of PUT request
    body = app.current_request.raw_body

    # write body to tmp file
    tmp_file_name = '/tmp/' + file_name
    with open(tmp_file_name, 'wb') as tmp_file:
        tmp_file.write(body)

    # upload tmp file to s3 bucket
    s3_client.upload_file(tmp_file_name, BUCKET, file_name)

    return Response(body='upload successful: {}'.format(file_name),
                    status_code=200,
                    headers={'Content-Type': 'text/plain'})

您可以直接从命令行用 curl and its --upload-file 测试它:

curl -X PUT https://YOUR_API_URL_HERE/upload/mypic.jpg --upload-file mypic.jpg --header "Content-Type:application/octet-stream"

要获得此 运行,您必须 手动将写入 s3 的策略 附加到您的 lambda 函数的角色。此角色由 Chalice 自动生成。 Attach the policy (e.g. AmazonS3FullAccess) manually next to the existing policy in the AWS IAM web interface 到您的 Chalice 项目创建的角色。

需要提及的事情:

  • 您无法写入 Lambda 函数的工作目录 /var/task/,但您在 /tmp/ 处有一些 space,请参阅
  • 您必须为 @app.route 指定可接受的内容类型 'application/octet-stream'(并相应地通过 curl 上传文件)。
  • HTTP PUT 将文件或资源放在特定的 URI 中,因此要使用 PUT,必须通过 HTTP 将此文件上传到 API。