<HC />
Back to Projects
Cloud & Serverless ArchitectureCompleted

Bloomkeeper — AWS Flower Detection App

A cloud-native flower identification and speech synthesis platform built on AWS serverless architecture using Amazon Rekognition label detection, Amazon Polly text-to-speech, direct S3 presigned URL uploads, and an event-driven Lambda pipeline.

AWS LambdaAmazon RekognitionAmazon PollyAWS API GatewayAWS S3AWS DynamoDBAWS EC2PythonFlaskGunicornboto3HTML5CSS3JavaScript

Screenshots

Bloomkeeper — AWS Flower Detection App — Field Journal Home Interface
Field Journal Home Interface

Key Metrics

Event-Driven Serverless Pipeline

ap-south-1

Amazon Polly MP3

Direct S3 Presigned PUT URL

Automated Resumable boto3 Scripts

Overview

Bloomkeeper is a cloud-native flower detection application that identifies flowers from photos, synthesizes the detected flower name into speech with Amazon Polly, and returns audio results to users. The system features a mobile field-journal UI on EC2, direct browser-to-S3 uploads via presigned URLs, an asynchronous S3-triggered processing Lambda, Amazon Rekognition label detection, and DynamoDB persistence.

Problem

Routing heavy image uploads and audio synthesis through application servers creates severe bandwidth bottlenecks, high server compute overhead, and tight coupling between upload success and downstream AI processing.

Solution

Architected an event-driven AWS serverless pipeline where the browser uploads raw image bytes directly to private S3 storage using presigned URLs. The upload triggers an asynchronous S3 ObjectCreated event Lambda that invokes Rekognition for label filtering, Polly for voice synthesis, and DynamoDB for status persistence, allowing client polling without EC2 overhead.

Architecture

Hybrid EC2 and serverless architecture in ap-south-1. A lightweight Flask app on EC2 (with zero AWS IAM permissions) serves the mobile UI. The browser requests presigned S3 PUT URLs from API Gateway (get_upload_url), uploads raw images directly to S3, and triggers an S3 ObjectCreated event Lambda (process_image). Lambda calls Rekognition DetectLabels, synthesizes an MP3 via Polly, saves audio to audio/<id>.mp3, and writes detection state to DynamoDB. The browser polls get_result for presigned MP3 playback URLs and fetches history via list_history.

Challenges

  • Implementing direct browser-to-S3 uploads with presigned PUT URLs to avoid routing image bytes through Flask or API Gateway request limits.
  • Decoupling upload completion from multi-service AI processing (Rekognition + Polly + DynamoDB) using asynchronous S3 events and client status polling.
  • Filtering generic Amazon Rekognition computer vision labels toward domain-specific botanical and flower classifications.
  • Orchestrating automated, idempotent, and resumable AWS infrastructure provisioning (deploy.py) and teardown (cleanup.py) using boto3.
  • Isolating the EC2 frontend server from AWS IAM permissions by enforcing direct client-to-API Gateway communication.

Lessons Learned

  • Direct browser-to-S3 object storage patterns using presigned URLs.
  • Event-driven asynchronous Lambda execution triggered by S3 object creation.
  • Text-to-speech audio synthesis integration using Amazon Polly.
  • Decoupled serverless microservice design across 4 specialized Lambda functions.
  • State management and asynchronous status polling patterns in NoSQL (DynamoDB).
  • Zero-trust frontend architecture keeping EC2 instances isolated from AWS IAM privileges.

Future Improvements

  • Migration of generic Rekognition label detection to a custom Rekognition Custom Labels botanical model for high-accuracy species identification.
  • Serverless frontend hosting on AWS S3 + CloudFront CDN to eliminate EC2 server hosting costs.
  • Real-time client updates using WebSockets or Server-Sent Events (SSE) instead of HTTP polling.
  • HTTPS enforcement and native getUserMedia live camera stream integration.
  • Automated S3 asset lifecycle expiration rules to prune old captures and audio files.