import streamlit as st import requests import json from PIL import Image import io import base64 from datetime import datetime import pandas as pd import plotly.express as px # Configure the app st.set_page_config( page_title="IndiScan - Product Health Analyzer", page_icon="🔍", layout="wide" ) # API endpoint API_URL = "http://localhost:8000" # Change this when deploying def main(): # Sidebar st.sidebar.title("IndiScan 🔍") scan_option = st.sidebar.radio( "Choose scan method:", ["Barcode", "Image Upload", "Manual Entry"] ) # Main content st.title("IndiScan - Product Health Analyzer") st.markdown(""" Analyze food and cosmetic products for health risks and get detailed insights. Upload an image, enter a barcode, or manually input product details. """) # Admin section in sidebar with st.sidebar.expander("Admin Controls 🔐"): admin_username = st.text_input("Username") admin_password = st.text_input("Password", type="password") if st.button("Login"): try: auth = (admin_username, admin_password) response = requests.get(f"{API_URL}/export", auth=auth) if response.status_code == 200: st.sidebar.success("Logged in as admin") st.session_state['admin_auth'] = auth else: st.sidebar.error("Invalid credentials") except Exception as e: st.sidebar.error(f"Login failed: {str(e)}") # Main content based on selected option if scan_option == "Barcode": barcode_scanner() elif scan_option == "Image Upload": image_scanner() else: manual_entry() def barcode_scanner(): st.header("Barcode Scanner 📱") barcode = st.text_input("Enter barcode number:") if barcode: try: response = requests.post(f"{API_URL}/scan/barcode", params={"barcode": barcode}) if response.status_code == 200: display_results(response.json()) else: st.error("Product not found") except Exception as e: st.error(f"Error: {str(e)}") def image_scanner(): st.header("Image Scanner 📸") uploaded_file = st.file_uploader("Upload product image", type=["jpg", "jpeg", "png"]) if uploaded_file: try: # Display uploaded image image = Image.open(uploaded_file) st.image(image, caption="Uploaded Image", use_column_width=True) # Process image files = {"file": uploaded_file} response = requests.post(f"{API_URL}/scan/image", files=files) if response.status_code == 200: display_results(response.json()) else: st.error("Failed to process image") except Exception as e: st.error(f"Error: {str(e)}") def manual_entry(): st.header("Manual Entry ✍️") col1, col2 = st.columns(2) with col1: product_type = st.selectbox("Product Type", ["Food", "Cosmetic"]) ingredients_text = st.text_area("Enter ingredients list (comma-separated or as shown on package):") with col2: if ingredients_text: try: response = requests.post( f"{API_URL}/analyze/text", data={ "text": ingredients_text, "product_type": product_type.lower() } ) if response.status_code == 200: display_results(response.json()) else: st.error("Failed to analyze ingredients") except Exception as e: st.error(f"Error: {str(e)}") def display_results(data): # Create three columns for different aspects of the analysis col1, col2, col3 = st.columns([2, 2, 1]) with col1: st.subheader("Health Score") score = data.get('health_score', {}).get('score', 0) # Create a gauge chart using plotly fig = px.pie( values=[score, 1000-score], names=['Score', 'Remaining'], hole=0.7, color_discrete_sequence=['#00ff00' if score > 600 else '#ff0000', '#eee'] ) fig.update_layout( annotations=[dict(text=f"{score}/1000", x=0.5, y=0.5, font_size=20, showarrow=False)], showlegend=False, width=300, height=300 ) st.plotly_chart(fig) # Display explanation if 'explanation' in data.get('health_score', {}): st.markdown(data['health_score']['explanation']) with col2: st.subheader("Ingredients Analysis") if 'ingredients' in data: ingredients = data['ingredients'] st.write(f"Found {len(ingredients)} ingredients:") for i, ingredient in enumerate(ingredients, 1): st.write(f"{i}. {ingredient}") # Display risks if available if 'risks' in data.get('health_score', {}): st.subheader("Risk Categories") risks = data['health_score']['risks'] for category, risk_data in risks.items(): with st.expander(f"{category.replace('_', ' ').title()}"): st.write(f"Found in: {', '.join(risk_data['ingredients'])}") with col3: if 'nutrition_info' in data: st.subheader("Nutrition Info") nutrition = data['nutrition_info'] for nutrient, value in nutrition.items(): st.metric(nutrient.title(), f"{value}g") if 'nutrition_analysis' in data: analysis = data['nutrition_analysis'] if analysis['concerns']: st.subheader("⚠️ Concerns") for concern in analysis['concerns']: st.write(f"- {concern}") if analysis['positives']: st.subheader("✅ Positives") for positive in analysis['positives']: st.write(f"- {positive}") if analysis['recommendations']: st.subheader("💡 Recommendations") for rec in analysis['recommendations']: st.write(f"- {rec}") # Price comparison if available if 'prices' in data: st.subheader("Price Comparison") prices_df = pd.DataFrame(data['prices']) fig = px.bar( prices_df, x='platform', y='price', title="Price Comparison Across Platforms", color='platform' ) st.plotly_chart(fig) # Display price table st.dataframe( prices_df[['platform', 'price', 'title', 'url']], column_config={ "url": st.column_config.LinkColumn("Link") } ) if __name__ == "__main__": main()