Summary
This release adds support for (1) Lambda context in Batch processing, (2) Context sharing support in REST and GraphQL APIs, and (3) Consolidate features to make prototyping local/non-prod environments easier. Bug fixes and other minor improvements are at the bottom.
Accessing Lambda context in Batch processing
You can now opt-in to receive a Lambda context object if your function has a parameter named lambda_context
.
This unlocks long-running data pipelines, where you need to know how much time you have left before your function times out - thanks to @mew1033 for the feature request.
from typing import Optional
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) # or DynamoDB, Kinesis
# lambda_context will be populated at runtime
def record_handler(record: SQSRecord, lambda_context: Optional[LambdaContext] = None): ...
@batch_processor(record_handler=record_handler, processor=processor)
def lambda_handler(event, context: LambdaContext):
return processor.response()
New context support in Event Handler (REST and GraphQL)
You can now inject contextual information before or during event routing. This is the precursor to Middleware support in Event Handler. This unlocks two common use cases:
- You split routes using
Router()
feature, and you need to pass data fromApp()
without running into potential circular import issues - You have custom logic to run before every event, and want to expose the result to any registered route with minimal effort
Thanks to @MaartenUreel for the feature request, and @benbridts, @gwlester, and @walmsles for the discussion to get to an optimal UX.
UX
Entrypoint: app.py
import todos
from aws_lambda_powertools.event_handler import APIGatewayRestResolver
from aws_lambda_powertools.utilities.typing import LambdaContext
app = APIGatewayRestResolver()
app.include_router(todos.router)
def lambda_handler(event: dict, context: LambdaContext) -> dict:
app.append_context(is_admin=True) # arbitrary number of key=value data
return app.resolve(event, context)
todos.py
import requests
from requests import Response
from aws_lambda_powertools.event_handler.api_gateway import Router
ENDPOINT = "https://jsonplaceholder.typicode.com/todos"
router = Router()
@router.get("/todos")
def get_todos():
is_admin: bool = router.context.get("is_admin", False)
todos = {}
if is_admin:
todos: Response = requests.get(ENDPOINT)
todos.raise_for_status()
todos = todos.json()[:10]
return {"todos": todos}
Optimizing for non-production environments
Thanks to @pmarko1711, Logger now uses pretty-print when you set POWERTOOLS_DEV=1
environment variable. This also helps us consolidate features where we can make it easier to prototype locally or against a non-production environment.
Debug mode simplified
When raising bug reports, you can now get Lambda Powertools debug logs with POWERTOOLS_DEBUG=1
. Previously, you had to change your source code to explicitly enable debugging in Powertools.
Changes
πNew features and non-breaking changes
- feat(logger): introduce POWERTOOLS_DEBUG for internal debugging (#1572) by @heitorlessa
- feat(logger): include logger name attribute when copy_config_to_registered_logger is used (#1568) by @heitorlessa
- feat(event-handler): context support to share data between routers (#1567) by @heitorlessa
- feat(batch): inject lambda_context if record handler signature accepts it (#1561) by @heitorlessa
- feat(logger): pretty-print JSON when POWERTOOLS_DEV is set (#1548) by @pmarko1711
π Documentation updates
- docs(homepage): introduce POWERTOOLS_DEV env var (#1569) by @heitorlessa
- docs(parser): add JSON string field extension example (#1526) by @rubenfonseca
π Bug and hot fixes
- fix(apigateway): update Response class to require status_code only (#1560) by @heitorlessa
- fix(event_sources): implement Mapping protocol on DictWrapper for better interop with existing middlewares (#1516) by @Tankanow
- fix(typing): level arg in copy_config_to_registered_loggers (#1534) by @kbakk
π§ Maintenance
- chore(multiple): localize powertools_dev env logic and warning (#1570) by @heitorlessa
- chore(deps-dev): bump types-requests from 2.28.11 to 2.28.11.1 (#1571) by @dependabot
- chore(deps): bump dependabot/fetch-metadata from 1.3.3 to 1.3.4 (#1565) by @dependabot
- chore(deps-dev): bump mkdocs-material from 8.5.3 to 8.5.4 (#1563) by @dependabot
- chore(deps-dev): bump mypy-boto3-secretsmanager from 1.24.54 to 1.24.83 (#1557) by @dependabot
- chore(deps-dev): bump pytest-cov from 3.0.0 to 4.0.0 (#1551) by @dependabot
- chore(deps-dev): bump flake8-bugbear from 22.9.11 to 22.9.23 (#1541) by @dependabot
- fix(event_sources): implement Mapping protocol on DictWrapper for better interop with existing middlewares (#1516) by @Tankanow
- chore(deps-dev): bump mypy-boto3-ssm from 1.24.80 to 1.24.81 (#1544) by @dependabot
- chore(deps-dev): bump mypy-boto3-ssm from 1.24.69 to 1.24.80 (#1542) by @dependabot
- chore(deps-dev): bump mako from 1.2.2 to 1.2.3 (#1537) by @dependabot
- chore(deps-dev): bump types-requests from 2.28.10 to 2.28.11 (#1538) by @dependabot
- chore(deps): bump email-validator from 1.2.1 to 1.3.0 (#1533) by @dependabot
- chore(deps-dev): bump mkdocs-material from 8.5.1 to 8.5.3 (#1532) by @dependabot
- chore(deps): bump fastjsonschema from 2.16.1 to 2.16.2 (#1530) by @dependabot
- chore(deps): bump codecov/codecov-action from 3.1.0 to 3.1.1 (#1529) by @dependabot
- chore(deps): bump actions/setup-python from 3 to 4 (#1528) by @dependabot
- chore(deps-dev): bump mypy-boto3-s3 from 1.24.36.post1 to 1.24.76 (#1531) by @dependabot
This release was made possible by the following contributors:
@Tankanow, @dependabot, @dependabot[bot], @heitorlessa, @kbakk, @pmarko1711, @rubenfonseca