translator / app.py
danielle2003's picture
Create app.py
d117f2c verified
import streamlit as st
from streamlit_webrtc import webrtc_streamer, VideoProcessorBase, RTCConfiguration
import av
import cv2
from pyzbar import pyzbar
import google.generativeai as genai
from google.generativeai import protos
import threading
import time
import json
import re
from google import genai
from google.genai import types
# ----------------------------
# App Configuration
# ----------------------------
st.set_page_config(
page_title="Real-Time Drug Code Verifier",
page_icon="πŸ”",
layout="wide"
)
# ----------------------------
# API Key Setup
# ----------------------------
# It's recommended to use st.secrets for API keys in a deployed app
GOOGLE_API_KEY = "AIzaSyAXFL0YdFIKUNISOQuV9FH-JTSnMC3PSMA"
# Load key from secrets
try:
if not GOOGLE_API_KEY:
GOOGLE_API_KEY = st.secrets["GOOGLE_API_KEY"]
except (FileNotFoundError, KeyError):
st.error("πŸ”‘ GOOGLE_API_KEY not found. Please add it to your Streamlit secrets.")
st.stop()
#.configure(api_key=GOOGLE_API_KEY)
client = genai.Client(api_key=GOOGLE_API_KEY)
# Define the grounding tool
grounding_tool = types.Tool(
google_search=types.GoogleSearch()
)
# Configure generation settings
config = types.GenerateContentConfig(
tools=[grounding_tool]
)
# ----------------------------
# Main Gemini Verification Function
# ----------------------------
@st.cache_data(show_spinner=False)
def verify_code_with_gemini(code: str, barcode_type: str):
"""
Verifies a product code by letting Gemini use its native Google Search tool.
"""
# Define the built-in Google Search tool using the specific syntax required by the library
prompt = f"""
You are a product verification assistant. A user has scanned a product with the code '{code}' (type: {barcode_type}).
Your goal is to use your built-in Google Search tool to augment your own knowledge and provide a comprehensive analysis.
Follow these steps:
1. Use your search tool to find information about the provided barcode and product type. This will give you real-time context.
2. Combine the information from the web search with your own general knowledge about products, manufacturers, and barcode standards.
3. Provide a detailed summary. This should include the likely product name, manufacturer, and a well-reasoned assessment of the code's authenticity. If the search results are inconclusive or suspicious, use your own knowledge to explain why (e.g., "This barcode format is unusual for this type of product," or "No major retailers list this code, which is suspicious.").
4. From the search results, find the best, most representative image URL for the product. If no good image is found, return an empty string.
5. IMPORTANT: Your final output MUST be ONLY the raw JSON object. Do not include ```json``` markers or any other explanatory text.
Example Output:
{{
"summary_text": "This EAN-13 code corresponds to 'Product Name' by 'Manufacturer'. The code format is valid and listed by several major retailers in the search results, suggesting it is authentic. No recalls or warnings were found.",
"image_url": "https://example.com/product_image.jpg"
}}
"""
response = None # Initialize response to None
try:
st.write("🧠 Generating content with Gemini and Google Search...")
response = client.models.generate_content(
model="gemini-2.5-flash",
contents=prompt,
config=config,
)
st.write("βœ… Gemini response received. Parsing JSON...")
# Extract JSON from the response text, which might be wrapped in markdown
raw_text = response.text
json_match = re.search(r'\{.*\}', raw_text, re.DOTALL)
if json_match:
json_str = json_match.group(0)
result_data = json.loads(json_str)
st.write("πŸ‘ JSON parsed successfully!")
return result_data
else:
st.write("❌ No JSON object found in the response.")
return {
"summary_text": "Verification failed: The AI did not return a valid JSON object.",
"image_url": "",
"raw_response": raw_text
}
except Exception as e:
st.write(f"❌ An error occurred: {e}")
raw_response_text = response.text if response else "No response from model."
return {
"summary_text": f"An error occurred during verification. Please check the details below.",
"image_url": "",
"error_details": str(e),
"raw_response": raw_response_text
}
# ----------------------------
# Video Processing Class
# ----------------------------
class QRCodeScanner(VideoProcessorBase):
def __init__(self):
self.result = None
self.lock = threading.Lock()
def recv(self, frame: av.VideoFrame) -> av.VideoFrame:
image = frame.to_ndarray(format="bgr24")
decoded_objects = pyzbar.decode(image)
for obj in decoded_objects:
code_data = obj.data.decode("utf-8")
code_type = obj.type
with self.lock:
self.result = {"data": code_data, "type": code_type}
(x, y, w, h) = obj.rect
cv2.rectangle(image, (x, y), (x + w, y + h), (0, 255, 0), 2)
text = f"Detected: {code_data}"
cv2.putText(image, text, (x, y - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 255, 0), 2)
break
return av.VideoFrame.from_ndarray(image, format="bgr24")
# ----------------------------
# Streamlit UI
# ----------------------------
st.title("πŸ” Real-Time Drug Code Verifier with AI Search")
st.markdown("Point a product's barcode or QR code at the camera. The app will use Gemini AI with Google Search to verify its authenticity.")
if "code_found" not in st.session_state:
st.session_state.update({"code_found": False, "last_code_data": "", "last_code_type": ""})
if not st.session_state["code_found"]:
st.subheader("πŸ“· Camera Feed")
webrtc_ctx = webrtc_streamer(
key="scanner",
video_processor_factory=QRCodeScanner,
rtc_configuration=RTCConfiguration({"iceServers": [{"urls": ["stun:stun.l.google.com:19302"]}]}),
media_stream_constraints={"video": True, "audio": False},
async_processing=True,
)
st.info("The camera will stop automatically once a code is detected.")
if webrtc_ctx.video_processor:
while True:
with webrtc_ctx.video_processor.lock:
result = webrtc_ctx.video_processor.result
if result:
st.session_state.update(code_found=True, last_code_data=result["data"], last_code_type=result["type"])
st.rerun()
time.sleep(0.2)
else:
st.success("βœ… Code captured successfully! The camera has been turned off.")
col1, col2 = st.columns([1, 2])
with col1:
st.subheader("πŸ“¦ Detected Code")
st.code(f"Data: {st.session_state['last_code_data']}\nType: {st.session_state['last_code_type']}", language="text")
if st.button("πŸ”„ Scan Another Product"):
st.session_state.update({"code_found": False, "last_code_data": "", "last_code_type": ""})
st.rerun()
with col2:
st.subheader("πŸ€– Gemini AI Verification")
with st.spinner("πŸ” Using Gemini with Google Search to verify..."):
verification_result = verify_code_with_gemini(
st.session_state['last_code_data'],
st.session_state['last_code_type']
)
# Display the summary text
st.info(verification_result.get("summary_text", "No summary available."))
# Display the image if a URL was found
image_url = verification_result.get("image_url")
if image_url:
st.image(image_url, caption="Product Image (from web search)")
# Display error details if they exist
if "error_details" in verification_result:
st.error("An error occurred during verification:")
st.code(f"Error: {verification_result['error_details']}\n\nRaw AI Response:\n{verification_result['raw_response']}", language="text")