-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathFunction.cs
More file actions
192 lines (163 loc) · 7.43 KB
/
Copy pathFunction.cs
File metadata and controls
192 lines (163 loc) · 7.43 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
using System;
using System.Collections.Generic;
using System.IO;
using Assignment4AWSLambda.AWSService;
using System.Threading.Tasks;
using Amazon.Lambda.Core;
using Amazon.Lambda.S3Events;
using Amazon.Rekognition;
using Amazon.Rekognition.Model;
using Amazon.S3;
using Amazon.S3.Model;
using Amazon.DynamoDBv2;
using Assignment4AWSLambda.Model;
//test
// Assembly attribute to enable the Lambda function's JSON input to be converted into a .NET class.
[assembly: LambdaSerializer(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))]
namespace Assignment4AWSLambda
{
public class Function
{
/// <summary>
/// The default minimum confidence used for detecting labels.
/// </summary>
public const float DEFAULT_MIN_CONFIDENCE = 70f;
/// <summary>
/// The name of the environment variable to set which will override the default minimum confidence level.
/// </summary>
public const string MIN_CONFIDENCE_ENVIRONMENT_VARIABLE_NAME = "MinConfidence";
IAmazonS3 S3Client { get; }
IAmazonRekognition RekognitionClient { get; }
private IAmazonDynamoDB dynamoDBClient;
float MinConfidence { get; set; } = DEFAULT_MIN_CONFIDENCE;
HashSet<string> SupportedImageTypes { get; } = new HashSet<string> { ".png", ".jpg", ".jpeg" };
/// <summary>
/// Default constructor used by AWS Lambda to construct the function. Credentials and Region information will
/// be set by the running Lambda environment.
///
/// This constuctor will also search for the environment variable overriding the default minimum confidence level
/// for label detection.
/// </summary>
public Function()
{
this.dynamoDBClient = new AmazonDynamoDBClient();
this.S3Client = new AmazonS3Client();
this.RekognitionClient = new AmazonRekognitionClient();
new AWSDynamoService(dynamoDBClient);
var environmentMinConfidence = System.Environment.GetEnvironmentVariable(MIN_CONFIDENCE_ENVIRONMENT_VARIABLE_NAME);
if(!string.IsNullOrWhiteSpace(environmentMinConfidence))
{
float value;
if(float.TryParse(environmentMinConfidence, out value))
{
this.MinConfidence = value;
Console.WriteLine($"Setting minimum confidence to {this.MinConfidence}");
}
else
{
Console.WriteLine($"Failed to parse value {environmentMinConfidence} for minimum confidence. Reverting back to default of {this.MinConfidence}");
}
}
else
{
Console.WriteLine($"Using default minimum confidence of {this.MinConfidence}");
}
}
/// <summary>
/// Constructor used for testing which will pass in the already configured service clients.
/// </summary>
/// <param name="s3Client"></param>
/// <param name="rekognitionClient"></param>
/// <param name="minConfidence"></param>
public Function(IAmazonS3 s3Client, IAmazonRekognition rekognitionClient, float minConfidence)
{
this.S3Client = s3Client;
this.RekognitionClient = rekognitionClient;
this.MinConfidence = minConfidence;
}
/// <summary>
/// A function for responding to S3 create events. It will determine if the object is an image and use Amazon Rekognition
/// to detect labels and add the labels as tags on the S3 object.
/// </summary>
/// <param name="input"></param>
/// <param name="context"></param>
/// <returns></returns>
public async Task FunctionHandler(S3Event input, ILambdaContext context)
{
foreach(var record in input.Records)
{
if(!SupportedImageTypes.Contains(Path.GetExtension(record.S3.Object.Key)))
{
Console.WriteLine($"Object {record.S3.Bucket.Name}:{record.S3.Object.Key} is not a supported image type");
continue;
}
Console.WriteLine($"Looking for labels in image {record.S3.Bucket.Name}:{record.S3.Object.Key}");
var detectResponses = await this.RekognitionClient.DetectLabelsAsync(new DetectLabelsRequest
{
MinConfidence = MinConfidence,
Image = new Image
{
S3Object = new Amazon.Rekognition.Model.S3Object
{
Bucket = record.S3.Bucket.Name,
Name = record.S3.Object.Key
}
}
});
var tags = new List<Tag>();
var labels = new List<MyLabel>();
foreach(var label in detectResponses.Labels)
{
if(tags.Count < 10)
{
Console.WriteLine($"\tFound Label {label.Name} with confidence {label.Confidence}");
tags.Add(new Tag { Key = label.Name, Value = label.Confidence.ToString() });
labels.Add(new MyLabel { Key = label.Name, Value = label.Confidence.ToString() });
}
else
{
Console.WriteLine($"\tSkipped label {label.Name} with confidence {label.Confidence} because the maximum number of tags has been reached");
}
}
await this.S3Client.PutObjectTaggingAsync(new PutObjectTaggingRequest
{
BucketName = record.S3.Bucket.Name,
Key = record.S3.Object.Key,
Tagging = new Tagging
{
TagSet = tags
}
});
byte[] metadata;
using (GetObjectResponse response = await this.S3Client.GetObjectAsync(
record.S3.Bucket.Name,
record.S3.Object.Key))
{
using (Stream responseStream = response.ResponseStream)
{
using (StreamReader reader = new StreamReader(responseStream))
{
using (var memStream = new MemoryStream())
{
var buffer = new byte[512];
var bytesRead = default(int);
while ((bytesRead = reader.BaseStream.Read(buffer, 0, buffer.Length)) > 0)
memStream.Write(buffer, 0, bytesRead);
metadata = memStream.ToArray();
}
}
}
}
MyImage image = new MyImage();
image.BucketName = record.S3.Bucket.Name;
image.KeyName = record.S3.Object.Key;
image.Labels = labels;
image.Processed = false;
image.Metadata = metadata;
image = new AWSDynamoService(dynamoDBClient).Create(image).Result;
Console.WriteLine($"\tSaved {image.KeyName} with confidence {image.Id}");
}
return;
}
}
}