Unleash the power of

<serverless>

with Powertools stripes for AWS
open source imageopen source image

Powertools for AWS is a developer toolkit to implement Serverless best practices and increase developer velocity

Voices of Success

Hear what our customers have to say

person

Daniel Furman

Distinguished Engineer at Capital One

person

Ran Isenberg

Principal Software Architect at CyberArk

<turbocharge>
your code

Powertools takes care of the heavy lifting, ensuring that your serverless applications adhere to industry-leading best practices. Say goodbye to tedious manual configuration and hello to automated optimization. Powertools for AWS effortlessly implements key serverless practices, including optimized resource allocation, efficient event-driven architecture, and streamlined scalability.

1250

Total lines of code

0%

Lines reduced

1import json
2import logging
3import os
4import boto3
5from aws_xray_sdk.core import xray_recorder
6from aws_xray_sdk.core import patch
7
8# Configure the logger
9logging.basicConfig(format='%(asctime)s - %(name)s - 
10%(levelname)s - %(message)s')
11logger = logging.getLogger()
12logger.setLevel(logging.INFO)
13
14# Configure AWS X-Ray
15patch(['boto3'])
16xray_recorder.configure(service='my-lambda-function')
17xray_recorder.configure(context_missing='LOG_ERROR')
18xray_recorder.configure(streaming_threshold=0)
19
20# Configure CloudWatch
21cloudwatch = boto3.client('cloudwatch')
22
23# Set cold start to true
24is_cold_start = True
25
26# Create a function to publish CloudWatch custom metrics
27def publish_custom_metric(value, metric_name):
28    cloudwatch.put_metric_data(
29        Namespace='WebsiteExample',
30        MetricData=[
31            {
32                'MetricName': metric_name,
33                'Value': value,
34                'Unit': 'Count'
35            }
36        ]
37    )
38
39def is_valid_payload(payload):
40    # Check if the payload resembles an AWS API Gateway event
41    return all(key in payload for key in ('httpMethod',
42    'path', 'queryStringParameters'))
43
44def lambda_handler(event, context):
45
46    # Initialize a trace segment
47    with xray_recorder.in_subsegment("## Lambda Handler ##") 
48    as subsegment:
49        # Check if the function is a cold start and create a 
50        metric
51        global is_cold_start
52        if not is_cold_start:
53            logger.info("Cold start detected. 
54            Initializing...")
55            publish_custom_metric(is_cold_start, "ColdStart")
56            is_cold_start = False
57
58            subsegment.put_annotation("ColdStart", "True")
59
60        # Check if the event resembles an AWS API Gateway 
61        event
62        if is_valid_payload(event):
63            # Check the HTTP method of the request
64            http_method = event['httpMethod']
65
66            # Default response content
67            response = {
68                "statusCode": 200,
69                "headers": {
70                    "Content-Type": "application/json"
71                },
72                "body": ""
73            }
74
75            # Retrieve the "id_todo" variable from the query 
76            parameters in the GET method
77            if http_method == "GET" and event['path'] == "/
78            example":
79                id_todo = event['queryStringParameters']
80                ['id_todo']
81                response["body"] = json.dumps({"message": 
82                f"This is the GET route /example, id_todo: 
83                {id_todo}"})
84                log_context = {
85                    "http_method": http_method,
86                    "path": event['path'],
87                    "id_todo": id_todo
88                }
89                logger.info(json.dumps(log_context))
90                # Publish a custom metric for the GET request
91                publish_custom_metric(1, "GETRequestCount")
92                subsegment.put_metadata("response", 
93                log_context)
94            # Receive a payload with "id_todo" and 
95            "name_todo" in the POST method
96            elif http_method == "POST" and event['path'] == 
97            "/example":
98                request_body = json.loads(event['body'])
99                id_todo = request_body.get('id_todo')
100                name_todo = request_body.get('name_todo')
101                log_context = {
102                    "http_method": http_method,
103                    "path": event['path'],
104                    "request_data": request_body
105                }
106                # Verify if the payload fields are filled
107                if id_todo and name_todo:
108                    response["body"] = json.dumps({"message": 
109                    f"This is the POST route /example, 
110                    id_todo: {id_todo}, name_todo: 
111                    {name_todo}"})
112                    logger.info(json.dumps(log_context))
113                    # Publish a custom metric for the POST 
114                    request
115                    publish_custom_metric(1, 
116                    "POSTRequestCount")
117                    subsegment.put_metadata("response", 
118                    log_context)
119                else:
120                    response["statusCode"] = 400  # Bad 
121                    Request
122                    response["body"] = json.dumps({"message": 
123                    "Missing 'id_todo' or 'name_todo' in the 
124                    payload"})
125                    logger.warning(json.dumps(log_context))
126            else:
127                # Handle other methods or paths, if needed
128                response["statusCode"] = 404
129                response["body"] = json.dumps({"message": 
130                "Route not found"})
131                log_context = {
132                    "http_method": http_method,
133                    "path": event['path'],
134                    "message": "Route not found"
135                }
136                logger.warning(json.dumps(log_context))
137        else:
138            # Handle cases where the payload doesn't resemble 
139            an AWS API Gateway event
140            response = {
141                "statusCode": 400,
142                "headers": {
143                    "Content-Type": "application/json"
144                },
145                "body": json.dumps({"message": "Invalid 
146                payload format"})
147            }
148            logger.warning("Invalid payload format")
149
150    return response

Join our thriving community

Collaborate, innovate, and shape the future together!

community image conversation image

<install>
Powertools for AWS

Python

TypeScript

Java

.NET

Lambda Layer (x86_64)

arn:aws:lambda:{region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:78

Lambda Layer (arm64)

arn:aws:lambda:{region}:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:78

Pip

pip install "aws-lambda-powertools"
github-logo

Open source
freedom

Harness the Power of our MIT-Licensed Solution

Get going with
Powertools
for AWS

<it’s free>


© 2025, Amazon Web Services, Inc. or its affiliates. All rights reserved.

Makeen logo