cloudwithshad
๐ŸŒ
GROUP PROJECT ยท 1 WEEK ยท MINI-AWARDS

Akwaaba โ€” AI Tourism Guide

A web app where tourists upload a photo of any Ghanaian landmark, dish, or sign โ€” and get back what it is, why it matters, and an audio walkthrough in their own language. Built in groups. Deployed on EC2. Defended on demo day.

3-4
PER TEAM
1 week
TO BUILD
4 services
AWS USED
5
AWARDS
1
The vision โ€” what you're building
10 min

A tourist in Accra spots a building they've never seen before. They open Akwaaba on their phone, snap a photo, hit upload. In 10 seconds, the app tells them:

  • What it is โ€” "Kwame Nkrumah Mausoleum, built 1992"
  • Why it matters โ€” a paragraph of cultural and historical context
  • Audio narration โ€” natural-sounding voice reads the explanation aloud
  • Their language โ€” French, Twi, Spanish, Mandarin โ€” whichever they speak

This isn't a toy. Real tourism boards across Africa would pay for this. Your version will be the proof-of-concept that you can build it.

The bigger goal

By the end of this week, your team will have a live URL anyone can visit, a public GitHub repo employers can browse, and a 5-minute demo ready to pitch. This is what makes you stand out when applying for cloud roles.

2
Team roles โ€” who does what
15 min

Groups of 3-4 students. Every team needs these four roles covered. One person can wear two hats if you're only 3 โ€” but don't try to do everything yourself.

1. UI Lead
"The Designer"
  • Owns the Streamlit app's look and feel
  • Designs the photo upload + language picker UI
  • Picks fonts, colours, layout, animations
  • Handles loading states and error messages
2. AWS Engineer
"The Infrastructure"
  • Provisions EC2, S3 bucket, IAM role
  • Sets up security groups + SSH access
  • Configures the deployment pipeline
  • Owns the AWS bill โ€” keeps it free-tier
3. AI Engineer
"The Brains"
  • Wires up Rekognition for object detection
  • Wires up Polly for audio generation
  • Wires up Translate for multilingual output
  • Handles the boto3 SDK calls cleanly
4. Data & Story Lead
"The Curator"
  • Builds the CSV/JSON of landmarks + facts
  • Writes the cultural context paragraphs
  • Picks test photos for demo day
  • Owns the demo script + presentation
Pro team tip

Pick roles BEFORE you start coding. Make a 1-page contract: who owns what, what your daily standup time is, where you'll commit code (one shared GitHub repo). The teams that organize early are the teams that ship.

3
Architecture โ€” how it all fits together
15 min
Tourist uploads photo EC2 Instance Streamlit app Python ยท port 8501 boto3 SDK calls AWS S3 (uploads) ๐Ÿ“ท Rekognition ๐Ÿ—ฃ๏ธ Polly ๐ŸŒ Translate ๐Ÿ“š facts.csv curated content Response name + facts audio.mp3 translated text Tourist sees the page + listens to audio
Photo โ†’ EC2/Streamlit โ†’ Rekognition (what is it?) + Polly (audio) + Translate (their language) โ†’ tourist sees results.
ComponentWhat it does
EC2 (t2.micro)Hosts the Streamlit app on port 8501
S3 bucketStores user-uploaded photos (temporary)
RekognitionDetects what's in the photo โ€” labels + confidence scores
PollyConverts text descriptions into audio MP3
TranslateConverts English descriptions into 70+ languages
facts.csv (local)Your team's curated landmark + dish + sign data
4
Build it locally first (Streamlit basics)
3 hours

Always build locally before deploying. Get the app working on your laptop with mock data, THEN move it to AWS.

Set up the project structure:

mkdir akwaaba-app cd akwaaba-app python -m venv venv source venv/bin/activate # on Mac/Linux # venv\Scripts\activate on Windows pip install streamlit boto3 Pillow pandas

Create the main app file app.py:

import streamlit as st import boto3 import pandas as pd from PIL import Image import io # Page config st.set_page_config( page_title="Akwaaba ๐Ÿ‡ฌ๐Ÿ‡ญ", page_icon="๐ŸŒ", layout="wide" ) # Header st.title("๐ŸŒ Akwaaba โ€” Your AI Tourism Guide") st.markdown("_Snap a photo. Discover the story._") # Sidebar โ€” language picker with st.sidebar: st.header("โš™๏ธ Settings") language = st.selectbox( "Tell me in...", ["English", "French", "Spanish", "Twi", "Mandarin"] ) st.divider() st.caption("Built by Team [YOUR-TEAM-NAME] ยท cloudwithshad bootcamp") # Main column โ€” photo upload uploaded = st.file_uploader( "Drop a photo of any Ghanaian landmark, dish, or sign", type=["jpg", "jpeg", "png"] ) if uploaded: img = Image.open(uploaded) col1, col2 = st.columns([1, 1]) with col1: st.image(img, caption="Your photo", use_container_width=True) with col2: with st.spinner("Analyzing..."): # MVP โ€” mock response. Real AWS calls in Step 5. st.success("### ๐Ÿ“ Kwame Nkrumah Mausoleum") st.write("Built in 1992, this monument honours Ghana's first president...")

Run it locally:

streamlit run app.py

Your browser opens at http://localhost:8501 with a working app. Polish the look, add your team's colour scheme, then move to Step 5.

UI Lead's playground

This is where the UI Lead really shines. Use st.columns(), st.tabs(), custom CSS via st.markdown(unsafe_allow_html=True). Look at streamlit.io/gallery for inspiration โ€” copy patterns shamelessly, make them yours.

5
Wire up AWS services (Rekognition + Polly + Translate)
4 hours

Time for the AI Engineer to shine. Replace the mock response with real AWS calls.

AWS credentials setup

Install AWS CLI locally and run aws configure with the IAM access keys from your AWS Engineer. (For EC2 deployment in Step 6, we'll use an IAM role instead โ€” much safer.)

The AWS helper module

Create aws_services.py:

import boto3 import io rekognition = boto3.client('rekognition', region_name='us-east-1') polly = boto3.client('polly', region_name='us-east-1') translate = boto3.client('translate', region_name='us-east-1') def detect_labels(image_bytes): """Returns top labels for an image with confidence scores.""" response = rekognition.detect_labels( Image={'Bytes': image_bytes}, MaxLabels=10, MinConfidence=70 ) return [(l['Name'], l['Confidence']) for l in response['Labels']] def text_to_audio(text, voice='Aria', language='en-US'): """Converts text to MP3 audio using Polly.""" # Voice mapping โ€” different voices for different languages voice_map = { 'English': ('Aria', 'en-US'), 'French': ('Lea', 'fr-FR'), 'Spanish': ('Lupe', 'es-US'), 'Mandarin': ('Zhiyu', 'cmn-CN'), } voice, lang = voice_map.get(language, ('Aria', 'en-US')) response = polly.synthesize_speech( Text=text, OutputFormat='mp3', VoiceId=voice, Engine='neural', LanguageCode=lang ) return response['AudioStream'].read() def translate_text(text, target_lang='en'): """Translates text to target language.""" lang_codes = { 'French': 'fr', 'Spanish': 'es', 'Mandarin': 'zh', 'Twi': 'tw' } if target_lang == 'English': return text target = lang_codes.get(target_lang, 'en') response = translate.translate_text( Text=text, SourceLanguageCode='en', TargetLanguageCode=target ) return response['TranslatedText']

The data file

The Data & Story Lead curates facts.csv. Format:

keyword,name,context,year mausoleum,Kwame Nkrumah Mausoleum,Built in 1992 to honour Ghana's first president and the architect of Pan-Africanism. The black granite obelisk symbolises eternal remembrance.,1992 slave,Cape Coast Castle,A UNESCO World Heritage Site. Once a hub of the trans-Atlantic slave trade. Now a museum that confronts that history with dignity and education.,1653 food,Jollof Rice,A West African staple. Tomato-based rice cooked with spices and often paired with grilled chicken or beef. Ghana and Nigeria have a friendly rivalry over whose version reigns supreme.,โ€” kente,Kente Cloth,Handwoven silk and cotton from the Ashanti and Ewe people. Every colour and pattern carries meaning. The most famous African textile in the world.,1700s

Then in your app.py, replace the mock response with real calls. Pseudocode:

  1. User uploads photo โ†’ convert to bytes
  2. Call detect_labels() โ†’ get top labels (e.g., "Building", "Monument", "Statue")
  3. Match label keywords against facts.csv โ†’ grab the matching cultural context
  4. If language โ‰  English โ†’ call translate_text() on the context
  5. Call text_to_audio() on the (translated) context
  6. Display: the labels, the context, and an st.audio() player
Hint: matching Rekognition labels to your facts.csv

Rekognition returns generic labels like "Building" or "Monument" โ€” not "Kwame Nkrumah Mausoleum". Your matching strategy:

(1) Check if any label keyword is in your CSV. (2) If not, fall back to the highest-confidence label. (3) Always have a graceful default: "We see something interesting! We don't have detailed facts yet, but here's what we detected: [labels]."

Make your CSV richer over the week โ€” the more landmarks, dishes, and signs you catalogue, the smarter the app appears.

6
Deploy to EC2 (the AWS Engineer's moment)
3 hours

Now the AWS Engineer takes the helm. Launch an EC2 instance similar to Week 1 Lab 2, but a bit more configured.

Launch the EC2 instance

SettingValue
Nameakwaaba-app
AMIAmazon Linux 2023
Instance typet2.micro (free tier) โ€” or t3.small if budget allows for faster boots
Key pairReuse from Week 1, or create new
Security groupAllow SSH (22) from your IP + HTTP (80) + custom TCP (8501) from anywhere
IAM roleCreate new role with: RekognitionFullAccess, PollyFullAccess, TranslateFullAccess, S3 ReadOnly
CRITICAL โ€” use an IAM role, not access keys

Do NOT copy your AWS access keys onto the EC2 instance. Instead, attach an IAM role at launch (in Advanced details โ†’ IAM instance profile). Then boto3 picks up credentials automatically. This is the production-correct pattern.

SSH in and install everything

From your laptop:

ssh -i your-key.pem ec2-user@<EC2-PUBLIC-IP>

Then on the EC2 instance:

sudo yum update -y sudo yum install -y git python3-pip pip3 install streamlit boto3 Pillow pandas # Clone your team repo git clone https://github.com/YOUR-TEAM/akwaaba-app.git cd akwaaba-app # Test locally first (Ctrl+C when you've confirmed it starts) streamlit run app.py --server.port 8501 --server.address 0.0.0.0

Now visit http://<EC2-PUBLIC-IP>:8501 in your browser. You should see your Streamlit app live on the internet!

Keep it running after you SSH out

The app dies when you close SSH. Run it as a background service:

# Quick fix โ€” run with nohup, survives SSH disconnect nohup streamlit run app.py --server.port 8501 --server.address 0.0.0.0 & # Better โ€” create a systemd service. Create /etc/systemd/system/akwaaba.service: # [Unit] # Description=Akwaaba Streamlit App # After=network.target # # [Service] # User=ec2-user # WorkingDirectory=/home/ec2-user/akwaaba-app # ExecStart=/usr/local/bin/streamlit run app.py --server.port 8501 --server.address 0.0.0.0 # Restart=always # # [Install] # WantedBy=multi-user.target sudo systemctl enable akwaaba sudo systemctl start akwaaba
Hint: I want a real domain, not an EC2 IP

Buy a cheap domain from Namecheap (~$10/year). Set up an A record pointing to your EC2's Elastic IP (free if attached to a running instance). For HTTPS, run nginx as a reverse proxy on port 80/443 and use Let's Encrypt's certbot for a free SSL cert. This takes another 2 hours but turns your demo URL into akwaaba.your-team-name.com โ€” much more impressive for the demo.

7
Polish โ€” what separates good from great
3-4 hours

The technical part is done. Now is when the project goes from "it works" to "judges remember this one". This is what wins awards.

UI polish (UI Lead)

  • Custom Streamlit theme using .streamlit/config.toml โ€” match the kente palette (gold, green, terracotta)
  • Add a hero image at the top โ€” a beautiful Ghana photo (Adinkra symbols work well)
  • Loading animations during AI calls โ€” st.spinner with custom messages ("Reading the photo... consulting our cultural archives...")
  • An "About" tab explaining who you are + how it works
  • Mobile-friendly: test on your phone over the EC2 IP

Data polish (Data & Story Lead)

  • At least 15-20 landmarks/dishes/signs in your CSV โ€” depth matters
  • Each context paragraph: 50-80 words โ€” readable, factual, with a touch of warmth
  • Pick 5-8 demo photos ahead of time, test that they all work flawlessly
  • Cover the iconic ones: Cape Coast Castle, Independence Arch, Larabanga Mosque, Lake Volta, Mole National Park

Architecture polish (AWS Engineer)

  • Add a billing alarm at $5 โ€” peace of mind
  • Set up CloudWatch logs from your Streamlit app โ€” useful if something breaks during demo
  • Add the AWS architecture diagram to your README (use draw.io or AWS's own diagram tool)

Story polish (Data & Story Lead)

  • Write a great README.md โ€” the first thing employers see on GitHub
  • Add screenshots, the architecture diagram, and a "Try it live" link
  • List the team members + their roles + their LinkedIn URLs
The 1% that wins

Every team will have a working app. The award winners are the teams who put 3 extra hours into polish: a beautiful loading animation, a thoughtful README, demo photos chosen with care, a kente-coloured theme that feels uniquely Ghanaian. Judges remember details.

8
Demo day โ€” your 5 minutes to shine
2 hours rehearsal

Each team gets 5 minutes to present + 3 minutes for Q&A. That's it. Make every second count.

๐ŸŽฌ The winning 5-minute structure

  • 00:00 โ€” 00:30 ยท The problem. One sentence. "Tourists visiting Ghana often don't know what they're looking at โ€” and tour guides aren't always available." Don't start with "Hi we are team X".
  • 00:30 โ€” 01:00 ยท The team. Names, roles, what each person owned. Quick. Build credibility.
  • 01:00 โ€” 02:30 ยท The live demo. Upload a photo, switch languages, hit play on the audio. THIS is the moment. Practice it 10 times.
  • 02:30 โ€” 03:30 ยท The architecture. Show your diagram. Say: "We used Rekognition for vision, Polly for audio, Translate for languages, all hosted on EC2." Sound senior.
  • 03:30 โ€” 04:30 ยท The hard parts. What was tricky? What did you figure out? Judges LOVE this โ€” it shows depth.
  • 04:30 โ€” 05:00 ยท What's next. "If we had another week, we'd add..." Show vision.
Demo day landmines

Always have a backup video of your app working โ€” in case the EC2 instance hiccups, the wifi dies, or AWS has an outage. Record a 60-second screen recording the night before. If anything fails, you smile and say "here's a recording from earlier" and keep going.

Final submission package

Drop this in the cohort WhatsApp group 24 hours before demo day:

  • Live EC2 URL (judges will visit)
  • GitHub repo link
  • Team name + member names
  • 30-second demo video (backup if EC2 fails)
๐Ÿ†
The 5 awards (mini-trophies + bragging rights)

Every team gets feedback. Top teams win one of these 5 awards. Aim for at least one โ€” none are technical perfection alone.

๐ŸŽจ
Most Polished

The app that looks and feels like a real product. Beautiful UI, thoughtful animations, mobile-friendly, kente-themed.

๐Ÿ’ก
Most Innovative

The team that took the brief and added something unexpected. Maybe AR overlays, maybe a chat interface, maybe gamification.

๐ŸŽค
Best Demo

The most compelling 5-minute presentation. Clear story, smooth live demo, confident speakers, audience engagement.

๐Ÿ“š
Best Documentation

The repo a hiring manager would clone. Stunning README, clear architecture diagram, proper team credits, easy setup instructions.

โค๏ธ
People's Choice

Voted by the cohort. The project everyone wishes they'd built โ€” the one that would genuinely help real tourists.

๐Ÿ‡ฌ๐Ÿ‡ญ

You're building Ghana's first AI tourism app.

This isn't just a bootcamp project. It's the kind of thing that wins tourism board grants, gets picked up by local startups, and shows up on your GitHub when employers Google you. Build it like it matters โ€” because it does.

Akwaaba. Welcome to building.