aws-powertools / powertools-lambda-python

A developer toolkit to implement Serverless best practices and increase developer velocity.
https://docs.powertools.aws.dev/lambda/python/latest/
MIT No Attribution
2.72k stars 378 forks source link

APIGatewayProxyEventV2: Headers Property in BaseProxyEvent Returns Incorrect Type #4497

Closed adriamontoto closed 2 weeks ago

adriamontoto commented 3 weeks ago

Describe the bug

In the AWS CDK, the BaseProxyEvent class, which is the parent class of APIGatewayProxyEventV2, contains a property headers that is supposed to return a dictionary. However, when using the APIGatewayProxyEventV2 class, the headers property returns a string instead of a dictionary, which is inconsistent with the documented behavior of BaseProxyEvent.

class BaseProxyEvent(DictWrapper):
    @property
    def headers(self) -> Dict[str, str]:
        return self.get("headers") or {}

Expected Behaviour

The headers property of the BaseProxyEvent class (and its subclass APIGatewayProxyEventV2) should return a dictionary as per its property definition and documentation.

request = APIGatewayProxyEventV2(data=event)
print(type(request.headers))  # Expected: <class 'dict'>

Current Behaviour

The headers property of the APIGatewayProxyEventV2 class returns a string instead of a dictionary.

request = APIGatewayProxyEventV2(data=event)
print(type(request.headers))  # Actual: <class 'str'>

Reproduction Steps

Create a lambda function (with the following code) that is triggered by a gateway endpoint (Proxy integration).

from aws_lambda_powertools.utilities.data_classes import APIGatewayProxyEventV2

def lambda_handler(event, context):
      request= APIGatewayProxyEventV2(data=event)
      print(type(request.headers)) 

Possible Solution

No response

Powertools for AWS Lambda (Python) version

2.39.0

AWS Lambda function runtime

3.11

Packaging format used

Lambda Layers, PyPi

Debugging logs

No response

boring-cyborg[bot] commented 3 weeks ago

Thanks for opening your first issue here! We'll come back to you as soon as we can. In the meantime, check out the #python channel on our Powertools for AWS Lambda Discord: Invite link

leandrodamascena commented 3 weeks ago

Hello @adriiamontoto! Thanks for reporting this. Do you have a reproducible payload? I'm using a payload for v2 and I can't see the error. I am using SAM CLI to emulate the Lambda environment.

code.py

from aws_lambda_powertools.utilities.data_classes import APIGatewayProxyEventV2

def lambda_handler(event, context):
      request= APIGatewayProxyEventV2(data=event)
      print("Headers type --->: ", type(request.headers)) 

event.json

{
    "version": "2.0",
    "routeKey": "$default",
    "rawPath": "/my/path",
    "rawQueryString": "parameter1=value1&parameter1=value2&parameter2=value",
    "cookies": [
      "cookie1",
      "cookie2"
    ],
    "headers": {
      "Header1": "value1",
      "Header2": "value1,value2"
    },
    "queryStringParameters": {
      "parameter1": "value1,value2",
      "parameter2": "value"
    },
    "requestContext": {
      "accountId": "123456789012",
      "apiId": "api-id",
      "authentication": {
        "clientCert": {
          "clientCertPem": "CERT_CONTENT",
          "subjectDN": "www.example.com",
          "issuerDN": "Example issuer",
          "serialNumber": "a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1",
          "validity": {
            "notBefore": "May 28 12:30:02 2019 GMT",
            "notAfter": "Aug  5 09:36:04 2021 GMT"
          }
        }
      },
      "authorizer": {
        "jwt": {
          "claims": {
            "claim1": "value1",
            "claim2": "value2"
          },
          "scopes": [
            "scope1",
            "scope2"
          ]
        }
      },
      "domainName": "id.execute-api.us-east-1.amazonaws.com",
      "domainPrefix": "id",
      "http": {
        "method": "POST",
        "path": "/my/path",
        "protocol": "HTTP/1.1",
        "sourceIp": "192.168.0.1/32",
        "userAgent": "agent"
      },
      "requestId": "id",
      "routeKey": "$default",
      "stage": "$default",
      "time": "12/Mar/2020:19:03:58 +0000",
      "timeEpoch": 1583348638390
    },
    "body": "{\"message\": \"hello world\", \"username\": \"tom\"}",
    "pathParameters": {
      "parameter1": "value1"
    },
    "isBase64Encoded": false,
    "stageVariables": {
      "stageVariable1": "value1",
      "stageVariable2": "value2"
    }
  }

output

image

Thanks

leandrodamascena commented 2 weeks ago

Closing this issue! Please feel free to reopen.

github-actions[bot] commented 2 weeks ago

⚠️COMMENT VISIBILITY WARNING⚠️

This issue is now closed. Please be mindful that future comments are hard for our team to see.

If you need more assistance, please either tag a team member or open a new issue that references this one.

If you wish to keep having a conversation with other community members under this issue feel free to do so.