Skip to content

Feature request: Add Event Source Data Class for AWS Lambda Function URLs #1141

Closed
@gwlester

Description

@gwlester
Contributor

Use case

With the general availability of AWS Lambda Function URLs to implement microservices AWS Lambda Powertools for Python should support this event type.

While I can not find a formal definition of what the event can look at, here is a sample:
{'version': '2.0', 'routeKey': '$default', 'rawPath': '/favicon.ico', 'rawQueryString': '', 'headers': {'sec-fetch-mode': 'no-cors', 'referer': 'https://c3zn6zdoafuxiztw6peqnbnflm0mywcm.lambda-url.us-east-1.on.aws/', 'sec-fetch-site': 'same-origin', 'accept-language': 'en-US,en;q=0.9', 'x-forwarded-proto': 'https', 'x-forwarded-port': '443', 'x-forwarded-for': '98.164.126.35', 'accept': 'image/avif,image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8', 'sec-ch-ua': '\" Not A;Brand\";v=\"99\", \"Chromium\";v=\"100\", \"Google Chrome\";v=\"100\"', 'sec-ch-ua-mobile': '?0', 'x-amzn-trace-id': 'Root=1-6260d9a0-4156ec632c4ba12352c4ff3a', 'sec-ch-ua-platform': '\"Linux\"', 'host': 'c3zn6zdoafuxiztw6peqnbnflm0mywcm.lambda-url.us-east-1.on.aws', 'accept-encoding': 'gzip, deflate, br', 'sec-fetch-dest': 'image', 'user-agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.75 Safari/537.36'}, 'requestContext': {'accountId': 'anonymous', 'apiId': 'c3zn6zdoafuxiztw6peqnbnflm0mywcm', 'domainName': 'c3zn6zdoafuxiztw6peqnbnflm0mywcm.lambda-url.us-east-1.on.aws', 'domainPrefix': 'c3zn6zdoafuxiztw6peqnbnflm0mywcm', 'http': {'method': 'GET', 'path': '/favicon.ico', 'protocol': 'HTTP/1.1', 'sourceIp': '98.164.126.35', 'userAgent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.75 Safari/537.36'}, 'requestId': '1e5fa2e6-65a2-474a-96f6-4c9858b0943f', 'routeKey': '$default', 'stage': '$default', 'time': '21/Apr/2022:04:12:16 +0000', 'timeEpoch': 1650514336041}, 'isBase64Encoded': False}

Please note that the path to the lambda is effectively /*.

Solution/User Experience

`
from aws_lambda_powertools.utilities.data_classes import event_source, FunctionUrlEvent

@event_source(data_class=FunctionUrlEvent)
`

Alternative solutions

No response

Acknowledgment

  • This feature request meets Lambda Powertools Tenets
    Should this be considered in other Lambda Powertools languages? i.e. Java, TypeScript

Activity

michaelbrewer

michaelbrewer commented on Apr 21, 2022

@michaelbrewer
Contributor

@gwlester it is pretty much the same as http api. And for now, even though i would like to resolve this, things are on a pause until August. Until then check what i mentioned elsewhere

from aws_lambda_powertools.utilities.data_classes import event_source, APIGatewayProxyEventV2

@event_source(data_class=APIGatewayProxyEventV2)
def handler(event: APIGatewayProxyEventV2, context):
   ...
gwlester

gwlester commented on Apr 21, 2022

@gwlester
ContributorAuthor

@michaelbrewer -- thanks for the "work around"!

michaelbrewer

michaelbrewer commented on May 3, 2022

@michaelbrewer
Contributor

The closet to official from AWS in the aws lambda go library:

Request:

{
  "version": "2.0",
  "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": "<urlid>",
    "authorizer": {
      "iam": {
        "accessKey": "AKIA...",
        "accountId": "111122223333",
        "callerId": "AIDA...",
        "userArn": "arn:aws:iam::111122223333:user/example-user",
        "userId": "AIDA..."
      }
    },
    "domainName": "<url-id>.lambda-url.us-west-2.on.aws",
    "domainPrefix": "<url-id>",
    "http": {
      "method": "POST",
      "path": "/my/path",
      "protocol": "HTTP/1.1",
      "sourceIp": "123.123.123.123",
      "userAgent": "agent"
    },
    "requestId": "id",
    "time": "12/Mar/2020:19:03:58 +0000",
    "timeEpoch": 1583348638390
  },
  "body": "Hello from client!",
  "isBase64Encoded": false
}

Response:

{
   "statusCode": 201,
    "headers": {
        "Content-Type": "application/json",
        "My-Custom-Header": "Custom Value"
    },
    "body": "{ \"message\": \"Hello, world!\" }",
    "cookies": [
        "Cookie_1=Value1; Expires=21 Oct 2021 07:48 GMT",
        "Cookie_2=Value2; Max-Age=78000"
    ],
    "isBase64Encoded": false
}

Go source:

// Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.

package events

// LambdaFunctionURLRequest contains data coming from the HTTP request to a Lambda Function URL.
type LambdaFunctionURLRequest struct {
	Version               string                          `json:"version"` // Version is expected to be `"2.0"`
	RawPath               string                          `json:"rawPath"`
	RawQueryString        string                          `json:"rawQueryString"`
	Cookies               []string                        `json:"cookies,omitempty"`
	Headers               map[string]string               `json:"headers"`
	QueryStringParameters map[string]string               `json:"queryStringParameters,omitempty"`
	RequestContext        LambdaFunctionURLRequestContext `json:"requestContext"`
	Body                  string                          `json:"body,omitempty"`
	IsBase64Encoded       bool                            `json:"isBase64Encoded"`
}

// LambdaFunctionURLRequestContext contains the information to identify the AWS account and resources invoking the Lambda function.
type LambdaFunctionURLRequestContext struct {
	AccountID    string                                                `json:"accountId"`
	RequestID    string                                                `json:"requestId"`
	Authorizer   *LambdaFunctionURLRequestContextAuthorizerDescription `json:"authorizer,omitempty"`
	APIID        string                                                `json:"apiId"`        // APIID is the Lambda URL ID
	DomainName   string                                                `json:"domainName"`   // DomainName is of the format `"<url-id>.lambda-url.<region>.on.aws"`
	DomainPrefix string                                                `json:"domainPrefix"` // DomainPrefix is the Lambda URL ID
	Time         string                                                `json:"time"`
	TimeEpoch    int64                                                 `json:"timeEpoch"`
	HTTP         LambdaFunctionURLRequestContextHTTPDescription        `json:"http"`
}

// LambdaFunctionURLRequestContextAuthorizerDescription contains authorizer information for the request context.
type LambdaFunctionURLRequestContextAuthorizerDescription struct {
	IAM *LambdaFunctionURLRequestContextAuthorizerIAMDescription `json:"iam,omitempty"`
}

// LambdaFunctionURLRequestContextAuthorizerIAMDescription contains IAM information for the request context.
type LambdaFunctionURLRequestContextAuthorizerIAMDescription struct {
	AccessKey string `json:"accessKey"`
	AccountID string `json:"accountId"`
	CallerID  string `json:"callerId"`
	UserARN   string `json:"userArn"`
	UserID    string `json:"userId"`
}

// LambdaFunctionURLRequestContextHTTPDescription contains HTTP information for the request context.
type LambdaFunctionURLRequestContextHTTPDescription struct {
	Method    string `json:"method"`
	Path      string `json:"path"`
	Protocol  string `json:"protocol"`
	SourceIP  string `json:"sourceIp"`
	UserAgent string `json:"userAgent"`
}

// LambdaFunctionURLResponse configures the HTTP response to be returned by Lambda Function URL for the request.
type LambdaFunctionURLResponse struct {
	StatusCode      int               `json:"statusCode"`
	Headers         map[string]string `json:"headers"`
	Body            string            `json:"body"`
	IsBase64Encoded bool              `json:"isBase64Encoded"`
	Cookies         []string          `json:"cookies"`
}
heitorlessa

heitorlessa commented on Jun 13, 2022

@heitorlessa
Contributor

Hey @gwlester we'll be looking in implementing official support for Lambda Function URL as soon as our pause ends.

rubenfonseca

rubenfonseca commented on Jul 28, 2022

@rubenfonseca
Contributor

Hi @gwlester! We're looking to start implementing this feature for release at the end of the next week. We would love if you had the change to contribute the necessary changes yourself. Otherwise, we will also be happy to take a look and ask you for a review. What would be the best for you?

gwlester

gwlester commented on Jul 28, 2022

@gwlester
ContributorAuthor
self-assigned this
on Jul 28, 2022
rubenfonseca

rubenfonseca commented on Aug 3, 2022

@rubenfonseca
Contributor

Hi @gwlester we've now worked on an implementation of the AWS Lambda Function URL data class and event handler here: #1408

We would appreciate if you take a look and review the code. And we're looking forward to any feedback you might have.

heitorlessa

heitorlessa commented on Aug 8, 2022

@heitorlessa
Contributor

Closing as it was released in 1.27.0

github-actions

github-actions commented on Aug 8, 2022

@github-actions
Contributor

⚠️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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

    Development

    No branches or pull requests

      Participants

      @rubenfonseca@gwlester@heitorlessa@michaelbrewer

      Issue actions

        Feature request: Add Event Source Data Class for AWS Lambda Function URLs · Issue #1141 · aws-powertools/powertools-lambda-python