我有一个 lambda 需要:
当我运行 lambda 时,我收到以下消息:
cannot import name 'awscrt' from 'botocore.compat' (/opt/python/lib/python3.10/site-packages/botocore/compat.py
显然,awscrt丢失了,我创建了一个具有此依赖性的layer,但问题仍然存在。
注意:我遵循以下逻辑:sigv4-authenticated-requests-python
如果它在本地工作而不是在 lambda 环境中工作,则可能是由于特定于平台的平台不兼容而发生的
_awscrt.abi3.so
(botocore.compat
隐藏了真正的异常消息):
[ERROR] Runtime.ImportModuleError: Unable to import module 'lambda_function': /var/task/_awscrt.abi3.so: invalid ELF header
解决方案是使用具有明确平台规范的 Docker 构建 lambda 包:
# assuming there is a valid Dockerfile that builds and packages what you need
docker build --platform linux/x86_64 -t lambda-layer
另一个解决方案是不使用
awscrt
库并使用 SigV4Auth
而不是 CrtSigV4Auth
import boto3
import requests
from botocore.auth import SigV4Auth
from requests import PreparedRequest
from requests.auth import AuthBase
from botocore.awsrequest import AWSRequest
class BotoSigV4Auth(AuthBase):
def __init__(self, service, session=None):
self.service = service
self.session = session or boto3.session.Session()
self.sign_required_headers = ["content-type", "host", "x-amz-date", "x-amz-security-token"]
def __call__(self, r: PreparedRequest):
aws_signer = SigV4Auth(self.session.get_credentials(), self.service, self.session.region_name)
aws_headers = {
k: v for k, v in r.headers.items() if k.lower() in self.sign_required_headers
}
aws_request = AWSRequest(method=r.method, url=r.url, headers=aws_headers, data=r.body)
aws_signer.add_auth(aws_request)
aws_prepared = aws_request.prepare()
r.url = aws_prepared.url
r.headers.update(aws_prepared.headers)
return r
auth = BotoSigV4Auth("healthlake")
response = requests.get(
auth=auth,
# other params
)