File size: 5,083 Bytes
a318724
 
 
 
c8d7df6
a318724
 
 
 
c8d7df6
 
a318724
 
c8d7df6
 
 
 
 
 
 
 
 
 
 
a318724
c8d7df6
 
 
 
a318724
c8d7df6
d457572
 
 
c8d7df6
a318724
c8d7df6
a318724
c8d7df6
a318724
 
 
 
c8d7df6
a318724
d457572
a318724
 
c8d7df6
a318724
 
 
 
 
 
 
 
beeb862
 
 
 
 
c8d7df6
beeb862
a318724
 
beeb862
 
 
 
 
 
 
 
 
 
 
 
 
 
 
c8d7df6
beeb862
a318724
 
beeb862
a318724
beeb862
 
 
 
 
 
 
 
 
 
 
 
 
 
 
c8d7df6
beeb862
a318724
 
beeb862
c8d7df6
a318724
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
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"<div style='color: #d32f2f; font-weight: bold;'>Error: {str(e)}</div>"
    else:
        product_names = [line.strip() for line in product_input.split("\n") if line.strip()]

    if not product_names:
        return "<div style='color: #d32f2f;'>No product names provided.</div>"

    # 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 = "<div style='font-family: Arial, sans-serif;'>"
    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 += "<hr style='margin: 15px 0; border: 0; border-top: 1px solid #eee;'>"
    output_html += "</div>"

    if not all_similarities:
        output_html = "<div style='color: #d32f2f; font-weight: bold; padding: 20px;'>No results found. Please check your input or try different products.</div>"

    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