tdurzynski commited on
Commit
8bb74bc
Β·
verified Β·
1 Parent(s): 8f31dd0

Update app.py

Browse files

πŸ”Ή Features of this Implementation
βœ… Firebase Authentication (Email & Password)
βœ… AWS S3 Storage for Uploaded Images
βœ… DynamoDB Metadata Storage
βœ… Securely Fetch Secrets from HF Secrets
βœ… Token-based Reward System

Files changed (1) hide show
  1. app.py +110 -32
app.py CHANGED
@@ -1,65 +1,143 @@
1
  import streamlit as st
2
- import requests
3
- import base64
4
  import io
 
 
5
  import time
6
  from PIL import Image
7
- import random
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8
 
9
- # Initialize session state for tokens
 
 
 
 
 
 
 
10
  if "tokens" not in st.session_state:
11
  st.session_state.tokens = 0
 
 
12
 
13
- # Page title
14
  st.title("πŸ“· Food Crowdsourcing Research App")
15
-
16
  st.write("Help our research by uploading food images! Earn tokens for future app use.")
17
 
18
- # Upload image
19
- uploaded_file = st.file_uploader("Upload a food image", type=["jpg", "png", "jpeg"])
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
20
 
21
- # Terms and Conditions
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
22
  st.markdown("### **Terms & Conditions**")
23
  st.write(
24
  "By uploading an image, you agree to transfer full copyright to the research team for AI training purposes. "
25
  "You are responsible for ensuring you own the image and it does not violate any copyright laws. "
26
- "We do not guarantee when tokens will be redeemable. Keep track of your user ID.")
 
27
  st.checkbox("I agree to the terms and conditions", key="terms_accepted")
28
 
29
- # Process image
30
  if uploaded_file and st.session_state.terms_accepted:
31
  image = Image.open(uploaded_file)
32
  st.image(image, caption="Uploaded Image", use_column_width=True)
33
 
34
- # Show original size
35
- st.write(f"Original size: {image.size}")
36
-
37
  # Convert PNG to JPEG if needed
38
  if image.format == "PNG":
39
  image = image.convert("RGB")
40
-
41
  # Resize image to max 1024x1024 px
42
  MAX_SIZE = (1024, 1024)
43
  image.thumbnail(MAX_SIZE)
44
-
45
- # Convert image to bytes
46
  img_bytes = io.BytesIO()
47
  image.save(img_bytes, format="JPEG", quality=80) # Reduce quality to save space
48
  img_bytes.seek(0)
49
-
50
- # Show resized size
51
- st.write(f"New size: {image.size}")
52
-
53
- # Upload to S3 (Simulated API Call)
54
- # response = requests.post("YOUR_BACKEND_API/upload", files={"file": img_bytes.getvalue()})
55
-
56
- # Token rewards system
57
- st.session_state.tokens += 1 # 1 Token for uploading
58
- st.write("βœ… You earned **1 token** for uploading!")
59
-
60
- # Future: Add annotation for an extra token
61
- # st.session_state.tokens += 1 # If annotation is provided
62
-
63
- st.success(f"Total tokens: {st.session_state.tokens}")
64
 
 
 
 
 
 
 
 
 
 
 
 
 
65
 
 
 
 
 
 
 
 
1
  import streamlit as st
2
+ import json
3
+ import os
4
  import io
5
+ import base64
6
+ import boto3
7
  import time
8
  from PIL import Image
9
+ import firebase_admin
10
+ from firebase_admin import credentials, auth, firestore
11
+
12
+ # πŸš€ Load Secrets from Hugging Face Secrets
13
+ FIREBASE_CONFIG = json.loads(os.getenv("FIREBASE_CONFIG", "{}"))
14
+ AWS_ACCESS_KEY = os.getenv("AWS_ACCESS_KEY")
15
+ AWS_SECRET_KEY = os.getenv("AWS_SECRET_KEY")
16
+ S3_BUCKET_NAME = os.getenv("S3_BUCKET_NAME", "food-image-crowdsourcing")
17
+ DYNAMODB_TABLE = os.getenv("DYNAMODB_TABLE", "FoodMetadata")
18
+
19
+ # βœ… Initialize Firebase Admin SDK
20
+ if FIREBASE_CONFIG:
21
+ cred = credentials.Certificate(FIREBASE_CONFIG)
22
+ firebase_admin.initialize_app(cred)
23
+ else:
24
+ st.error("⚠️ Firebase configuration is missing! Please check HF Secrets.")
25
+
26
+ # βœ… Initialize AWS Services (S3 & DynamoDB)
27
+ s3 = boto3.client(
28
+ "s3",
29
+ aws_access_key_id=AWS_ACCESS_KEY,
30
+ aws_secret_access_key=AWS_SECRET_KEY,
31
+ )
32
 
33
+ dynamodb = boto3.resource(
34
+ "dynamodb",
35
+ aws_access_key_id=AWS_ACCESS_KEY,
36
+ aws_secret_access_key=AWS_SECRET_KEY,
37
+ )
38
+ metadata_table = dynamodb.Table(DYNAMODB_TABLE)
39
+
40
+ # πŸ”Ή Initialize Session State for Tokens
41
  if "tokens" not in st.session_state:
42
  st.session_state.tokens = 0
43
+ if "user_email" not in st.session_state:
44
+ st.session_state.user_email = None
45
 
46
+ # πŸ”Ή UI - Page Title
47
  st.title("πŸ“· Food Crowdsourcing Research App")
 
48
  st.write("Help our research by uploading food images! Earn tokens for future app use.")
49
 
50
+ # βœ… **User Authentication Section**
51
+ st.sidebar.header("πŸ”‘ User Authentication")
52
+
53
+ auth_choice = st.sidebar.radio("Select an option", ["Login", "Sign Up", "Logout"])
54
+
55
+ if auth_choice == "Sign Up":
56
+ with st.sidebar.form("signup_form"):
57
+ email = st.text_input("Email")
58
+ password = st.text_input("Password", type="password")
59
+ submit_button = st.form_submit_button("Sign Up")
60
+
61
+ if submit_button:
62
+ try:
63
+ user = auth.create_user(email=email, password=password)
64
+ st.success(f"βœ… Account created! Now login with {email}.")
65
+ except Exception as e:
66
+ st.error(f"⚠️ {str(e)}")
67
 
68
+ if auth_choice == "Login":
69
+ with st.sidebar.form("login_form"):
70
+ email = st.text_input("Email")
71
+ password = st.text_input("Password", type="password")
72
+ submit_button = st.form_submit_button("Login")
73
+
74
+ if submit_button:
75
+ try:
76
+ user = auth.get_user_by_email(email)
77
+ st.session_state.user_email = email
78
+ st.success(f"βœ… Welcome back, {email}!")
79
+ except Exception as e:
80
+ st.error(f"⚠️ {str(e)}")
81
+
82
+ if auth_choice == "Logout":
83
+ if st.session_state.user_email:
84
+ st.session_state.user_email = None
85
+ st.success("βœ… Logged out successfully!")
86
+
87
+ # πŸ”Ή **Ensure User is Logged In**
88
+ if not st.session_state.user_email:
89
+ st.warning("⚠️ Please log in to upload images.")
90
+ st.stop()
91
+
92
+ # βœ… **Image Upload Section**
93
+ uploaded_file = st.file_uploader("πŸ“Έ Upload a food image", type=["jpg", "png", "jpeg"])
94
+
95
+ # βœ… **Terms & Conditions**
96
  st.markdown("### **Terms & Conditions**")
97
  st.write(
98
  "By uploading an image, you agree to transfer full copyright to the research team for AI training purposes. "
99
  "You are responsible for ensuring you own the image and it does not violate any copyright laws. "
100
+ "We do not guarantee when tokens will be redeemable. Keep track of your user ID."
101
+ )
102
  st.checkbox("I agree to the terms and conditions", key="terms_accepted")
103
 
104
+ # βœ… **Process and Upload Image**
105
  if uploaded_file and st.session_state.terms_accepted:
106
  image = Image.open(uploaded_file)
107
  st.image(image, caption="Uploaded Image", use_column_width=True)
108
 
109
+ # Show Original Size
110
+ st.write(f"πŸ“ Original size: {image.size}")
111
+
112
  # Convert PNG to JPEG if needed
113
  if image.format == "PNG":
114
  image = image.convert("RGB")
115
+
116
  # Resize image to max 1024x1024 px
117
  MAX_SIZE = (1024, 1024)
118
  image.thumbnail(MAX_SIZE)
119
+
120
+ # Convert Image to Bytes
121
  img_bytes = io.BytesIO()
122
  image.save(img_bytes, format="JPEG", quality=80) # Reduce quality to save space
123
  img_bytes.seek(0)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
124
 
125
+ # πŸ”Ή Generate Unique File Name
126
+ file_name = f"raw-uploads/{st.session_state.user_email}_{int(time.time())}.jpg"
127
+
128
+ # βœ… **Upload to S3**
129
+ try:
130
+ s3.put_object(
131
+ Bucket=S3_BUCKET_NAME,
132
+ Key=file_name,
133
+ Body=img_bytes.getvalue(),
134
+ ContentType="image/jpeg",
135
+ )
136
+ st.success("βœ… Image uploaded successfully to S3!")
137
 
138
+ # βœ… **Store Metadata in DynamoDB**
139
+ metadata_table.put_item(
140
+ Item={
141
+ "user_email": st.session_state.user_email,
142
+ "file_name": file_name,
143
+ "