Spaces:
Running
Running
| from __future__ import annotations | |
| import json | |
| from datetime import datetime, timedelta, date | |
| from typing import Any, Dict, List, Optional | |
| import streamlit as st | |
| from database.operations import find_image_analyses, list_image_categories | |
| from components.image_render_analysis import render_analyzer_results | |
| def _coerce_dt(val: Any) -> Optional[datetime]: | |
| if isinstance(val, datetime): | |
| return val | |
| try: | |
| return datetime.fromisoformat(str(val)) | |
| except Exception: | |
| return None | |
| def _label_for_item(doc: Dict[str, Any]) -> str: | |
| """Shown in the wide dropdown.""" | |
| ts = _coerce_dt(doc.get("created_at")) | |
| ts_s = ts.strftime("%Y-%m-%d %H:%M") if ts else "Unknown time" | |
| cat = doc.get("category") or "—" | |
| model = doc.get("analyzer_model") or "—" | |
| return f"{ts_s} · {cat} · {model}" | |
| def render_image_analysis_library(uid: Optional[str] = None, prefix: str = "img_ana_lib") -> None: | |
| st.subheader("Image Analysis Library") | |
| today = datetime.utcnow().date() | |
| default_start = today - timedelta(days=30) | |
| c1, c2, c3 = st.columns([1, 1, 1]) | |
| with c1: | |
| start_date: date = st.date_input("Start date", value=default_start, key=f"{prefix}_start") | |
| with c2: | |
| end_date: date = st.date_input("End date", value=today, key=f"{prefix}_end") | |
| with c3: | |
| try: | |
| # Ensure uid is not None before filtering | |
| if uid: | |
| cats: List[str] = list_image_categories(created_by=uid) # <-- filter per user | |
| else: | |
| cats: List[str] = [] | |
| if "All" not in cats: | |
| cats = ["All"] + cats | |
| except Exception as e: | |
| st.error(f"Error loading categories: {e}") | |
| cats = ["All"] | |
| category = st.selectbox("Category", options=cats, index=0, key=f"{prefix}_cat") | |
| st.markdown("---") | |
| try: | |
| start_dt = datetime.combine(start_date, datetime.min.time()) | |
| end_dt = datetime.combine(end_date + timedelta(days=1), datetime.min.time()) | |
| query_cat = None if (not category or category == "All") else category | |
| docs: List[Dict[str, Any]] = find_image_analyses( | |
| category=query_cat, start_date=start_dt, end_date=end_dt, limit=200, created_by=uid | |
| ) | |
| except Exception as e: | |
| st.error(f"Failed to load image analyses: {e}") | |
| return | |
| if not docs: | |
| st.info("No image analysis for the selected filters.") | |
| return | |
| labels = [_label_for_item(d) for d in docs] | |
| selected_label = st.selectbox( | |
| "Select an analysis", | |
| options=labels, | |
| index=0, | |
| key="img_lib_sel", | |
| ) | |
| sel_idx = labels.index(selected_label) if selected_label in labels else 0 | |
| doc = docs[sel_idx] | |
| thumb_b64 = doc.get("thumbnail") | |
| if thumb_b64: | |
| try: | |
| st.image( | |
| f"data:image/jpeg;base64,{thumb_b64}", | |
| caption="Thumbnail", | |
| width=220, | |
| ) | |
| except Exception: | |
| pass | |
| analysis = doc.get("results") or {} | |
| if analysis: | |
| render_analyzer_results(analysis) | |
| try: | |
| res = json.dumps(analysis, indent=2, ensure_ascii=False) | |
| st.download_button( | |
| "Download JSON", | |
| data=res.encode("utf-8"), | |
| file_name=f"image_analysis_{doc.get('_id','item')}.json", | |
| mime="application/json", | |
| width='stretch', | |
| key="img_lib_json_dl", | |
| ) | |
| except Exception: | |
| pass | |
| else: | |
| st.info("No analysis stored for this item.") | |