import gradio as gr from utils import SafeProgress, format_categories_html from embeddings import create_product_embeddings from similarity import compute_similarities from chicory_api import call_chicory_parser # Global variable for embeddings embeddings = {} def categorize_products(product_input, is_file=False, top_n=5, confidence_threshold=0.5, progress=None): """Categorize products from text input or file""" progress_tracker = SafeProgress(progress) progress_tracker(0, desc="Starting...") # Parse input if is_file: from utils import parse_product_file try: product_names = parse_product_file(product_input.name) except Exception as e: return f"
Error: {str(e)}
" else: product_names = [line.strip() for line in product_input.split("\n") if line.strip()] if not product_names: return "
No product names provided.
" # Create embeddings progress_tracker(0.2, desc="Generating product embeddings...") products_embeddings = create_product_embeddings(product_names) # Call Chicory Parser API progress_tracker(0.5, desc="Calling Chicory Parser API...") chicory_results = call_chicory_parser(product_names) # Compute similarities progress_tracker(0.7, desc="Computing similarities...") all_similarities = compute_similarities(embeddings, products_embeddings) # Format results progress_tracker(0.9, desc="Formatting results...") output_html = "
" for product, similarities in all_similarities.items(): filtered_similarities = [(ingredient, score) for ingredient, score in similarities if score >= confidence_threshold] top_similarities = filtered_similarities[:top_n] output_html += format_categories_html(product, top_similarities, chicory_result=chicory_results.get(product)) output_html += "
" output_html += "
" if not all_similarities: output_html = "
No results found. Please check your input or try different products.
" progress_tracker(1.0, desc="Done!") return output_html def create_demo(): """Create the Gradio interface""" with gr.Blocks(css=""" .results-container { min-height: 400px; } .chicory-result { visibility: visible !important; display: block !important; } .container { gap: 20px; } """) as demo: gr.Markdown("# Product Categorization Tool\nAnalyze products and find the most similar ingredients using AI embeddings.") with gr.Tabs(): with gr.TabItem("Text Input"): with gr.Row(): with gr.Column(scale=1): # Input section text_input = gr.Textbox(lines=10, placeholder="Enter product names, one per line", label="Product Names") input_controls = gr.Row() with input_controls: top_n = gr.Slider(1, 10, 5, label="Top N Results") confidence = gr.Slider(0.1, 0.9, 0.5, label="Confidence Threshold") categorize_btn = gr.Button("Categorize") with gr.Column(scale=1): # Results section text_output = gr.HTML(label="Categorization Results", elem_classes="results-container") categorize_btn.click( fn=categorize_products, inputs=[text_input, gr.State(False), top_n, confidence], outputs=text_output ) with gr.TabItem("File Upload"): with gr.Row(): with gr.Column(scale=1): # Input section file_input = gr.File(label="Upload JSON or text file with products", file_types=[".json", ".txt"]) file_controls = gr.Row() with file_controls: file_top_n = gr.Slider(1, 10, 5, label="Top N Results") file_confidence = gr.Slider(0.1, 0.9, 0.5, label="Confidence Threshold") process_btn = gr.Button("Process File") with gr.Column(scale=1): # Results section file_output = gr.HTML(label="Categorization Results", elem_classes="results-container") process_btn.click( fn=categorize_products, inputs=[file_input, gr.State(True), file_top_n, file_confidence], outputs=file_output ) gr.Markdown("Powered by Voyage AI embeddings • Built with Gradio") return demo