botocore.exceptions.NoCredentialsError:无法定位凭证,即使手动传递凭证

6

你好,我是一个创建flask应用程序的新手,我已经创建了一个小型GUI来将文件上传到S3 Bucket。以下是处理此操作的代码片段。

s3 = boto3.client('s3', region_name="eu-west-1", 
    endpoint_url=S3_LOCATION, aws_access_key_id=S3_KEY, aws_secret_access_key=S3_SECRET)

myclient = boto3.resource('s3')
file = request.files['file[]']
filename=file.filename
data_files = request.files.getlist('file[]')
for data_file in data_files:
    file_contents = data_file.read()
    ts = time.gmtime()
    k=time.strftime("%Y-%m-%dT%H:%M:%S", ts)
    name=filename[0:-4]
    newfilename=(name+k+'.txt')
    myclient.Bucket(S3_BUCKET).put_object(Key=newfilename,Body=file_contents)
    message='File Uploaded Successfully'
    print('upload Successful')

当我从本地系统测试它时,该部分运行良好,但在将其上传到 EC2 实例后出现问题。

myclient.Bucket(S3_BUCKET).put_object(Key=newfilename,Body=file_contents)

这是发生错误的位置:

botocore.exceptions.NoCredentialsError: 无法找到凭证

我创建了一个名为config.py的文件,其中存储着所有凭证,并在运行时传递它们。不确定在EC2实例上导致错误的原因,请帮助我解决。


你尝试过这里提到的解决方案吗?(https://dev59.com/YlwX5IYBdhLWcg3w2iku) - Venkatesh Wadawadagi
1个回答

10

你可能会混淆boto3服务资源和客户端

#!!!! this instantiate an object call s3 to boto3.s3.client with credential  
s3 = boto3.client('s3', region_name="eu-west-1", 
    endpoint_url=S3_LOCATION, aws_access_key_id=S3_KEY, aws_secret_access_key=S3_SECRET)

#!!!! this instantiate an object call myclient to boto3.s3.resource that use
#     credential inside .aws folder, since no designated credential given.
myclient = boto3.resource('s3')

看起来你正在尝试在不使用.aws/credential和.aws/default访问密钥的情况下传递显式凭据到boto3.resource。如果是这样,那么这不是正确的做法。为了明确地将凭据传递给boto3.resource,建议使用boto3.Session(也适用于boto3.client)。这还允许您通过使用初始化会话连接到不同的AWS服务,而不是在程序内部传递不同服务的API密钥。
import boto3
session = boto3.session(
      region_name = 'us-west-2', 
      aws_access_key_id=S3_KEY, 
      aws_secret_access_key=S3_SECRET)

# now instantiate the services
myclient = session.resource('s3')
# .... the rest of the code

然而,更好的方法是利用.aws凭证。因为在代码中硬编码任何访问密钥/密码都是一种不好的做法。如果需要在不同区域访问不同的API密钥,还可以使用配置文件名称。例如:

~/.aws/credential

[default]
aws_access_key_id = XYZABC12345
aws_secret_access_key = SECRET12345

[appsinfinity] 
aws_access_key_id = XYZABC12346
aws_secret_access_key = SECRET12346

~/.aws/config [默认] 区域 = 美国西部1

[profile appsinfinity] 
region = us-west-2

而这段代码 {{code}}

import boto3
app_infinity_session = boto3.session(profile_name= 'appsinfinity')
....

4
boto3.session 必须使用大写字母 'S' 而不是小写字母 's',因为该模块中有一个名为 Session 的类,使用小写字母 'session' 将导致 TypeError: 'module' object is not callable。 - Santeau

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