sarthak413 commited on
Commit
0d75dc7
Β·
verified Β·
1 Parent(s): 06771c5

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +114 -79
app.py CHANGED
@@ -1,97 +1,132 @@
1
  import gradio as gr
2
  from huggingface_hub import InferenceClient
3
- from fastapi import FastAPI, HTTPException
4
- import os
5
 
6
- # Initialize clients
7
- client = InferenceClient("HuggingFaceH4/zephyr-7b-beta")
8
- app = FastAPI()
9
 
10
- # Configuration - Change this default key for production!
11
- DEFAULT_SYSTEM_MESSAGE = "You are a chatbot that helps in mood detection and recommends recipes"
12
- API_TOKEN = "default-secret-key" # πŸ‘ˆ Change this for production deployments
 
 
 
13
 
14
- def generate_response(
15
- message: str,
16
- history: list[tuple[str, str]] = None,
17
- system_message: str = DEFAULT_SYSTEM_MESSAGE,
18
- max_tokens: int = 512,
19
- temperature: float = 0.7,
20
- top_p: float = 0.95
21
- ):
22
- """Core response generation logic"""
23
- messages = [{"role": "system", "content": system_message}]
24
 
25
- if history:
26
- for user_msg, assistant_msg in history:
27
- if user_msg:
28
- messages.append({"role": "user", "content": user_msg})
29
- if assistant_msg:
30
- messages.append({"role": "assistant", "content": assistant_msg})
31
 
32
- messages.append({"role": "user", "content": message})
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
33
 
34
- try:
35
- response = ""
36
- for chunk in client.chat_completion(
37
- messages,
38
- max_tokens=max_tokens,
39
- stream=True,
40
- temperature=temperature,
41
- top_p=top_p,
42
- ):
43
- response += chunk.choices[0].delta.content or ""
44
- return response
45
- except Exception as e:
46
- raise HTTPException(status_code=500, detail=str(e))
47
 
48
- # FastAPI Endpoints
49
- @app.post("/api/chat")
50
- async def api_chat_endpoint(
51
- message: str,
52
- api_token: str,
53
- system_message: str = DEFAULT_SYSTEM_MESSAGE,
54
- max_tokens: int = 512,
55
- temperature: float = 0.7,
56
- top_p: float = 0.95
57
  ):
58
- """External API endpoint"""
59
- if api_token != API_TOKEN:
60
- raise HTTPException(status_code=403, detail="Invalid API token")
 
 
 
 
 
 
 
 
 
 
 
61
 
62
- return {
63
- "response": generate_response(
64
- message=message,
65
- system_message=system_message,
66
- max_tokens=max_tokens,
67
- temperature=temperature,
68
- top_p=top_p
69
- )
70
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
71
 
72
- # Gradio Interface - Now includes API key validation
73
- def chat_ui(message: str, history: list[tuple[str, str]], api_key: str):
74
- if api_key != API_TOKEN:
75
- return "πŸ”’ Error: Invalid API Key"
76
- return generate_response(message, history)
 
 
 
 
 
 
 
77
 
78
- chat_interface = gr.ChatInterface(
79
- fn=chat_ui,
 
80
  additional_inputs=[
81
- gr.Textbox(API_TOKEN, label="API Key", type="password"),
82
- gr.Textbox(DEFAULT_SYSTEM_MESSAGE, label="System message"),
83
- gr.Slider(1, 2048, 512, step=1, label="Max new tokens"),
84
- gr.Slider(0.1, 4.0, 0.7, step=0.1, label="Temperature"),
85
- gr.Slider(0.1, 1.0, 0.95, step=0.05, label="Top-p sampling"),
 
 
86
  ],
87
- title="🍳 Mood-Based Recipe Assistant",
88
- description=f"API Key: {API_TOKEN}" # Shows default key for testing
 
 
 
 
 
 
89
  )
90
 
91
- # Mount Gradio to FastAPI
92
- chat_interface.mount_to(app, path="/")
93
-
94
  if __name__ == "__main__":
95
- import uvicorn
96
- print(f"πŸ”‘ Default API Token: {API_TOKEN}") # Visible in console
97
- uvicorn.run(app, host="0.0.0.0", port=7860)
 
1
  import gradio as gr
2
  from huggingface_hub import InferenceClient
3
+ from datasets import load_dataset
4
+ import pandas as pd
5
 
6
+ # --- Load the Indian Recipes Dataset ---
7
+ dataset = load_dataset("nf-analyst/indian_recipe")
8
+ recipes = dataset["train"].to_pandas()
9
 
10
+ # Preprocess: Combine relevant fields for search
11
+ recipes["search_text"] = (
12
+ recipes["name"] + " " +
13
+ recipes["ingredients"].apply(lambda x: ' '.join(x)) + " " +
14
+ recipes["instructions"].apply(lambda x: ' '.join(x))
15
+ )
16
 
17
+ # --- Enhanced Search Function (Semantic + Keyword) ---
18
+ from sentence_transformers import SentenceTransformer
19
+ import faiss
20
+ import numpy as np
 
 
 
 
 
 
21
 
22
+ # Initialize semantic search
23
+ model = SentenceTransformer("all-MiniLM-L6-v2")
24
+ embeddings = model.encode(recipes["search_text"].tolist())
25
+ index = faiss.IndexFlatL2(embeddings.shape[1])
26
+ index.add(embeddings)
 
27
 
28
+ def search_recipes(query, top_k=3):
29
+ # Semantic search first
30
+ query_embedding = model.encode([query])
31
+ distances, indices = index.search(query_embedding, top_k)
32
+
33
+ # Keyword verification
34
+ results = []
35
+ for i in indices[0]:
36
+ recipe = recipes.iloc[i]
37
+ if query.lower() in recipe["search_text"].lower():
38
+ results.append({
39
+ "name": recipe["name"],
40
+ "ingredients": recipe["ingredients"],
41
+ "instructions": recipe["instructions"],
42
+ "cook_time": recipe["cook_time"],
43
+ "diet": recipe["diet"]
44
+ })
45
+ return results if results else None
46
 
47
+ # --- Modified Respond Function ---
48
+ client = InferenceClient("HuggingFaceH4/zephyr-7b-beta")
 
 
 
 
 
 
 
 
 
 
 
49
 
50
+ def respond(
51
+ message,
52
+ history: list[tuple[str, str]],
53
+ system_message,
54
+ max_tokens,
55
+ temperature,
56
+ top_p,
 
 
57
  ):
58
+ # Search our dataset first
59
+ found_recipes = search_recipes(message)
60
+
61
+ if not found_recipes:
62
+ yield "No matching Indian recipes found. Try terms like 'butter chicken', 'biryani', or 'dal tadka'."
63
+ return
64
+
65
+ # Format recipes as strict context
66
+ recipe_context = "\n\n".join([
67
+ f"Recipe {i+1}: {r['name']} ({r['diet']}, {r['cook_time']})\n"
68
+ f"Ingredients: {', '.join(r['ingredients'])}\n"
69
+ f"Method: {' '.join(r['instructions'][:3])}..."
70
+ for i, r in enumerate(found_recipes)
71
+ ])
72
 
73
+ # Force the LLM to only use these recipes
74
+ strict_system_prompt = f"""You are an Indian food expert. ONLY recommend from these verified recipes.
75
+ NEVER invent recipes. If asked for variations, suggest only minor modifications to these:
76
+
77
+ {recipe_context}
78
+
79
+ Respond in this format:
80
+ 1. First recommend recipe names matching the query
81
+ 2. If asked for details, provide ONLY from the recipes above
82
+ 3. For substitutions, suggest similar ingredients from these recipes
83
+ """
84
+
85
+ messages = [{"role": "system", "content": strict_system_prompt}]
86
+
87
+ # Add conversation history
88
+ for user_msg, bot_msg in history:
89
+ if user_msg:
90
+ messages.append({"role": "user", "content": user_msg})
91
+ if bot_msg:
92
+ messages.append({"role": "assistant", "content": bot_msg})
93
+
94
+ messages.append({"role": "user", "content": message})
95
 
96
+ # Generate response
97
+ response = ""
98
+ for chunk in client.chat_completion(
99
+ messages,
100
+ max_tokens=max_tokens,
101
+ stream=True,
102
+ temperature=temperature,
103
+ top_p=top_p,
104
+ ):
105
+ token = chunk.choices[0].delta.content
106
+ response += token
107
+ yield response
108
 
109
+ # --- Gradio Interface with Indian Food Examples ---
110
+ demo = gr.ChatInterface(
111
+ respond,
112
  additional_inputs=[
113
+ gr.Textbox(
114
+ value="You are an expert on Indian cuisine.",
115
+ label="System message"
116
+ ),
117
+ gr.Slider(minimum=1, maximum=2048, value=512, step=1, label="Max new tokens"),
118
+ gr.Slider(minimum=0.1, maximum=4.0, value=0.7, step=0.1, label="Temperature"),
119
+ gr.Slider(minimum=0.1, maximum=1.0, value=0.95, step=0.05, label="Top-p"),
120
  ],
121
+ examples=[
122
+ "Vegetarian North Indian dinner",
123
+ "Quick chicken curry",
124
+ "Traditional South Indian breakfast",
125
+ "Gluten-free Indian dessert"
126
+ ],
127
+ title="πŸ› Authentic Indian Recipe Assistant",
128
+ description="Get recommendations ONLY from verified Indian recipes"
129
  )
130
 
 
 
 
131
  if __name__ == "__main__":
132
+ demo.launch()