shiny spoon
a cloud-backed social platform built with flask and fastapi, featuring posts with image uploads, oauth login, dynamodb storage, s3 media, and a lambda-powered welcome email system
A full-stack social platform split across three repositories: a Flask frontend, a FastAPI backend, and an AWS Lambda function. Users can sign up or log in with Google and Facebook OAuth, create posts with image uploads, manage their profile, and browse the latest feed, with a Lambda-triggered welcome email on signup.
key features
- Social feed with latest posts and weather widget
- User authentication with session-based login
- Google and Facebook OAuth login
- Create, update, and delete posts with optional image uploads
- Profile image upload and account management
- Account deletion that deactivates posts and removes login
- S3 media pipeline with pre-signed URLs for secure image serving
- DynamoDB storage with composite keys and GSI for active post queries
- Lambda-triggered welcome email via Gmail API on signup
tech stack
# frontend
python | flask | jinja2 | wtforms | flask-wtf | requests
# backend
python | fastapi | boto3
# cloud
aws dynamodb | aws s3 | aws lambda
# auth & integrations
google oauth | facebook oauth | visual crossing weather api | gmail api
system architecture
The app runs across a full AWS stack with three main compute layers communicating over HTTP.
Requests from the internet hit Route 53 for DNS routing, then flow to Elastic Beanstalk which hosts the Flask frontend. Elastic Beanstalk handles SSL via Certificate Manager and manages Google and Facebook OAuth redirect flows. The Flask app communicates with the FastAPI backend through API Gateway, which routes requests to EC2. The FastAPI backend on EC2 runs as a Docker container pulled from Elastic Container Registry and owns all DynamoDB reads and writes, as well as S3 uploads and pre-signed URL generation for media. On signup, EC2 invokes a Lambda function which calls the Gmail API to send a welcome email.

system architecture diagram
api architecture
the FastAPI backend exposes endpoints across three groups.
/logins # create, read, update, delete logins in DynamoDB
/posts # create, read, update, delete posts in DynamoDB
/utilities # s3 uploads and pre-signed url generation
highlights
login, signup, home feed, and profile screens from the Flask app.

login page

sign up page

home page

user profile page
Building Shiny Spoon was my first time splitting a project into real separate services. Having a Flask app focused purely on UI and sessions, a FastAPI backend handling data and cloud operations, and a Lambda function for side effects made the separation of concerns concrete in a way that a monolith never does.
The most valuable backend lesson was modeling data in DynamoDB with partition and sort keys, and designing queries around access patterns rather than table structure. Serving images via pre-signed S3 URLs instead of public buckets was also a good early lesson in treating media as a secure resource. Triggering Lambda from the API and sending welcome emails via the Gmail API was my first end-to-end experience with event-driven cloud architecture.