使用boto3在Localstack部署时出现“无法连接到端点URL”错误

12

我正在使用Localstack在本地测试我的更改。我的Lambda函数应该执行putObject并在S3存储桶中创建对象。当直接在AWS环境中进行测试时,功能正常工作。但在Localstack中,它无法工作。我收到以下错误:

无法连接到端点URL:"http://localhost:4572/doyouknowme/pokemon.jpeg"  raise EndpointConnectionError(endpoint_url=request.url, error=e)ponset_exceptionlhost:4572/doyouknowme/pokemon.jpeg"

AWS凭证:

[default]
aws_access_key_id = AKI****************
aws_secret_access_key = gL************************
region = us-east-1

Lambda函数代码:

import json
import urllib.parse
import boto3
import base64

print('Loading function')
# session = boto3.Session(profile_name='personal')
# s3 = session.client('s3', endpoint_url='http://localhost:4574')

s3 = boto3.client('s3', endpoint_url='http://localhost:4572', region_name='us-east-1')


def lambda_handler(event, context):
    # raise Exception('Something went wrong')
    print("Received event: " + json.dumps(event, indent=2))


    try:
        image_data = base64.b64decode(event['image_data'])
        response = s3.put_object(
            Body=image_data,
            Bucket='doyouknowme',
            Key='pokemon.jpeg',
            ContentType='image/jpeg'
        )

        print(response)
        return response

    except Exception as e:
        print(e)
        # print(
        #     'Error getting object {} from bucket {}. Make sure they exist and your bucket is in the same region as '
        #     'this function.'.format(
        #         key, bucket))
        raise e

我不确定为什么S3密钥被附加到Lambda访问的端点URL上。感谢您的帮助解决这个问题。

3个回答

31

对于那些遇到这个问题的人:我在另一个Docker中使用了boto3来访问localstack,并试图使用http://localhost:4566进行访问。

我通过将http://host.docker.internal:4566作为我的boto3会话客户端的endpoint-url来解决了这个问题。

或者,如果您正在使用docker-compose,则可以将两个docker容器放在同一网络中,通过调用boto3容器名称作为终端点来实现调用。(例如:http://boto3-container:4566)

希望这能帮助到有需要的人!


2
它确实帮助了某个人!我花了几个小时来尝试解决这个问题,直到我找到这里。我一直在使用 http://%s:4566" % os.environ["LOCALSTACK_HOSTNAME"]http://localhost:4566,但它们都没有起作用。无法将其与此处的命令列表协调一致:https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-cli-command-reference-sam-local-invoke.html - TheSoldier

2

对我来说,只有os.environ变量起作用,硬编码其他任何东西,如localhost都不起作用。

client = boto3.client('lambda',endpoint_url='http://' + os.environ["LOCALSTACK_HOSTNAME"] + ':4566')

实际上,以下代码检测变量是否存在,以自动调整端点 URL,如果它在 localstack 或 AWS 云中运行,则进行相应的调整:
if os.environ.get("LOCALSTACK_HOSTNAME"):
    client = boto3.client('lambda',endpoint_url='http://' + os.environ["LOCALSTACK_HOSTNAME"] + ':4566')
else:
    client = boto3.client('lambda')

0

如果从一个 Docker 容器联系到 localstack 容器,需要验证以下几点:

  1. 相关的localstack端口已暴露给其他容器。(使用docker/docker-composeexpose部分)

  2. 如果使用docker-compose服务,则需要将其添加到links部分:-localstack

  3. 最重要的是通过http://localstack:4566/进行连接。
    相反,如果您正在尝试在主机上使用运行在后台的localstack容器测试本地代码,则只需使用http://localhost:4566

  4. 验证主机和Docker之间是否存在localstack端口映射,即:

    ports:
    - 4566:4566

  5. 请注意http://localstack:4566!=http://localhost:4566。;)


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