File size: 5,865 Bytes
da4346f
 
 
 
 
8aa425b
da4346f
 
 
 
 
915e496
 
 
 
da4346f
 
 
 
 
 
 
8aa425b
 
 
 
 
 
 
 
 
 
 
 
a2907e4
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8aa425b
 
a2907e4
8aa425b
a2907e4
da4346f
915e496
 
 
8aa425b
 
 
a2907e4
 
 
 
 
 
 
 
 
 
 
8aa425b
a2907e4
 
8aa425b
 
 
da4346f
a2907e4
da4346f
8aa425b
 
 
 
 
 
 
 
 
a2907e4
 
 
 
 
8aa425b
 
 
 
 
 
 
 
 
a2907e4
 
8aa425b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
da4346f
 
 
915e496
 
 
da4346f
a2907e4
da4346f
 
8aa425b
da4346f
9efbbcb
 
 
 
 
 
da4346f
9efbbcb
 
 
 
 
da4346f
 
915e496
 
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
import os
from dotenv import load_dotenv
import gradio as gr
from langchain_huggingface import HuggingFaceEndpoint
from datetime import datetime
from datasets import load_dataset

# Load environment variables
load_dotenv()
HF_TOKEN = os.getenv("HF_TOKEN")

# Check if token exists and handle error gracefully
if not HF_TOKEN:
    raise ValueError("HF_TOKEN environment variable not found. Please set it in your .env file.")

# Initialize the HuggingFace inference endpoint
llm = HuggingFaceEndpoint(
    repo_id="mistralai/Mistral-7B-Instruct-v0.3",
    huggingfacehub_api_token=HF_TOKEN.strip(),
    temperature=0.7,
)

# Load the Indian Recipe Dataset
try:
    ds = load_dataset("Anupam007/indian-recipe-dataset")
    
    # Extract unique ingredients from the dataset
    all_ingredients = set()
    for recipe in ds['train']:
        if 'ingredients' in recipe:
            # Split ingredients and clean them
            ingredients = [ing.strip().lower() for ing in recipe['ingredients'].split(',')]
            all_ingredients.update(ingredients)
    
    # Expand ingredient variants
    INGREDIENT_VARIANTS = {}
    for ing in all_ingredients:
        # Add singular and plural variants
        singular = ing.rstrip('s')
        plural = ing + 's'
        INGREDIENT_VARIANTS[singular] = [singular, plural]
        INGREDIENT_VARIANTS[plural] = [singular, plural]
    
    # Combine with direct mappings for common ingredients
    INGREDIENT_VARIANTS.update({
        'potato': ['potato', 'potatoes'],
        'tomato': ['tomato', 'tomatoes'],
        'onion': ['onion', 'onions'],
        'spinach': ['spinach', 'spinaches'],
        'chicken': ['chicken'],
        'turmeric': ['turmeric'],
        'cumin': ['cumin']
    })
except Exception as e:
    print(f"Error loading dataset: {e}")
    INGREDIENT_VARIANTS = {}

# Input validation function
def validate_ingredients(ingredients):
    if not ingredients or ingredients.strip() == "":
        return "Invalid"
    
    # Split and clean input ingredients
    input_ingredients = [ing.strip().lower() for ing in ingredients.split(',')]
    
    # Check if all input ingredients have a valid variant
    valid_matches = []
    for ing in input_ingredients:
        matched = False
        for key, variants in INGREDIENT_VARIANTS.items():
            if ing in variants:
                valid_matches.append(ing)
                matched = True
                break
        if not matched:
            print(f"No match found for ingredient: {ing}")
    
    # If all ingredients have a match, return Valid
    if len(valid_matches) == len(input_ingredients):
        return "Valid"
    else:
        return "Invalid"

# Recipe generation function
def generate_recipe(ingredients):
    # Split and clean input ingredients
    input_ingredients = [ing.strip().lower() for ing in ingredients.split(',')]
    
    # Find matching recipes in the dataset
    matching_recipes = []
    for recipe in ds['train']:
        if 'ingredients' in recipe and 'instructions' in recipe:
            recipe_ingredients = [ing.strip().lower() for ing in recipe['ingredients'].split(',')]
            
            # Check if input ingredients are in the recipe
            match_count = sum(1 for ing in input_ingredients 
                               for recipe_ing in recipe_ingredients 
                               if any(variant in recipe_ing for variant in INGREDIENT_VARIANTS.get(ing, [ing])))
            
            if match_count > 0:
                matching_recipes.append({
                    'title': recipe.get('title', 'Untitled Recipe'),
                    'ingredients': recipe.get('ingredients', ''),
                    'instructions': recipe.get('instructions', '')
                })
    
    # If matching recipes found, select one
    if matching_recipes:
        # Choose first matching recipe (could randomize)
        selected_recipe = matching_recipes[0]
        
        # Format the recipe output
        recipe_output = f"Recipe: {selected_recipe['title']}\n\n"
        recipe_output += "Ingredients:\n"
        recipe_output += f"{selected_recipe['ingredients']}\n\n"
        recipe_output += "Instructions:\n"
        recipe_output += selected_recipe['instructions']
        
        return recipe_output
    else:
        # Fallback to LLM generation if no matching recipes
        prompt = (
            f"You are an expert chef specializing in Indian cuisine. Using the ingredients: {ingredients}, "
            f"suggest a unique Indian recipe. Provide a title, list of ingredients, and detailed step-by-step instructions. "
            f"Focus on traditional Indian cooking methods and spices."
        )
        return llm(prompt).strip()

# Combined function for Gradio
def suggest_recipes(ingredients):
    if not ingredients or ingredients.strip() == "":
        return "Please enter ingredients before submitting."
    
    validation_result = validate_ingredients(ingredients)
    if "Valid" in validation_result:
        return generate_recipe(ingredients)
    else:
        return "I'm sorry, but I can't process this request due to invalid ingredients. Please provide valid Indian cooking ingredients!"

# Minimalist Gradio interface
with gr.Blocks() as app:
    gr.Markdown("# 🍳 Indian Recipe Generator")
    gr.Markdown("Enter Indian ingredients, and we'll find or create a delightful recipe!")
    gr.Markdown("💡 Tip: Try ingredients like tomato, onion, potato, spinach, chicken, or spices like turmeric, cumin!")
    
    with gr.Row():
        ingredients_input = gr.Textbox(label="Ingredients")
        recipe_output = gr.Textbox(label="Recipe")
    
    generate_button = gr.Button("Generate Recipe")
    generate_button.click(suggest_recipes, inputs=ingredients_input, outputs=recipe_output)

# Launch the app
if __name__ == "__main__":
    app.launch()