【问题标题】:Uploading file to AWS S3 through Chalice API call通过 Chalice API 调用将文件上传到 AWS S3
【发布时间】:2017-11-13 15:19:17
【问题描述】:

我正在尝试通过 Chalice 将文件上传到我的 S3 存储桶(我目前正在使用它,对此仍然很陌生)。但是,我似乎无法正确处理。

我已正确设置 AWS,成功完成本教程会返回一些消息。然后我尝试做一些上传/下载,问题出现了。

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'}
    )

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

我收到了错误日志:

没有这样的文件或目录:''

在这种情况下,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)

【问题讨论】:

  • 你想从哪里上传哪个文件到哪个位置?您app.py 已部署到 AWS API 和 Lambda 函数,即“同一文件夹”在部署后可能不是真的。
  • 该文件与 app.py 位于同一文件夹中。我也尝试使用文件的绝对路径,但都不起作用。我想正确的问题应该是“正确的做法是什么?”

标签: python python-3.x boto3 chalice


【解决方案1】:

我让它运行起来了,这对我来说就像app.pyAWS Chalice project 中一样工作:

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 及其--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 旁边的 AWS IAM web interface 中现有策略到您的 Chalice 项目创建的角色。

值得一提的:

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

【讨论】:

  • 按照你的步骤,我仍然得到 500。按照这个人的指示,我已经为 chalice 用户创建了对 S3 的完全访问权限:brianpark.ca/blog/… 我放入了一个 try/except 子句以使用app.log.error(blhblah) 记录任何错误,并且没有记录任何内容。
  • 我选择您的答案作为正确答案,因为我认为我的问题来自其他部分。我相信您的解决方案可以解决我提出的问题。我只需要弄清楚许可部分。如果你对此有一些看法,请与我分享:)
  • 谢谢。这是我的 IAM 设置的screenshot,如果可以的话。我通过“附加策略”添加了 s3 访问权限
  • 啊.....我明白你的意思了。我正在直接编辑 chalice 角色(在您的情况下是 hello-chalice-dev)权限
  • 这样(如图)在chalice deploy之后不会被覆盖。
猜你喜欢
  • 1970-01-01
  • 2016-11-20
  • 2019-07-25
  • 1970-01-01
  • 2018-01-21
  • 1970-01-01
  • 1970-01-01
  • 2022-01-23
  • 1970-01-01
相关资源
最近更新 更多