Spaces:
Runtime error
Runtime error
| #Imports | |
| import os | |
| import tempfile | |
| import streamlit as st | |
| from PIL import Image | |
| # from main import analyze_media, process_with_blip | |
| from main import analyze_media | |
| #import openai | |
| import io | |
| import zipfile | |
| # Initialize OpenAI API | |
| # from dotenv import load_dotenv | |
| # load_dotenv() | |
| # api_key = os.getenv("OPENAI_API_KEY") | |
| # openai.api_key = api_key | |
| # --- Streamlit Setup --- | |
| st.set_page_config(layout="wide", page_title="Vision Sort") | |
| st.sidebar.header("Configuration") | |
| # --- Sidebar Config --- | |
| min_confidence = st.sidebar.number_input("Confidence Threshold", min_value=0, max_value=100, value=25, step=1) | |
| borderline_min = st.sidebar.number_input("Borderline Minimum", min_value=0, max_value=100, value=15, step=1) | |
| # --- Main Interface --- | |
| st.title("π VisionSort Pro") | |
| uploaded_files = st.file_uploader("Upload images/videos", type=["jpg", "jpeg", "png", "mp4", "mov"], accept_multiple_files=True) | |
| user_prompt = st.text_input("Search prompt", placeholder="e.g. 'find the cat'") | |
| if uploaded_files and user_prompt: | |
| results = {"high": [], "borderline": [], "low": []} | |
| temp_paths = [] | |
| with st.spinner(f"Processing {len(uploaded_files)} files..."): | |
| for file in uploaded_files: | |
| with tempfile.NamedTemporaryFile(delete=False, suffix=os.path.splitext(file.name)[1]) as f: | |
| f.write(file.read()) | |
| temp_paths.append(f.name) | |
| media_results = analyze_media( | |
| f.name, | |
| user_prompt, | |
| min_confidence, | |
| (borderline_min, min_confidence) | |
| ) | |
| for res in media_results: | |
| results[res["status"]].append(res) | |
| # Sort all groups by confidence descending | |
| for group in results.values(): | |
| group.sort(key=lambda r: r["confidence"], reverse=True) | |
| # --- Display Confident Matches --- | |
| if results["high"]: | |
| st.subheader(f"π― Confident Matches ({len(results['high'])})") | |
| cols = st.columns(4) | |
| for idx, res in enumerate(results["high"]): | |
| with cols[idx % 4]: | |
| st.image(Image.open(res["path"]), use_container_width=True) | |
| st.caption(f"{res['confidence']:.1f}% | {res['timestamp']:.2f}s") | |
| # --- Display Borderline Matches --- | |
| if results["borderline"]: | |
| st.subheader(f"β οΈ Potential Matches ({len(results['borderline'])})") | |
| #if st.checkbox("Show borderline results", True): | |
| if st.checkbox("Show borderline results", True, key="show_borderline"): | |
| cols = st.columns(4) | |
| for idx, res in enumerate(results["borderline"]): | |
| with cols[idx % 4]: | |
| st.image(Image.open(res["path"]), use_container_width=True) | |
| st.caption(f"{res['confidence']:.1f}% | {res['timestamp']:.2f}s") | |
| # if st.button("π§ Explain Match", key=f"blip_{idx}"): | |
| # with st.expander("π BLIP Analysis"): | |
| # st.write(f"**BLIP Description:** {process_with_blip(res['path'])}") | |
| # if "gpt_suggestion" in res: | |
| # st.write(f"**GPT Suggestion:** {res['gpt_suggestion']}") | |
| # --- Display Low Confidence Matches Only If GPT Enabled --- | |
| # if results["low"] and openai.api_key: | |
| # st.subheader(f"β Low Confidence Matches ({len(results['low'])})") | |
| # if st.checkbox("Show low confidence results"): | |
| # for res in results["low"]: | |
| # st.image(Image.open(res["path"]), use_container_width=True) | |
| # st.caption(f"{res['confidence']:.1f}% | {res['timestamp']:.2f}s") | |
| # if "gpt_suggestion" in res: | |
| # st.markdown(f"**π‘ GPT Suggestion:** {res['gpt_suggestion']}") | |
| # --- Display Low Confidence Matches ------------------------------------------------------ | |
| if results["low"]: | |
| st.subheader(f"β Low Confidence Matches ({len(results['low'])})") | |
| # if st.checkbox("Show low confidence results"): | |
| if st.checkbox("Show low confidence results", key="show_low"): | |
| for res in results["low"]: | |
| st.image(Image.open(res["path"]), use_container_width=True) | |
| st.caption(f"{res['confidence']:.1f}% | {res['timestamp']:.2f}s") | |
| # --- Prepare Downloadable Results --- | |
| download_ready = [] | |
| if results["high"]: | |
| download_ready += results["high"] | |
| if results["borderline"] and st.session_state.get("show_borderline", True): | |
| download_ready += results["borderline"] | |
| if results["low"] and st.session_state.get("show_low", False): | |
| download_ready += results["low"] | |
| if download_ready: | |
| zip_buffer = io.BytesIO() | |
| with zipfile.ZipFile(zip_buffer, "w") as zipf: | |
| for res in download_ready: | |
| try: | |
| filename = os.path.basename(res["path"]) | |
| zipf.write(res["path"], arcname=filename) | |
| except Exception: | |
| continue | |
| zip_buffer.seek(0) | |
| st.download_button( | |
| label="β¬οΈ Download Displayed Images", | |
| data=zip_buffer, | |
| file_name="visionSort_results.zip", | |
| mime="application/zip" | |
| ) | |
| # --- Cleanup Temporary Files --- | |
| for path in temp_paths: | |
| if os.path.exists(path): | |
| os.unlink(path) | |