Part 5: Add S3 delete event handler¶
Now that we are automatically importing uploaded images to our table, we need to be able to automatically delete images from our table that get deleted from our bucket. This can be accomplished by doing the following:
Add Lambda function for S3 object deletion¶
Add a new Lambda function that is invoked whenever an object is deleted from the S3 bucket and if it is an image, removes the image from the table.
Instructions¶
In the
app.pyfile add a new functionhandle_object_removedthat is triggered whenever an object gets deleted from the bucket and deletes the item from table if it is an image:
@app.on_s3_event(bucket=os.environ['MEDIA_BUCKET_NAME'], events=['s3:ObjectRemoved:*']) def handle_object_removed(event): if _is_image(event.key): get_media_db().delete_media_file(event.key)
Verification¶
Ensure the contents of the
app.pyfile is:
1import os
2
3import boto3
4from chalice import Chalice
5from chalicelib import db
6from chalicelib import rekognition
7
8app = Chalice(app_name='media-query')
9
10_MEDIA_DB = None
11_REKOGNITION_CLIENT = None
12_SUPPORTED_IMAGE_EXTENSIONS = (
13 '.jpg',
14 '.png',
15)
16
17
18def get_media_db():
19 global _MEDIA_DB
20 if _MEDIA_DB is None:
21 _MEDIA_DB = db.DynamoMediaDB(
22 boto3.resource('dynamodb').Table(
23 os.environ['MEDIA_TABLE_NAME']))
24 return _MEDIA_DB
25
26
27def get_rekognition_client():
28 global _REKOGNITION_CLIENT
29 if _REKOGNITION_CLIENT is None:
30 _REKOGNITION_CLIENT = rekognition.RekognitonClient(
31 boto3.client('rekognition'))
32 return _REKOGNITION_CLIENT
33
34
35@app.on_s3_event(bucket=os.environ['MEDIA_BUCKET_NAME'],
36 events=['s3:ObjectCreated:*'])
37def handle_object_created(event):
38 if _is_image(event.key):
39 _handle_created_image(bucket=event.bucket, key=event.key)
40
41
42@app.on_s3_event(bucket=os.environ['MEDIA_BUCKET_NAME'],
43 events=['s3:ObjectRemoved:*'])
44def handle_object_removed(event):
45 if _is_image(event.key):
46 get_media_db().delete_media_file(event.key)
47
48
49def _is_image(key):
50 return key.endswith(_SUPPORTED_IMAGE_EXTENSIONS)
51
52
53def _handle_created_image(bucket, key):
54 labels = get_rekognition_client().get_image_labels(bucket=bucket, key=key)
55 get_media_db().add_media_file(key, media_type=db.IMAGE_TYPE, labels=labels)
Redeploy the Chalice application¶
Deploy the updated Chalice application with the new Lambda function.
Instructions¶
Run
chalice deploy:$ chalice deploy Creating IAM role: media-query-dev-handle_object_removed Creating lambda function: media-query-dev-handle_object_removed Configuring S3 events in bucket media-query-mediabucket-fb8oddjbslv1 to function media-query-dev-handle_object_removed Resources deployed: - Lambda ARN: arn:aws:lambda:us-west-2:123456789123:function:media-query-dev-handle_object_created - Lambda ARN: arn:aws:lambda:us-west-2:123456789123:function:media-query-dev-handle_object_removed
Verification¶
Delete the uploaded
othersample.jpgobject from the previous part:$ aws s3 rm s3://$MEDIA_BUCKET_NAME/othersample.jpg
Use the
scanCLI command to ensure the object is no longer in the table:$ aws dynamodb scan --table-name $MEDIA_TABLE_NAME { "Items": [ { "name": { "S": "sample.jpg" }, "labels": { "L": [ { "S": "Animal" }, { "S": "Canine" }, { "S": "Dog" }, { "S": "German Shepherd" }, { "S": "Mammal" }, { "S": "Pet" }, { "S": "Collie" } ] }, "type": { "S": "image" } } ], "Count": 1, "ScannedCount": 1, "ConsumedCapacity": null }If the item still appears, try running the
scancommand after waiting for ten seconds. Sometimes, it takes a little bit of time for the Lambda function to get triggered. In the end, the table should only have thesample.jpgitem.