From 74c220c99865d71026192de882d192f062401c59 Mon Sep 17 00:00:00 2001 From: Abilashkumar Date: Wed, 25 Dec 2024 16:00:34 +0530 Subject: [PATCH 1/6] rekognition-s3-detectlabels-python --- rekognition-s3-detectlabels-python/README.md | 66 ++++++++++++++ .../example-pattern.json | 59 +++++++++++++ .../src/lambda_function.py | 42 +++++++++ .../template.yaml | 85 +++++++++++++++++++ 4 files changed, 252 insertions(+) create mode 100644 rekognition-s3-detectlabels-python/README.md create mode 100644 rekognition-s3-detectlabels-python/example-pattern.json create mode 100644 rekognition-s3-detectlabels-python/src/lambda_function.py create mode 100644 rekognition-s3-detectlabels-python/template.yaml diff --git a/rekognition-s3-detectlabels-python/README.md b/rekognition-s3-detectlabels-python/README.md new file mode 100644 index 000000000..b6f083530 --- /dev/null +++ b/rekognition-s3-detectlabels-python/README.md @@ -0,0 +1,66 @@ +# Amazon S3 to Amazon Rekognition through AWS EventBridge + +This pattern demonstrates how to create an S3 bucket which when uploaded with an object invokes a Lambda function through EventBridge. The function detect labels in an image through Amazon Rekognition. The lambda function is built using Python. + +Learn more about this pattern at Serverless Land Patterns: https://serverlessland.com/patterns/s3-eventbridge-rekognition-detectlabels-python + +Important: this application uses various AWS services and there are costs associated with these services after the Free Tier usage - please see the [AWS Pricing page](https://aws.amazon.com/pricing/) for details. You are responsible for any AWS costs incurred. No warranty is implied in this example. + +## Requirements + +* [Create an AWS account](https://portal.aws.amazon.com/gp/aws/developer/registration/index.html) if you do not already have one and log in. The IAM user that you use must have sufficient permissions to make necessary AWS service calls and manage AWS resources. +* [AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/install-cliv2.html) installed and configured +* [Git Installed](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git) +* [AWS Serverless Application Model](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-install.html) (AWS SAM) installed + +## Deployment Instructions + +1. Create a new directory, navigate to that directory in a terminal and clone the GitHub repository: + ``` + git clone https://github.com/aws-samples/serverless-patterns + ``` +1. Change directory to the pattern directory: + ``` + cd s3-eventbridge-rekognition-detectfaces-python + ``` +1. From the command line, use AWS SAM to deploy the AWS resources for the pattern as specified in the template.yml file: + ``` + sam deploy --guided + ``` +1. During the prompts: + * Enter a stack name + * Enter the desired AWS Region + * Allow SAM CLI to create IAM roles with the required permissions. + + Once you have run `sam deploy --guided` mode once and saved arguments to a configuration file (samconfig.toml), you can use `sam deploy` in future to use these defaults. + +1. Note the outputs from the SAM deployment process. These contain the resource names and/or ARNs which are used for testing. + +## How it works + +The Cloudformation template creates 2 S3 buckets (source and destination buckets) along with a Lambda function (Python) and an EventBridge event. The Lambda function is triggered by the EventBridge which listens to an object upload in the S3 bucket. The lambda function makes a DetectLabels API call to detect the labels in an image and stores the output in the destination S3 bucket. + +## Testing + +Upload the file (document/image) to the input S3 -input-bucket- bucket via the console or use the PutObject API call below: + +``` +aws s3api put-object --bucket > --key --body /path/to/your/ +``` + +Replace the parameters in the above command appropriately. + +## Cleanup + +1. Delete the stack + ```bash + aws cloudformation delete-stack --stack-name STACK_NAME + ``` +1. Confirm the stack has been deleted + ```bash + aws cloudformation list-stacks --query "StackSummaries[?contains(StackName,'STACK_NAME')].StackStatus" + ``` +---- +Copyright 2024 Amazon.com, Inc. or its affiliates. All Rights Reserved. + +SPDX-License-Identifier: MIT-0 diff --git a/rekognition-s3-detectlabels-python/example-pattern.json b/rekognition-s3-detectlabels-python/example-pattern.json new file mode 100644 index 000000000..289a50a55 --- /dev/null +++ b/rekognition-s3-detectlabels-python/example-pattern.json @@ -0,0 +1,59 @@ +{ + "title": "S3 to Rekognition using EventBridge", + "description": "SAM template for S3 trigger to Lambda for detecting labels in an image using Rekognition and EventBridge", + "language": "python", + "level": "200", + "framework": "SAM", + "introBox": { + "headline": "How it works", + "text": [ + "This pattern demonstrates how to creates two S3 buckets (source and destination) which when uploaded with an object invokes a Lambda function through EventBridge and detects labels in an image using Amazon Rekognition.", + "Once a file is uploaded to an S3 bucket, it is listened by the EventBridge which further invokes the lambda function", + "The lambda function writes the output of the detected labels using Rekognition to the destination S3 bucket." + ] + }, + "gitHub": { + "template": { + "repoURL": "https://github.com/aws-samples/serverless-patterns/tree/main/rekognition-s3-detectlabels-python", + "templateURL": "serverless-patterns/rekognition-s3-detectlabels-python", + "projectFolder": "rekognition-s3-detectlabels-python", + "templateFile": "template.yaml" + } + }, + "resources": { + "bullets": [ + { + "text": "Detecting Labels using Rekognition", + "link": "https://docs.aws.amazon.com/rekognition/latest/dg/labels-detect-labels-image.html" + }, + { + "text": "Amazon Rekognition", + "link": "https://aws.amazon.com/rekognition/" + } + ] + }, + "deploy": { + "text": [ + "sam deploy" + ] + }, + "testing": { + "text": [ + "See the GitHub repo for detailed testing instructions." + ] + }, + "cleanup": { + "text": [ + "Delete the stack: cdk delete." + ] + }, + "authors": [ + { + "name": "Abilashkumar P C", + "image": "https://drive.google.com/file/d/1bxOh_WBw8J_xEqvT-qRezH8WXqSBPI24/view?usp=sharing", + "bio": "Sr. Cloud Support Engineer @ AWS", + "linkedin": "abilashkumar-p-c" + } + ] + } + \ No newline at end of file diff --git a/rekognition-s3-detectlabels-python/src/lambda_function.py b/rekognition-s3-detectlabels-python/src/lambda_function.py new file mode 100644 index 000000000..3ace93479 --- /dev/null +++ b/rekognition-s3-detectlabels-python/src/lambda_function.py @@ -0,0 +1,42 @@ +import boto3 +import json +import os +s3 = boto3.client('s3') +rekognition = boto3.client('rekognition') + +def handler(event, context): + # Extract bucket and key from the EventBridge event + detail = event['detail'] + bucket = detail['bucket']['name'] + key = detail['object']['key'] + + # Call Rekognition to detect faces + response = rekognition.detect_labels( + Image={ + 'S3Object': { + 'Bucket': bucket, + 'Name': key + } + }, + MaxLabels=15 + ) + + # Write the Rekognition output to the output bucket + output_key = f"rekognition-output-{key}" + output_key = output_key[:output_key.rfind('.')] + output_key = output_key + ".json" + print(output_key) + + labelDetection=response['Labels'] + print(response) + + s3.put_object( + Bucket=os.environ['OUTPUT_BUCKET'], + Key=output_key, + Body=json.dumps(labelDetection) + ) + + return { + 'statusCode': 200, + 'body': json.dumps('Label detection successfully') + } \ No newline at end of file diff --git a/rekognition-s3-detectlabels-python/template.yaml b/rekognition-s3-detectlabels-python/template.yaml new file mode 100644 index 000000000..6c78e8031 --- /dev/null +++ b/rekognition-s3-detectlabels-python/template.yaml @@ -0,0 +1,85 @@ +AWSTemplateFormatVersion: '2010-09-09' +Transform: AWS::Serverless-2016-10-31 +Description: 'SAM template for S3 trigger to Lambda for detecting labels in an image using Rekognition and EventBridge' + +Resources: + # Input S3 bucket + InputBucket: + Type: AWS::S3::Bucket + Properties: + BucketName: !Sub '${AWS::StackName}-input-bucket-${AWS::AccountId}' + NotificationConfiguration: + EventBridgeConfiguration: + EventBridgeEnabled: true + + # Output S3 bucket + OutputBucket: + Type: AWS::S3::Bucket + Properties: + BucketName: !Sub '${AWS::StackName}-output-bucket-${AWS::AccountId}' + + # Lambda function + RekognitionFunction: + Type: AWS::Serverless::Function + Properties: + FunctionName: !Sub '${AWS::StackName}-rekognition-function' + Handler: lambda_function.handler + Runtime: python3.8 + Timeout: 30 + Environment: + Variables: + OUTPUT_BUCKET: !Ref OutputBucket + Policies: + - S3ReadPolicy: + BucketName: !Ref InputBucket + - S3WritePolicy: + BucketName: !Ref OutputBucket + - Statement: + - Effect: Allow + Action: + - rekognition:DetectLabels + Resource: '*' + CodeUri: src/ + + + # EventBridge Rule + S3ObjectCreatedRule: + Type: AWS::Events::Rule + Properties: + Description: "Rule to capture S3 object created events" + EventPattern: + source: + - aws.s3 + detail-type: + - Object Created + detail: + bucket: + name: + - !Ref InputBucket + State: "ENABLED" + Targets: + - Arn: !GetAtt RekognitionFunction.Arn + Id: "RekognitionFunctionTarget" + + # Permission for EventBridge to invoke Lambda + RekognitionFunctionPermission: + Type: AWS::Lambda::Permission + Properties: + FunctionName: !Ref RekognitionFunction + Action: "lambda:InvokeFunction" + Principal: "events.amazonaws.com" + SourceArn: !GetAtt S3ObjectCreatedRule.Arn + +Outputs: + InputBucketName: + Description: 'Name of the input S3 bucket' + Value: !Ref InputBucket + OutputBucketName: + Description: 'Name of the output S3 bucket' + Value: !Ref OutputBucket + RekognitionFunctionName: + Description: 'Name of the Rekognition Lambda function' + Value: !Ref RekognitionFunction + RekognitionFunctionArn: + Description: 'ARN of the Rekognition Lambda function' + Value: !GetAtt RekognitionFunction.Arn From d122d4fde0c11d9020ba51d0073fb166111c68ef Mon Sep 17 00:00:00 2001 From: Abilashkumar <111060919+abilashkumar@users.noreply.github.com> Date: Wed, 25 Dec 2024 16:11:03 +0530 Subject: [PATCH 2/6] Update README.md --- rekognition-s3-detectlabels-python/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rekognition-s3-detectlabels-python/README.md b/rekognition-s3-detectlabels-python/README.md index b6f083530..694f9d5d6 100644 --- a/rekognition-s3-detectlabels-python/README.md +++ b/rekognition-s3-detectlabels-python/README.md @@ -2,7 +2,7 @@ This pattern demonstrates how to create an S3 bucket which when uploaded with an object invokes a Lambda function through EventBridge. The function detect labels in an image through Amazon Rekognition. The lambda function is built using Python. -Learn more about this pattern at Serverless Land Patterns: https://serverlessland.com/patterns/s3-eventbridge-rekognition-detectlabels-python +Learn more about this pattern at Serverless Land Patterns: https://serverlessland.com/patterns/rekognition-s3-detectlabels-python Important: this application uses various AWS services and there are costs associated with these services after the Free Tier usage - please see the [AWS Pricing page](https://aws.amazon.com/pricing/) for details. You are responsible for any AWS costs incurred. No warranty is implied in this example. From 25c3701db20fca9e1e39b8ab5fe1251b422ca0aa Mon Sep 17 00:00:00 2001 From: Abilashkumar <111060919+abilashkumar@users.noreply.github.com> Date: Wed, 25 Dec 2024 16:17:29 +0530 Subject: [PATCH 3/6] Update README.md --- rekognition-s3-detectlabels-python/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rekognition-s3-detectlabels-python/README.md b/rekognition-s3-detectlabels-python/README.md index 694f9d5d6..0a45a87da 100644 --- a/rekognition-s3-detectlabels-python/README.md +++ b/rekognition-s3-detectlabels-python/README.md @@ -21,7 +21,7 @@ Important: this application uses various AWS services and there are costs associ ``` 1. Change directory to the pattern directory: ``` - cd s3-eventbridge-rekognition-detectfaces-python + cd rekognition-s3-detectlabels-python ``` 1. From the command line, use AWS SAM to deploy the AWS resources for the pattern as specified in the template.yml file: ``` From 3028fd0bf97829b5f7e22a44bebdd035cd4d7edc Mon Sep 17 00:00:00 2001 From: Abilashkumar <111060919+abilashkumar@users.noreply.github.com> Date: Thu, 2 Jan 2025 16:30:01 +0530 Subject: [PATCH 4/6] Update README.md Added changes on "delete the stack" section and mentioned the output can be downloaded. --- rekognition-s3-detectlabels-python/README.md | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/rekognition-s3-detectlabels-python/README.md b/rekognition-s3-detectlabels-python/README.md index 0a45a87da..9c16151a6 100644 --- a/rekognition-s3-detectlabels-python/README.md +++ b/rekognition-s3-detectlabels-python/README.md @@ -47,6 +47,7 @@ Upload the file (document/image) to the input S3 -input-bucket-> --key --body /path/to/your/ ``` +The output of the operation can be downloaded from the output S3 bucket -output-bucket-. Replace the parameters in the above command appropriately. @@ -54,11 +55,7 @@ Replace the parameters in the above command appropriately. 1. Delete the stack ```bash - aws cloudformation delete-stack --stack-name STACK_NAME - ``` -1. Confirm the stack has been deleted - ```bash - aws cloudformation list-stacks --query "StackSummaries[?contains(StackName,'STACK_NAME')].StackStatus" + sam delete ``` ---- Copyright 2024 Amazon.com, Inc. or its affiliates. All Rights Reserved. From 678d47afe9c01ba0ec77a7573a66e56ffff5a312 Mon Sep 17 00:00:00 2001 From: Abilashkumar <111060919+abilashkumar@users.noreply.github.com> Date: Thu, 2 Jan 2025 16:30:56 +0530 Subject: [PATCH 5/6] Apply suggestions from code review Updated the suggested changes Co-authored-by: Marco --- rekognition-s3-detectlabels-python/README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/rekognition-s3-detectlabels-python/README.md b/rekognition-s3-detectlabels-python/README.md index 9c16151a6..1c09daac3 100644 --- a/rekognition-s3-detectlabels-python/README.md +++ b/rekognition-s3-detectlabels-python/README.md @@ -1,6 +1,6 @@ # Amazon S3 to Amazon Rekognition through AWS EventBridge -This pattern demonstrates how to create an S3 bucket which when uploaded with an object invokes a Lambda function through EventBridge. The function detect labels in an image through Amazon Rekognition. The lambda function is built using Python. +This pattern demonstrates how to create an Amazon S3 bucket that triggers an AWS Lambda function via Amazon EventBridge upon object upload. The Lambda function detects labels in an image using Amazon Rekognition. The Lambda function is built using Python. Learn more about this pattern at Serverless Land Patterns: https://serverlessland.com/patterns/rekognition-s3-detectlabels-python @@ -38,14 +38,14 @@ Important: this application uses various AWS services and there are costs associ ## How it works -The Cloudformation template creates 2 S3 buckets (source and destination buckets) along with a Lambda function (Python) and an EventBridge event. The Lambda function is triggered by the EventBridge which listens to an object upload in the S3 bucket. The lambda function makes a DetectLabels API call to detect the labels in an image and stores the output in the destination S3 bucket. +The CloudFormation template creates two Amazon S3 buckets (source and destination) along with an AWS Lambda function (written in Python) and an Amazon EventBridge event. The Lambda function is triggered by EventBridge, which listens for object uploads in the S3 source bucket. The Lambda function makes a `DetectLabels` API call to Amazon Rekognition to detect labels in an image and stores the output in the destination S3 bucket. ## Testing -Upload the file (document/image) to the input S3 -input-bucket- bucket via the console or use the PutObject API call below: +Upload the file (document/image) to the input S3 `-input-bucket-` bucket via the console or use the `PutObject` API call below: ``` -aws s3api put-object --bucket > --key --body /path/to/your/ +aws s3api put-object --bucket --key --body /path/to/your/ ``` The output of the operation can be downloaded from the output S3 bucket -output-bucket-. From 8699fa39a945bfe58cfb9009cdb08fbf8999d38e Mon Sep 17 00:00:00 2001 From: Marco Date: Fri, 24 Jan 2025 15:36:29 +0100 Subject: [PATCH 6/6] Create rekognition-s3-detectlabels-python.json added patterns json --- .../rekognition-s3-detectlabels-python.json | 82 +++++++++++++++++++ 1 file changed, 82 insertions(+) create mode 100644 rekognition-s3-detectlabels-python/rekognition-s3-detectlabels-python.json diff --git a/rekognition-s3-detectlabels-python/rekognition-s3-detectlabels-python.json b/rekognition-s3-detectlabels-python/rekognition-s3-detectlabels-python.json new file mode 100644 index 000000000..a1181d0ae --- /dev/null +++ b/rekognition-s3-detectlabels-python/rekognition-s3-detectlabels-python.json @@ -0,0 +1,82 @@ +{ + "title": "S3 to Rekognition using EventBridge", + "description": "SAM template for Amazon S3 trigger to AWS Lambda for detecting labels in an image using Amazon Rekognition and Amazon EventBridge", + "language": "Python", + "level": "200", + "framework": "SAM", + "introBox": { + "headline": "How it works", + "text": [ + "This pattern demonstrates how to creates two S3 buckets (source and destination) which when uploaded with an object invokes a Lambda function through EventBridge and detects labels in an image using Amazon Rekognition.", + "Once a file is uploaded to an S3 bucket, it is listened by the EventBridge which further invokes the lambda function", + "The lambda function writes the output of the detected labels using Rekognition to the destination S3 bucket." + ] + }, + "gitHub": { + "template": { + "repoURL": "https://github.com/aws-samples/serverless-patterns/tree/main/rekognition-s3-detectlabels-python", + "templateURL": "serverless-patterns/rekognition-s3-detectlabels-python", + "projectFolder": "rekognition-s3-detectlabels-python", + "templateFile": "template.yaml" + } + }, + "resources": { + "bullets": [ + { + "text": "Detecting Labels using Rekognition", + "link": "https://docs.aws.amazon.com/rekognition/latest/dg/labels-detect-labels-image.html" + }, + { + "text": "Amazon Rekognition", + "link": "https://aws.amazon.com/rekognition/" + } + ] + }, + "deploy": { + "text": ["sam deploy"] + }, + "testing": { + "text": ["See the GitHub repo for detailed testing instructions."] + }, + "cleanup": { + "text": ["Delete the stack: cdk delete."] + }, + "authors": [ + { + "name": "Abilashkumar P C", + "image": "https://drive.google.com/file/d/1bxOh_WBw8J_xEqvT-qRezH8WXqSBPI24/view?usp=sharing", + "bio": "Sr. Cloud Support Engineer @ AWS", + "linkedin": "abilashkumar-p-c" + } + ], + "patternArch": { + "icon1": { + "x": 20, + "y": 50, + "service": "s3", + "label": "Amazon S3" + }, + "icon2": { + "x": 50, + "y": 50, + "service": "lambda", + "label": "AWS Lambda" + }, + "icon3": { + "x": 80, + "y": 50, + "service": "rekognition", + "label": "Amazon Rekognition" + }, + "line1": { + "from": "icon1", + "to": "icon2", + "label": "" + }, + "line2": { + "from": "icon2", + "to": "icon3", + "label": "" + } + } +}