Reputation: 77
I am running a api with aws-sam that points to a flask based lambda function which is my app.
Here is the template.json for sam:
"Flask": {
"Type": "AWS::Serverless::Function",
"Properties": {
"CodeUri": "api/",
"Handler": "app.app",
"Tracing": "Active",
"Events": {
"Whoami": {
"Type": "Api",
"Properties": {
"Path": "/{proxy+}",
"Method": "any",
"RestApiId": {
"Ref": "SibilusApi"
}
}
}
}
}
},
"EmailSender": {
"Type": "AWS::Serverless::Function",
"Properties": {
"FunctionName": "EmailSender",
"CodeUri": "api/",
"Handler":
"src/email_sender_lambda_function.lambda_handler",
"Tracing": "Active"
}
},
I then have another lambda function, that I wish to invoke from my flask application.
I start my api with sam local start-api --docker-network sam-network
.
in my app.py I have:
import json
from flask_lambda import FlaskLambda
from flask_cors import CORS
import boto3
app = FlaskLambda(__name__)
CORS(app)
@app.route("/hello", methods=["GET"])
def hello():
print("I am running")
lambda_client = boto3.client("lambda", endpoint_url="http://localhost:3001", use_ssl=False)
response = lambda_client.invoke(FunctionName="EmailSender", Payload = json.dumps({"event": "hello world"}))
print(response)
return {"hello": "world"}, 200
I started my other lambda function locally with
sam local start-lambda --docker-network sam-network
Now I have the api on http://127.0.0.1:3000 , and I have my local lambda functions running on http://127.0.0.1:3001.
If I try to invoke the local lambda function from command line with a curl on port 3001, it works fine.
When I curl my api:
curl http://localhost:3000/hello
the flask application executes the /hello
as expected
But my flask application cannot invoke my EmailSender function runnning locally in SAM:
error message
Traceback (most recent call last):
File "/var/task/flask/app.py", line 2073, in wsgi_app
response = self.full_dispatch_request()
File "/var/task/flask/app.py", line 1519, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/var/task/flask_cors/extension.py", line 165, in wrapped_function
return cors_after_request(app.make_response(f(*args, **kwargs)))
File "/var/task/flask/app.py", line 1517, in full_dispatch_request
rv = self.dispatch_request()
File "/var/task/flask/app.py", line 1503, in dispatch_request
return self.ensure_sync(self.view_functions[rule.endpoint])(**req.view_args)
File "/var/task/app.py", line 14, in hello
response = lambda_client.invoke(FunctionName="EmailSender", Payload = json.dumps({"event": "hello world"}))
File "/var/task/botocore/client.py", line 530, in _api_call
return self._make_api_call(operation_name, kwargs)
File "/var/task/botocore/client.py", line 943, in _make_api_call
http, parsed_response = self._make_request(
File "/var/task/botocore/client.py", line 966, in _make_request
return self._endpoint.make_request(operation_model, request_dict)
File "/var/task/botocore/endpoint.py", line 119, in make_request
return self._send_request(request_dict, operation_model)
File "/var/task/botocore/endpoint.py", line 202, in _send_request
while self._needs_retry(
File "/var/task/botocore/endpoint.py", line 354, in _needs_retry
responses = self._event_emitter.emit(
File "/var/task/botocore/hooks.py", line 412, in emit
return self._emitter.emit(aliased_event_name, **kwargs)
File "/var/task/botocore/hooks.py", line 256, in emit
return self._emit(event_name, kwargs)
File "/var/task/botocore/hooks.py", line 239, in _emit
response = handler(**kwargs)
File "/var/task/botocore/retryhandler.py", line 207, in __call__
if self._checker(**checker_kwargs):
File "/var/task/botocore/retryhandler.py", line 284, in __call__
should_retry = self._should_retry(
File "/var/task/botocore/retryhandler.py", line 320, in _should_retry
return self._checker(attempt_number, response, caught_exception)
File "/var/task/botocore/retryhandler.py", line 363, in __call__
checker_response = checker(
File "/var/task/botocore/retryhandler.py", line 247, in __call__
return self._check_caught_exception(
File "/var/task/botocore/retryhandler.py", line 416, in _check_caught_exception
raise caught_exception
File "/var/task/botocore/endpoint.py", line 281, in _do_get_response
http_response = self._send(request)
File "/var/task/botocore/endpoint.py", line 377, in _send
return self.http_session.send(request)
File "/var/task/botocore/httpsession.py", line 484, in send
raise EndpointConnectionError(endpoint_url=request.url, error=e)
botocore.exceptions.EndpointConnectionError: Could not connect to the endpoint URL: "http://localhost:3001/2015-03-31/functions/EmailSender/invocations"END RequestId: fc4d80cf-ec20-414a-a2bd-c9067ba964b1
Am I doing something wrong?
I realize that the problem might be the "localhost" part in the flask application, but I haven't been able to figure out what to put instead. If I use --docker-network, and tries the docker's internal ip, it wouldn't work.
Could anyone point me in the right direction?
Upvotes: 1
Views: 589
Reputation: 1
I faced the same problem today, and I've resolved it.
You should use host.docker.internal
when you specify the endpoint URL.
Your code:
lambda_client = boto3.client("lambda", endpoint_url="http://localhost:3001", use_ssl=False)
Correct one is:
lambda_client = boto3.client("lambda", endpoint_url="http://host.docker.internal:3001", use_ssl=False)
Note: I'm using Docker Desktop on Windows.
Hope this helps you!
Upvotes: 0