无法从“botocore.compat”导入名称“awscrt”

问题描述 投票:0回答:1

我有一个 lambda 需要:

  • 准备负载
  • 使用 AWS 版本 4 签署请求
  • 向另一个服务发送请求并返回响应

当我运行 lambda 时,我收到以下消息:

cannot import name 'awscrt' from 'botocore.compat' (/opt/python/lib/python3.10/site-packages/botocore/compat.py

显然,awscrt丢失了,我创建了一个具有此依赖性的layer,但问题仍然存在。

注意:我遵循以下逻辑:sigv4-authenticated-requests-python

amazon-web-services aws-lambda
1个回答
0
投票

如果它在本地工作而不是在 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
)

© www.soinside.com 2019 - 2024. All rights reserved.