使用 Boto3 S3 资源时 S3 Ninja 端点抛出无法连接错误
S3 Ninja endpoint throws could not connect error when using Boto3 S3 resource
我正在尝试将 S3 Ninja 与 Python 中的 boto3
一起使用,但是尽管有 docker 容器 运行,我还是无法配置 S3客户端使用 S3 Ninja。
尝试使用 boto3.session.Session().client().get_object()
获取对象时,我的尝试导致了以下错误。
s3 = S3()
content = s3.get('mybucket', 'myobject')
botocore.exceptions.EndpointConnectionError: Could not connect to the endpoint URL: "http://localhost:9444/mybucket/myobject.json"
按预期使用 curl http://localhost:9444/mybucket/myfile.json
returns 文件,看起来 S3 Ninja 正在运行。但是S3客户端不知为何找不到。
我已经为端点尝试了以下两个值 URL。
- http://localhost:9444
- http://localhost:9444/s3
class S3:
client: boto3.client
def __init__(self) -> None:
local = os.environ.get('LOCAL')
if local == 'true':
self.client = boto3.session.Session().client(
service_name='s3',
aws_access_key_id='my_access_key',
aws_secret_access_key='my_secret_key',
endpoint_url='http://localhost:9444',
config=botocore.client.Config(
s3={
'addressing_style': 'path'
}
)
)
else:
self.client = boto3.client('s3')
def get(self, bucket_name: str, key: str) -> str:
response = self.client.get_object(
Bucket=bucket_name,
Key=key)
return response['Body'].read().decode('utf-8')
有什么问题?
这是一个令人沮丧的问题,一段时间后我发现这是由于我使用了 Lambda 函数引起的。
我问题中的代码是 Lambda 函数的一部分。函数和 API 是 运行 在本地使用 sam local start-api
,任何调用实际上是 运行 在 docker 容器中。所以这个问题是 Lambda 容器无法与本地主机上的 S3 Ninja 通信,因为它不在本地主机上 运行ning。
此处的简单修复是针对默认 docker 网络(网桥)172.17.0.1
的 IP,而不是本地主机。
class S3:
client: boto3.client
def __init__(self) -> None:
local = Environment.local == 'true'
if local:
logger.info('Using S3 Ninja to emulate the S3 API.')
self.client = boto3.client(
service_name='s3',
aws_access_key_id='AKIAIOSFODNN7EXAMPLE',
aws_secret_access_key='wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY',
endpoint_url='http://172.17.0.1:9444/s3/'
)
else:
self.client = boto3.client('s3')
也可以在单独的 docker 网络上 运行 S3 Ninja,然后在同一网络上启动本地 API。我不确定为什么需要这样做,但认为值得一提。
docker network create lambda-local
docker network inspect lambda-local # Record the gateway IP address.
docker run --name s3ninja --network lambda-local -d -p 9444:9000 scireum/s3-ninja:latest
sam local start-api --docker-network lambda-local
# Make sure to use the gateway IP address discovered using 'docker network inspect'.
endpoint_url='http://172.20.0.1:9444/s3/'
我正在尝试将 S3 Ninja 与 Python 中的 boto3
一起使用,但是尽管有 docker 容器 运行,我还是无法配置 S3客户端使用 S3 Ninja。
尝试使用 boto3.session.Session().client().get_object()
获取对象时,我的尝试导致了以下错误。
s3 = S3()
content = s3.get('mybucket', 'myobject')
botocore.exceptions.EndpointConnectionError: Could not connect to the endpoint URL: "http://localhost:9444/mybucket/myobject.json"
按预期使用 curl http://localhost:9444/mybucket/myfile.json
returns 文件,看起来 S3 Ninja 正在运行。但是S3客户端不知为何找不到。
我已经为端点尝试了以下两个值 URL。
- http://localhost:9444
- http://localhost:9444/s3
class S3:
client: boto3.client
def __init__(self) -> None:
local = os.environ.get('LOCAL')
if local == 'true':
self.client = boto3.session.Session().client(
service_name='s3',
aws_access_key_id='my_access_key',
aws_secret_access_key='my_secret_key',
endpoint_url='http://localhost:9444',
config=botocore.client.Config(
s3={
'addressing_style': 'path'
}
)
)
else:
self.client = boto3.client('s3')
def get(self, bucket_name: str, key: str) -> str:
response = self.client.get_object(
Bucket=bucket_name,
Key=key)
return response['Body'].read().decode('utf-8')
有什么问题?
这是一个令人沮丧的问题,一段时间后我发现这是由于我使用了 Lambda 函数引起的。
我问题中的代码是 Lambda 函数的一部分。函数和 API 是 运行 在本地使用 sam local start-api
,任何调用实际上是 运行 在 docker 容器中。所以这个问题是 Lambda 容器无法与本地主机上的 S3 Ninja 通信,因为它不在本地主机上 运行ning。
此处的简单修复是针对默认 docker 网络(网桥)172.17.0.1
的 IP,而不是本地主机。
class S3:
client: boto3.client
def __init__(self) -> None:
local = Environment.local == 'true'
if local:
logger.info('Using S3 Ninja to emulate the S3 API.')
self.client = boto3.client(
service_name='s3',
aws_access_key_id='AKIAIOSFODNN7EXAMPLE',
aws_secret_access_key='wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY',
endpoint_url='http://172.17.0.1:9444/s3/'
)
else:
self.client = boto3.client('s3')
也可以在单独的 docker 网络上 运行 S3 Ninja,然后在同一网络上启动本地 API。我不确定为什么需要这样做,但认为值得一提。
docker network create lambda-local
docker network inspect lambda-local # Record the gateway IP address.
docker run --name s3ninja --network lambda-local -d -p 9444:9000 scireum/s3-ninja:latest
sam local start-api --docker-network lambda-local
# Make sure to use the gateway IP address discovered using 'docker network inspect'.
endpoint_url='http://172.20.0.1:9444/s3/'