Spaces:
Sleeping
Sleeping
File size: 6,904 Bytes
c627f4d 854f3b8 c627f4d | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 | import streamlit as st
from qa_backend import DogFoodQASystem
import time
from typing import Dict, Any, List
import logging
import nltk
nltk.download('punkt_tab')
# Configure logging
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
# Configure page settings
st.set_page_config(
page_title="Dog Food Advisor",
page_icon="π",
layout="wide"
)
# Custom CSS for better styling
st.markdown("""
<style>
.stAlert {
padding: 1rem;
margin: 1rem 0;
border-radius: 0.5rem;
}
.search-result {
padding: 1rem;
margin: 0.5rem 0;
border: 1px solid #ddd;
border-radius: 0.5rem;
}
.debug-info {
font-size: small;
color: gray;
padding: 0.5rem;
background-color: #f0f0f0;
border-radius: 0.3rem;
}
</style>
""", unsafe_allow_html=True)
@st.cache_resource
def load_qa_system() -> DogFoodQASystem:
"""Initialize and cache the QA system."""
qa_system = DogFoodQASystem()
# Run diagnostics
vector_store_status = qa_system.diagnose_vector_store()
return qa_system, vector_store_status
def display_search_result(result: Dict[str, Any], index: int) -> None:
"""Display a single search result with enhanced source and score information."""
with st.container():
# Source indicator and styling
sources = result['sources']
if len(sources) > 1:
source_color = "#9C27B0" # Purple for both sources
source_badge = "π Found in Both Sources"
scores_text = f"BM25: {result['original_scores']['BM25']:.3f}, Vector: {result['original_scores']['Vector']:.3f}"
elif 'Vector' in sources:
source_color = "#2E7D32" # Green for Vector
source_badge = "π’ Vector Search"
scores_text = f"Score: {result['original_scores']['Vector']:.3f}"
else:
source_color = "#1565C0" # Blue for BM25
source_badge = "π΅ BM25 Search"
scores_text = f"Score: {result['original_scores']['BM25']:.3f}"
# Display header with source and score information
st.markdown(f"""
<div class="search-result">
<h4 style="color: {source_color}">
Result {index + 1} | {source_badge} | {scores_text}
</h4>
</div>
""", unsafe_allow_html=True)
# Display product details
col1, col2 = st.columns(2)
with col1:
st.write("**Product Details:**")
st.write(f"β’ Brand: {result['metadata']['brand']}")
st.write(f"β’ Product: {result['metadata']['product_name']}")
st.write(f"β’ Price: ${result['metadata']['price']:.2f}")
with col2:
st.write("**Additional Information:**")
st.write(f"β’ Weight: {result['metadata']['weight']}kg")
st.write(f"β’ Dog Type: {result['metadata']['dog_type']}")
if 'reviews' in result['metadata']:
st.write(f"β’ Reviews: {result['metadata']['reviews']}")
st.markdown("**Description:**")
st.write(result['text'])
st.markdown("---")
def display_search_stats(results: List[Dict[str, Any]]) -> None:
"""Display detailed statistics about search results."""
total_results = len(results)
duplicates = sum(1 for r in results if len(r['sources']) > 1)
vector_only = sum(1 for r in results if r['sources'] == ['Vector'])
bm25_only = sum(1 for r in results if r['sources'] == ['BM25'])
st.markdown("#### Search Results Statistics")
col1, col2, col3, col4 = st.columns(4)
with col1:
st.metric("Total Unique Results", total_results)
with col2:
st.metric("Found in Both Sources", duplicates, "π")
with col3:
st.metric("Vector Only", vector_only, "π’")
with col4:
st.metric("BM25 Only", bm25_only, "π΅")
def main():
# Header
st.title("π Dog Food Advisor")
st.markdown("""
Ask questions about dog food products in English or Spanish.
The system will provide relevant recommendations based on your query.
""")
# Initialize QA system with diagnostics
qa_system, vector_store_status = load_qa_system()
# Display system status
with st.sidebar:
st.markdown("### System Status")
if vector_store_status:
st.success("Vector Store: Connected")
else:
st.error("Vector Store: Not Connected")
st.warning("Only BM25 search will be available")
# Query input
query = st.text_input(
"Enter your question:",
placeholder="e.g., 'What's the best food for puppies?' or 'ΒΏCuΓ‘l es la mejor comida para perros adultos?'"
)
# Add a search button
search_button = st.button("Search")
if query and search_button:
with st.spinner("Processing your query..."):
try:
# Process query
start_time = time.time()
result = qa_system.process_query(query)
processing_time = time.time() - start_time
# Display answer
st.markdown("### Answer")
st.write(result["answer"])
# Display search stats
display_search_stats(result["search_results"])
# Display processing information
st.markdown(f"""
<div class='debug-info'>
Language detected: {result['language']} |
Processing time: {processing_time:.2f}s
</div>
""", unsafe_allow_html=True)
# Display search results in an expander
with st.expander("View Relevant Products", expanded=False):
st.markdown("### Search Results")
for i, search_result in enumerate(result["search_results"]):
display_search_result(search_result, i)
except Exception as e:
st.error(f"An error occurred: {str(e)}")
logging.error(f"Error processing query: {str(e)}", exc_info=True)
# Add footer with instructions
st.markdown("---")
with st.expander("Usage Tips"):
st.markdown("""
- Ask questions in English or Spanish
- Be specific about your dog's needs (age, size, special requirements)
- Include price preferences (e.g., 'affordable', 'premium')
- Results are ranked by relevance and include price, brand, and product details
- Results are color-coded:
- π΅ Blue: BM25 Search Results
- π’ Green: Vector Search Results
""")
if __name__ == "__main__":
main()
|