Blueprints and lambda function inconsistency
- Dominant language
- Python
- Stars
- 11.1k
- Forks
- 1k
- Avg merge
- 1d 22h
- Merged PRs (30d)
- 2
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.
Contributor guide
Research direction
Start by reproducing the blueprint lambda scenario from app.py and chalicelib/blueprints/first_blueprint.py, then inspect sam.json and the PureLambdaWrapper versus MiddlewareHandler paths. Check the related chalice deploy behavior when the handler changes. Done means the blueprint lambda and app-level lambda follow the intended middleware and deployment behavior without requiring manual function edits.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- aws, python
- Domain
- backend, cloud
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100