如果在运行Python脚本或应用程序时看到此错误,则偶然发现了Boto3无法找到对特定AWS服务签署API呼叫所需的有效AWS凭据时出现的最常见错误之一。 P>
有很多堆叠的问题:
此错误特定于Python;如果您正在寻找无法找到凭据的解决方案,那么我们已经写了一个blog post。
在调用API之前,您需要创建特定于要使用的服务的客户端。
实例化服务客户端的最传统方法是使用Boto3 SDK提供的以下抽象之一:
- boto3。客户端('s3');
- boto3。资源('s3')。
不管抽象的类型如何,除非已经实例化了,否则将创建新的默认boto3.session.session。如果您想知道boto3.session.session对象是什么,我建议指其文档:
会话存储配置状态,并允许您创建服务客户端和资源。
一个简单的例子
要重现错误,让我使用一个示例脚本来调用Amazon S3 API,该Amazon S3 API返回请求的已验证发件人拥有的所有存储桶的列表。
import boto3
s3_client = boto3.client("s3")
list_buckets_response = s3_client.list_buckets()["Buckets"]
bucket_names = ", ".join(list(map(lambda bucket: bucket["Name"], list_buckets_response)))
print(bucket_names)
正如我先前所说,执行boto3.client("s3")
指令并创建新的默认会话对象;此会话对象也包含AWS凭据信息。您可以轻松推断出,如果Boto3无法找到凭据,则会抛出 botocore.exceptions.nocredentialserror 错误。在这种情况下,执行上一个脚本将产生类似于以下内容的输出:
boto3在哪里寻找凭据?
boto3通过可能位置列表搜索AWS凭据,直到找到有效的位置为止。
中所述-
boto3对客户初始化期间作为参数传递的凭据更高优先级。
-
如果未提供凭据这种方式,它将在环境变量和共享配置文件中寻找它们(即〜/.aws/recertentials和〜/.aws/config Files)。
li> -
如果它仍然无法获得有效的凭据,它试图通过配置IAM角色的Amazon EC2实例上的实例元数据服务获得它们。
再次, botocore.exceptions.nocredentialserror 如果boto3无法在任何列出的位置找到有效的AWS凭据。
让我们找到解决方案!
为了解决该问题,我将生成一组与特定IAM用户相关的临时凭据。为IAM用户生成临时凭证涉及调用STS旋转式API。我让Leapp自动为我生成它们。
设置后,BOTO3应该能够从〜/.aws/凭据文件中获得有效的AWS凭据。让我们尝试再次运行Python脚本。
正如预期的那样,boto3在〜/.aws/recertentials 文件中找到了一组有效的临时凭据。它使用这些凭据签署Amazon S3 API请求,并获取请求的身份验证发送者拥有的存储库列表。
boto3会话:锦上添花
长期运行的脚本呢?如果脚本试图访问Amazon S3列表存储桶API,但是BOTO3加载的第一组凭据已过期?好吧,它将无法转发请求。
问题在于,仅使用boto3.client或boto3.Resource模块级函数,第一组凭据包裹在默认 boto3.session.session.sessess.sessess对象中,不会刷新。
要保持凭证始终与凭证提供商链位置之一中的凭据保持一致,您可以直接实例化boto3.session.session.session对象,并从中获取新的Amazon S3客户端。
import boto3
while True:
input("type a key to list the available Amazon S3 buckets")
s3_client = boto3.session.Session().client("s3")
try:
buckets = s3_client.list_buckets()["Buckets"]
bucket_names = ", ".join(list(map(lambda bucket: bucket["Name"], buckets)))
print(bucket_names)
except Exception as e:
print(e)
为了模拟一个长期运行的脚本,我介绍了一个WILE循环,该循环首先要求用户键入一个键以运行n-th-th-Teperation。这样,我们可以通过在触发n-th Tiperation之前启动/停止LEAPP会话来控制凭据可用。
在这一点上,让我们通过离开Leapp会话停止来运行脚本;它返回以下输出。
您可以看到,它无法找到凭据,因为在触发第一次迭代时,任何凭据提供商链中都无法使用凭据。
现在,让我们开始Leapp会话。
此时,〜/.aws/凭据文件中关联的一组新的临时凭据。
通过触发第二次迭代,我们从脚本中获得了以下输出:
在第二次迭代期间,boto3能够从位于〜/.aws/凭据文件中的一组有效的AWS凭据来实例化新的会话对象。因此,它可以签名并转发到Amazon S3存储端端点,以获取身份验证的发送者拥有的存储桶列表。
我可以微调以前的脚本以维护会话对象的单个实例并重新确定它,只有在签署请求的凭据过期的情况下才能重新确定。
所以,我的建议是使用boto3.session.session对象作为实例化,是一种刷新凭证的优雅方式。
那就是,伙计们!
我希望您能找到理解和求解botocore.exceptions.nocredentialserror所需的所有信息!
作为外卖,请考虑重构现有代码以采用boto3.session.session对象,除非您已经使用了它。它可能是改变游戏规则的人,尤其是在长期运行的脚本中。
本文是该博客的IAM how to fix系列的一部分。
请访问subscribing to our newsletter的IAM专业知识!
在评论中分享您对此博客文章的想法和反馈,或通过我的Twitter profile与我联系。
如果您喜欢Leapp的体验,请给我们星星!