Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(batch): inject lambda_context if record handler signature accepts it #1561

Merged

Conversation

heitorlessa
Copy link
Contributor

@heitorlessa heitorlessa commented Sep 30, 2022

Issue number: #1242

Summary

Changes

Please provide a summary of what's being changed

This PR allows customers to receive a Lambda Context to help calculate how much time left before a request times out, among execution environment metadata.

User experience

Please share what the user experience looks like before and after this change

Record handlers can now update their signature with an additional parameter named lambda_context.

BEFORE

def record_handler(record: SQSRecord):

AFTER

def record_handler(record: SQSRecord, lambda_context: Optional[LambdaContext] = None): ...

@batch_processor decorator

When using @batch_processor decorator, we'll automatically inject the Lambda context.

from typing import Optional

from aws_lambda_powertools import Logger, Tracer
from aws_lambda_powertools.utilities.batch import (BatchProcessor, EventType,
                                                   batch_processor)
from aws_lambda_powertools.utilities.data_classes.sqs_event import SQSRecord
from aws_lambda_powertools.utilities.typing import LambdaContext

processor = BatchProcessor(event_type=EventType.SQS)
tracer = Tracer()
logger = Logger()


@tracer.capture_method
def record_handler(record: SQSRecord, lambda_context: Optional[LambdaContext] = None):
    if lambda_context is not None:
        remaining_time = lambda_context.get_remaining_time_in_millis()
    ...


@logger.inject_lambda_context
@tracer.capture_lambda_handler
@batch_processor(record_handler=record_handler, processor=processor)
def lambda_handler(event, context: LambdaContext):
    return processor.response()

batch processor context manager

When using the context manager, customers will need to pass the Lambda context as an additional parameter:

from typing import Optional

from aws_lambda_powertools import Logger, Tracer
from aws_lambda_powertools.utilities.batch import BatchProcessor, EventType
from aws_lambda_powertools.utilities.data_classes.sqs_event import SQSRecord
from aws_lambda_powertools.utilities.typing import LambdaContext

processor = BatchProcessor(event_type=EventType.SQS)
tracer = Tracer()
logger = Logger()


@tracer.capture_method
def record_handler(record: SQSRecord, lambda_context: Optional[LambdaContext] = None):
    if lambda_context is not None:
        remaining_time = lambda_context.get_remaining_time_in_millis()
    ...

@logger.inject_lambda_context
@tracer.capture_lambda_handler
def lambda_handler(event, context: LambdaContext):
    batch = event["Records"]
    with processor(records=batch, handler=record_handler, lambda_context=context):
        result = processor.process()

    return result

Checklist

If your change doesn't seem to apply, please leave them unchecked.

  • Meet tenets criteria
  • I have performed a self-review of this change
  • Changes have been tested
  • Changes are documented
  • PR title follows conventional commit semantics
  • Update documentation
  • Create tests for valid signature but context manager doesn't include lambda context
Is this a breaking change?

RFC issue number:

Checklist:

  • Migration process documented
  • Implement warnings (if it can live side by side)

Acknowledgment

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

Disclaimer: We value your time and bandwidth. As such, any pull requests created on non-triaged issues might not be successful.

@boring-cyborg boring-cyborg bot added the tests label Sep 30, 2022
@pull-request-size pull-request-size bot added the size/M Denotes a PR that changes 30-99 lines, ignoring generated files. label Sep 30, 2022
@github-actions github-actions bot added the feature New feature or functionality label Sep 30, 2022
@heitorlessa heitorlessa marked this pull request as ready for review September 30, 2022 15:09
@heitorlessa heitorlessa requested a review from a team as a code owner September 30, 2022 15:09
@heitorlessa heitorlessa requested review from am29d and rubenfonseca and removed request for a team and am29d September 30, 2022 15:09
@codecov-commenter
Copy link

Codecov Report

Base: 99.73% // Head: 99.73% // Increases project coverage by +0.00% 🎉

Coverage data is based on head (280355d) compared to base (effb910).
Patch coverage: 100.00% of modified lines in pull request are covered.

Additional details and impacted files
@@           Coverage Diff            @@
##           develop    #1561   +/-   ##
========================================
  Coverage    99.73%   99.73%           
========================================
  Files          124      124           
  Lines         5718     5727    +9     
  Branches       651      653    +2     
========================================
+ Hits          5703     5712    +9     
  Misses           8        8           
  Partials         7        7           
Impacted Files Coverage Δ
aws_lambda_powertools/utilities/batch/base.py 99.26% <100.00%> (+0.05%) ⬆️

Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here.

☔ View full report at Codecov.
📢 Do you have feedback about the report comment? Let us know in this issue.

@@ -94,7 +98,7 @@ def __enter__(self):
def __exit__(self, exception_type, exception_value, traceback):
self._clean()

def __call__(self, records: List[dict], handler: Callable):
def __call__(self, records: List[dict], handler: Callable, lambda_context: Optional[LambdaContext] = None):
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

note to self: take the opportunity to make records typing more specific. Need to check with Mypy accepts it due to liskov substitution principle.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since I can access record properties in my Lambda code, I'm not sure this is a real concern for now. Maybe in the future it's worth spending some time on it?
But yes, I love static and strong typing ❤️

@heitorlessa heitorlessa changed the title feat(batch): pass lambda_context if record handler signature accepts it feat(batch): inject lambda_context if record handler signature accepts it Oct 3, 2022
@heitorlessa heitorlessa self-assigned this Oct 3, 2022
Copy link
Contributor

@leandrodamascena leandrodamascena left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @heitorlessa! Another PR without errors and changes, you are a wizard! 🧙

@@ -94,7 +98,7 @@ def __enter__(self):
def __exit__(self, exception_type, exception_value, traceback):
self._clean()

def __call__(self, records: List[dict], handler: Callable):
def __call__(self, records: List[dict], handler: Callable, lambda_context: Optional[LambdaContext] = None):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since I can access record properties in my Lambda code, I'm not sure this is a real concern for now. Maybe in the future it's worth spending some time on it?
But yes, I love static and strong typing ❤️

self._handler_accepts_lambda_context = False
else:
self.lambda_context = lambda_context
self._handler_accepts_lambda_context = "lambda_context" in inspect.signature(self.handler).parameters
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to update the documentation to make it clear that the method signature must have a lambda_context parameter otherwise it won't work. The first time I tried to add a context parameter and I couldn't access LambdaContext properties LOL 😵‍💫

Mentioning #1369 not to forget when refactoring documentation.

@leandrodamascena leandrodamascena merged commit 9545f69 into aws-powertools:develop Oct 3, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature New feature or functionality size/M Denotes a PR that changes 30-99 lines, ignoring generated files. tests
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Feature request: Add the ability to access the LambdaContext when using batch processing
3 participants