github.com/minio/minio@v0.0.0-20240328213742-3f72439b8a27/docs/lambda/README.md (about)

     1  # Object Lambda
     2  
     3  MinIO's Object Lambda implementation allows for transforming your data to serve unique data format requirements for each application. For example, a dataset created by an ecommerce application might include personally identifiable information (PII). When the same data is processed for analytics, PII should be redacted. However, if the same dataset is used for a marketing campaign, you might need to enrich the data with additional details, such as information from the customer loyalty database.
     4  
     5  MinIO's Object Lambda, enables application developers to process data retrieved from MinIO before returning it to an application. You can register a Lambda Function target on MinIO, once successfully registered it can be used to transform the data for application GET requests on demand.
     6  
     7  This document focuses on showing a working example on how to use Object Lambda with MinIO, you must have [MinIO deployed in your environment](https://min.io/docs/minio/linux/operations/installation.html) before you can start using external lambda functions. You also must install Python version 3.8 or later for the lambda handlers to work.
     8  
     9  ## Example Lambda handler
    10  
    11  Install the necessary dependencies.
    12  ```sh
    13  pip install flask requests
    14  ```
    15  
    16  Following is an example lambda handler.
    17  ```py
    18  from flask import Flask, request, abort, make_response
    19  import requests
    20  
    21  app = Flask(__name__)
    22  @app.route('/', methods=['POST'])
    23  def get_webhook():
    24  	if request.method == 'POST':
    25  		# obtain the request event from the 'POST' call
    26  		event = request.json
    27  
    28  		object_context = event["getObjectContext"]
    29  
    30  		# Get the presigned URL to fetch the requested
    31  		# original object from MinIO
    32  		s3_url = object_context["inputS3Url"]
    33  
    34  		# Extract the route and request token from the input context
    35  		request_route = object_context["outputRoute"]
    36  		request_token = object_context["outputToken"]
    37  
    38  		# Get the original S3 object using the presigned URL
    39  		r = requests.get(s3_url)
    40  		original_object = r.content.decode('utf-8')
    41  
    42  		# Transform all text in the original object to uppercase
    43  		# You can replace it with your custom code based on your use case
    44  		transformed_object = original_object.upper()
    45  
    46  		# Write object back to S3 Object Lambda
    47  		# response sends the transformed data
    48  		# back to MinIO and then to the user
    49  		resp = make_response(transformed_object, 200)
    50  		resp.headers['x-amz-request-route'] = request_route
    51  		resp.headers['x-amz-request-token'] = request_token
    52  		return resp
    53  
    54  	else:
    55  		abort(400)
    56  
    57  if __name__ == '__main__':
    58  	app.run()
    59  ```
    60  
    61  When you're writing a Lambda function for use with MinIO, the function is based on event context that MinIO provides to the Lambda function. The event context provides information about the request being made. It contains the parameters with relevant context. The fields used to create the Lambda function are as follows:
    62  
    63  The field of `getObjectContext` means the input and output details for connections to MinIO. It has the following fields:
    64  
    65  - `inputS3Url` – A presigned URL that the Lambda function can use to download the original object. By using a presigned URL, the Lambda function doesn't need to have MinIO credentials to retrieve the original object. This allows Lambda function to focus on transformation of the object instead of securing the credentials.
    66  
    67  - `outputRoute` – A routing token that is added to the response headers when the Lambda function returns the transformed object. This is used by MinIO to further verify the incoming response validity.
    68  
    69  - `outputToken` – A token added to the response headers when the Lambda function returns the transformed object. This is used by MinIO to verify the incoming response validity.
    70  
    71  Lets start the lamdba handler.
    72  
    73  ```
    74  python lambda_handler.py
    75   * Serving Flask app 'webhook'
    76   * Debug mode: off
    77  WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
    78   * Running on http://127.0.0.1:5000
    79  Press CTRL+C to quit
    80  ```
    81  
    82  ## Start MinIO with Lambda target
    83  
    84  Register MinIO with a Lambda function, we are calling our target name as `function`, but you may call it any other friendly name of your choice.
    85  ```
    86  MINIO_LAMBDA_WEBHOOK_ENABLE_function=on MINIO_LAMBDA_WEBHOOK_ENDPOINT_function=http://localhost:5000 minio server /data &
    87  ...
    88  ...
    89  MinIO Object Storage Server
    90  Copyright: 2015-2023 MinIO, Inc.
    91  License: GNU AGPLv3 <https://www.gnu.org/licenses/agpl-3.0.html>
    92  Version: DEVELOPMENT.2023-02-05T05-17-27Z (go1.19.4 linux/amd64)
    93  
    94  ...
    95  ...
    96  Object Lambda ARNs: arn:minio:s3-object-lambda::function:webhook
    97  
    98  ```
    99  
   100  ### Lambda Target with Auth Token
   101  
   102  If your lambda target expects an authorization token then you can enable it per function target as follows
   103  
   104  ```
   105  MINIO_LAMBDA_WEBHOOK_ENABLE_function=on MINIO_LAMBDA_WEBHOOK_ENDPOINT_function=http://localhost:5000 MINIO_LAMBDA_WEBHOOK_AUTH_TOKEN="mytoken" minio server /data &
   106  ```
   107  
   108  ### Lambda Target with mTLS authentication
   109  
   110  If your lambda target expects mTLS client you can enable it per function target as follows
   111  ```
   112  MINIO_LAMBDA_WEBHOOK_ENABLE_function=on MINIO_LAMBDA_WEBHOOK_ENDPOINT_function=http://localhost:5000 MINIO_LAMBDA_WEBHOOK_CLIENT_CERT=client.crt MINIO_LAMBDA_WEBHOOK_CLIENT_KEY=client.key minio server /data &
   113  ```
   114  
   115  ## Create a bucket and upload some data
   116  
   117  Create a bucket named `functionbucket`
   118  ```
   119  mc alias set myminio/ http://localhost:9000 minioadmin minioadmin
   120  mc mb myminio/functionbucket
   121  ```
   122  
   123  Create a file `testobject` with some test data that will be transformed
   124  ```
   125  cat > testobject << EOF
   126  MinIO is a High Performance Object Storage released under GNU Affero General Public License v3.0. It is API compatible with Amazon S3 cloud storage service. Use MinIO to build high performance infrastructure for machine learning, analytics and application data workloads.
   127  EOF
   128  ```
   129  
   130  Upload this object to the bucket via `mc cp`
   131  ```
   132  mc cp testobject myminio/functionbucket/
   133  ```
   134  
   135  ## Invoke Lambda transformation via PresignedGET
   136  
   137  Following example shows how you can use [`minio-go` PresignedGetObject](https://min.io/docs/minio/linux/developers/go/API.html#presignedgetobject-ctx-context-context-bucketname-objectname-string-expiry-time-duration-reqparams-url-values-url-url-error)
   138  ```go
   139  package main
   140  
   141  import (
   142  	"context"
   143  	"log"
   144  	"net/url"
   145  	"time"
   146  	"fmt"
   147  
   148  	"github.com/minio/minio-go/v7"
   149  	"github.com/minio/minio-go/v7/pkg/credentials"
   150  )
   151  
   152  func main() {
   153  	s3Client, err := minio.New("localhost:9000", &minio.Options{
   154  		Creds:  credentials.NewStaticV4("minioadmin", "minioadmin", ""),
   155  		Secure: false,
   156  	})
   157  	if err != nil {
   158  		log.Fatalln(err)
   159  	}
   160  
   161  	// Set lambda function target via `lambdaArn`
   162  	reqParams := make(url.Values)
   163  	reqParams.Set("lambdaArn", "arn:minio:s3-object-lambda::function:webhook")
   164  
   165  	// Generate presigned GET url with lambda function
   166  	presignedURL, err := s3Client.PresignedGetObject(context.Background(), "functionbucket", "testobject", time.Duration(1000)*time.Second, reqParams)
   167  	if err != nil {
   168  		log.Fatalln(err)
   169  	}
   170  	fmt.Println(presignedURL)
   171  }
   172  ```
   173  
   174  Use the Presigned URL via `curl` to receive the transformed object.
   175  ```
   176  curl -v $(go run presigned.go)
   177  ...
   178  ...
   179  > GET /functionbucket/testobject?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=minioadmin%2F20230205%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20230205T173023Z&X-Amz-Expires=1000&X-Amz-SignedHeaders=host&lambdaArn=arn%3Aminio%3As3-object-lambda%3A%3Atoupper%3Awebhook&X-Amz-Signature=d7e343f0da9d4fa2bc822c12ad2f54300ff16796a1edaa6d31f1313c8e94d5b2 HTTP/1.1
   180  > Host: localhost:9000
   181  > User-Agent: curl/7.81.0
   182  > Accept: */*
   183  >
   184  
   185  MINIO IS A HIGH PERFORMANCE OBJECT STORAGE RELEASED UNDER GNU AFFERO GENERAL PUBLIC LICENSE V3.0. IT IS API COMPATIBLE WITH AMAZON S3 CLOUD STORAGE SERVICE. USE MINIO TO BUILD HIGH PERFORMANCE INFRASTRUCTURE FOR MACHINE LEARNING, ANALYTICS AND APPLICATION DATA WORKLOADS.
   186  ```