-
Couldn't load subscription status.
- Fork 1k
Description
There's an inconsistency around how lambda functions are deployed when defined in app.py vs how they're deployed as part of a blueprint. When a lambda function is declared in a blueprint, the the AWS handler in sam.json is defined to be the path to the lambda function directly, so something like chalicelib.blueprints.first_blueprint.my_lambda.
Problem with this, is that the initialization logic in app.py is completely skipped when the function is invoked, so any middleware registered there is not applied to the lambda function defined in the blueprint. In addition to this, because blueprints defer middleware registration until app.register_blueprint is called, defining middleware in the blueprint containing the lambda function doesn't work either.
There's no issues with REST APIs because the AWS Handler is always app.app, but not the case with lambda functions. I tested these scenario with a bunch of log statements throughout both my code and the chalice framework, and always end up having a PureLambdaWrapper when defining the lambda function through a blueprint but MiddlewareHandler when defining it in app.py because without registration logic in app.py being executed, the middleware list is always empty in the blueprint.
Here's more or less the structure I was using:
app.py:
app = Chalice(app_name="asdf')
app.register_middleware(error_handler, "pure_lambda")
app.register_blueprint(first_blueprint.first_routes)
app.register_blueprint(second_blueprint.second_routes)
chalicelib/blueprints/first_blueprint.py:
first_routes = Blueprint(__name__)
@first_routes.lambda_function(name="my-lambda-function")
def my_lambda_function(event: dict, context) -> dict:
return {"hello": "there"}
@first_routes.route("/cool/api/one", methods=['POST'], cors=True)
def cool_api_one() -> dict:
return {"another": "hello"}
chalicelib/blueprints/second_blueprint.py:
second_routes = Blueprint(__name__)
@second_routes.route("/cool/api/two", methods=['POST'], cors=True)
def cool_api_two() -> dict:
return {"yet another": "hello"}
Also not exactly related, but chalice deploy doesn't update the AWS Handler when switching between a version of the code not defining a lambda function through a blueprint and another which does. Only way I managed to fix that was by deleting my old lambda function or editing it with the new handler, but either option would create downtime. I can create another issue if this is actually a bug and is easier to deal with separately.