Skip to content

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

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

Closed
2 tasks done
gwlester opened this issue Apr 21, 2022 · 9 comments
Closed
2 tasks done
Assignees
Labels
feature-request feature request

Comments

@gwlester
Copy link
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

@gwlester gwlester added feature-request feature request triage Pending triage from maintainers labels Apr 21, 2022
@michaelbrewer
Copy link
Contributor

michaelbrewer commented Apr 21, 2022

@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
Copy link
Contributor Author

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

@michaelbrewer
Copy link
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 removed the triage Pending triage from maintainers label May 20, 2022
@heitorlessa
Copy link
Contributor

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

@rubenfonseca
Copy link
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
Copy link
Contributor Author

gwlester commented Jul 28, 2022 via email

@rubenfonseca
Copy link
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
Copy link
Contributor

Closing as it was released in 1.27.0

@github-actions
Copy link
Contributor

github-actions bot commented Aug 8, 2022

⚠️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
Labels
feature-request feature request
Projects
None yet
Development

No branches or pull requests

4 participants