arjunanand13 commited on
Commit
0729c66
·
verified ·
1 Parent(s): 705b991

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +58 -252
app.py CHANGED
@@ -1,265 +1,71 @@
 
1
  import os
 
 
 
2
  import gradio as gr
3
- import pandas as pd
4
- import json
5
- from dotenv import load_dotenv
6
- import httpx
7
 
8
- # Load environment variables
9
- load_dotenv()
10
 
11
- # Get OpenAI API key
12
- api_key = os.getenv("OPENAI_API_KEY")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
13
 
14
- # Helper function for OpenAI API calls
15
- def openai_chat_completion(messages, temperature=0, response_format=None, max_tokens=None):
16
- """Make a direct API call to OpenAI without using the client library"""
17
- url = "https://api.openai.com/v1/chat/completions"
18
-
19
- headers = {
20
- "Content-Type": "application/json",
21
- "Authorization": f"Bearer {api_key}"
22
- }
23
-
24
- payload = {
25
- "model": "gpt-3.5-turbo",
26
- "messages": messages,
27
- "temperature": temperature
28
- }
29
-
30
- if response_format:
31
- payload["response_format"] = response_format
32
-
33
- if max_tokens:
34
- payload["max_tokens"] = max_tokens
35
-
36
- response = httpx.post(url, json=payload, headers=headers)
37
-
38
- if response.status_code != 200:
39
- raise Exception(f"OpenAI API error: {response.status_code} - {response.text}")
40
-
41
- return response.json()
42
 
43
- # Simple database using pandas DataFrames
44
- class SimpleDatabase:
45
- def __init__(self):
46
- # Sample product data
47
- self.products = pd.DataFrame({
48
- 'product_id': [1, 2, 3, 4, 5],
49
- 'name': ['Laptop', 'Smartphone', 'Headphones', 'Monitor', 'Keyboard'],
50
- 'category': ['Electronics', 'Electronics', 'Audio', 'Electronics', 'Accessories'],
51
- 'price': [1200, 800, 150, 300, 80],
52
- 'stock': [10, 25, 50, 15, 30]
53
- })
54
-
55
- # Sample transactions data
56
- self.transactions = pd.DataFrame({
57
- 'transaction_id': [101, 102, 103, 104, 105, 106, 107],
58
- 'product_id': [1, 2, 3, 1, 5, 2, 4],
59
- 'quantity': [1, 2, 3, 1, 2, 1, 2],
60
- 'date': ['2025-04-29', '2025-04-29', '2025-04-28', '2025-04-28', '2025-04-27', '2025-04-29', '2025-04-29'],
61
- 'revenue': [1200, 1600, 450, 1200, 160, 800, 600]
62
- })
63
-
64
- def query_database(self, query_type, **kwargs):
65
- """Execute queries on the database based on query type"""
66
- if query_type == "product_info":
67
- if 'product_name' in kwargs:
68
- return self.products[self.products['name'].str.lower() == kwargs['product_name'].lower()]
69
- elif 'product_id' in kwargs:
70
- return self.products[self.products['product_id'] == kwargs['product_id']]
71
- else:
72
- return self.products
73
-
74
- elif query_type == "max_revenue_product":
75
- date_filter = kwargs.get('date', '2025-04-29') # Default to today
76
-
77
- # Group by product_id and calculate total revenue for the specified date
78
- daily_revenue = self.transactions[self.transactions['date'] == date_filter].groupby(
79
- 'product_id')['revenue'].sum().reset_index()
80
-
81
- if daily_revenue.empty:
82
- return "No sales data found for that date."
83
-
84
- # Find the product with max revenue
85
- max_revenue_product_id = daily_revenue.loc[daily_revenue['revenue'].idxmax()]['product_id']
86
- max_revenue = daily_revenue.loc[daily_revenue['revenue'].idxmax()]['revenue']
87
-
88
- # Get product details
89
- product_details = self.products[self.products['product_id'] == max_revenue_product_id].iloc[0]
90
-
91
- return {
92
- 'product_name': product_details['name'],
93
- 'revenue': max_revenue,
94
- 'date': date_filter
95
- }
96
-
97
- elif query_type == "inventory_check":
98
- product_name = kwargs.get('product_name')
99
- if product_name:
100
- product = self.products[self.products['name'].str.lower() == product_name.lower()]
101
- if not product.empty:
102
- return {'product': product_name, 'stock': product.iloc[0]['stock']}
103
- return f"Product '{product_name}' not found."
104
- return self.products[['name', 'stock']]
105
-
106
- return "Query type not supported"
107
 
108
- class QueryRouter:
109
- def __init__(self):
110
- """Initialize the query router"""
111
- pass
112
-
113
- def _classify_query(self, query):
114
- """Classify the query to determine which agent should handle it"""
115
- # Use OpenAI to classify the query
116
- messages = [
117
- {"role": "system", "content": """
118
- You are a query classifier for a shop assistant system.
119
- Classify customer queries into one of these categories:
120
- - max_revenue_product: Questions about which product generated the most revenue (today or on a specific date)
121
- - inventory_check: Questions about product availability or stock levels
122
- - product_info: Questions about product details, pricing, etc.
123
- - general_knowledge: Questions that require general knowledge not related to specific shop data
124
-
125
- Return ONLY the category as a single word without any explanation.
126
- """},
127
- {"role": "user", "content": query}
128
- ]
129
-
130
- response = openai_chat_completion(messages, temperature=0)
131
-
132
- # Extract the query type from the response
133
- query_type = response["choices"][0]["message"]["content"].strip().lower()
134
- return query_type
135
-
136
- def _extract_parameters(self, query, query_type):
137
- """Extract relevant parameters from the query based on query type"""
138
- # Use OpenAI to extract parameters
139
- prompt_content = f"""
140
- Extract parameters from this customer query: "{query}"
141
- Query type: {query_type}
142
-
143
- For max_revenue_product:
144
- - date (in YYYY-MM-DD format, extract "today" as today's date which is 2025-04-29)
145
-
146
- For inventory_check or product_info:
147
- - product_name (the name of the product being asked about)
148
-
149
- Return ONLY a valid JSON object with the extracted parameters, nothing else.
150
- Example: {{"product_name": "laptop"}} or {{"date": "2025-04-29"}}
151
- """
152
-
153
- messages = [
154
- {"role": "system", "content": "You extract parameters from customer queries for a shop assistant."},
155
- {"role": "user", "content": prompt_content}
156
- ]
157
-
158
- response = openai_chat_completion(messages, temperature=0, response_format={"type": "json_object"})
159
-
160
- # Parse the JSON response
161
- try:
162
- parameters = json.loads(response["choices"][0]["message"]["content"])
163
- return parameters
164
- except json.JSONDecodeError:
165
- return {}
166
-
167
- # Parse the JSON response
168
- import json
169
- try:
170
- parameters = json.loads(response.choices[0].message.content)
171
- return parameters
172
- except json.JSONDecodeError:
173
- return {}
174
-
175
- def _handle_general_knowledge(self, query):
176
- """Handle general knowledge queries using OpenAI"""
177
- messages = [
178
- {"role": "system", "content": """
179
- You are a helpful assistant for a shop. Answer the customer's question
180
- using your general knowledge. Keep answers brief and focused.
181
- """},
182
- {"role": "user", "content": query}
183
- ]
184
-
185
- response = openai_chat_completion(messages, temperature=0.7, max_tokens=150)
186
-
187
- return response["choices"][0]["message"]["content"]
188
-
189
- def _format_response(self, query_type, data):
190
- """Format the response based on query type and data"""
191
- if query_type == "max_revenue_product":
192
- if isinstance(data, str):
193
- return data
194
- return f"The product with the highest revenue on {data['date']} is {data['product_name']} with ${data['revenue']} in sales."
195
-
196
- elif query_type == "inventory_check":
197
- if isinstance(data, str):
198
- return data
199
- if isinstance(data, dict) and 'product' in data:
200
- return f"We currently have {data['stock']} units of {data['product']} in stock."
201
- return "Here's our current inventory: " + ", ".join([f"{row['name']}: {row['stock']} units" for _, row in data.iterrows()])
202
-
203
- elif query_type == "product_info":
204
- if data.empty:
205
- return "Product not found."
206
- if len(data) == 1:
207
- product = data.iloc[0]
208
- return f"{product['name']} ({product['category']}): ${product['price']}. We have {product['stock']} units in stock."
209
- return "Here are our products: " + ", ".join([f"{row['name']}: ${row['price']}" for _, row in data.iterrows()])
210
-
211
- return str(data)
212
-
213
- def process(self, query, db):
214
- """Process the query and return a response"""
215
- # Classify the query
216
- query_type = self._classify_query(query)
217
-
218
- # If it's a general knowledge query, handle it differently
219
- if query_type == "general_knowledge":
220
- return self._handle_general_knowledge(query)
221
-
222
- # Extract parameters from the query
223
- parameters = self._extract_parameters(query, query_type)
224
-
225
- # Query the database
226
- result = db.query_database(query_type, **parameters)
227
-
228
- # Format the response
229
- response = self._format_response(query_type, result)
230
-
231
- return response
232
 
233
- # Initialize database and router
234
- db = SimpleDatabase()
235
- router = QueryRouter()
 
 
 
 
 
 
 
236
 
237
- def process_query(query):
238
- """Process the user query and return a response"""
239
- if not query.strip():
240
- return "Please ask a question about our shop products or services."
241
-
242
- response = router.process(query, db)
243
- return response
244
 
245
- # Create Gradio interface
246
- demo = gr.Interface(
247
- fn=process_query,
248
- inputs=gr.Textbox(
249
- placeholder="Ask about product pricing, inventory, sales, or any other question...",
250
- label="Customer Query"
251
- ),
252
- outputs=gr.Textbox(label="Shop Assistant Response"),
253
- title="Shop Voice Box Assistant",
254
- description="Ask questions about products, inventory, sales, or general questions.",
255
- examples=[
256
- ["What's the maximum revenue product today?"],
257
- ["How many laptops do we have in stock?"],
258
- ["Tell me about the smartphone."],
259
- ["What's the weather like today?"]
260
- ]
261
- )
262
 
263
- # Launch the app
264
  if __name__ == "__main__":
265
  demo.launch()
 
1
+ ```python
2
  import os
3
+ import sqlite3
4
+ import requests
5
+ import openai
6
  import gradio as gr
 
 
 
 
7
 
8
+ # Load API keys from environment
9
+ openai.api_key = os.getenv("OPENAI_API_KEY")
10
 
11
+ # --- Agents ---
12
+ def db_agent(query: str) -> str:
13
+ conn = sqlite3.connect("shop.db")
14
+ cur = conn.cursor()
15
+ if "max revenue" in query.lower():
16
+ cur.execute(
17
+ """
18
+ SELECT product, SUM(amount) AS revenue
19
+ FROM transactions
20
+ WHERE date = date('now')
21
+ GROUP BY product
22
+ ORDER BY revenue DESC
23
+ LIMIT 1
24
+ """
25
+ )
26
+ row = cur.fetchone()
27
+ return f"Top product today: {row[0]} with ₹{row[1]:,.2f}" if row else "No transactions found for today."
28
+ return None
29
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
30
 
31
+ def web_search_agent(query: str) -> str:
32
+ # Example using SerpAPI
33
+ resp = requests.get(
34
+ "https://serpapi.com/search",
35
+ params={"q": query, "api_key": os.getenv("SERPAPI_KEY")}
36
+ ).json()
37
+ snippet = resp.get("organic_results", [{}])[0].get("snippet", "")
38
+ return llm_agent(f"Summarize: {snippet}")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
39
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
40
 
41
+ def llm_agent(prompt: str) -> str:
42
+ resp = openai.ChatCompletion.create(
43
+ model="gpt-4o-mini",
44
+ messages=[
45
+ {"role": "system", "content": "You are a helpful assistant."},
46
+ {"role": "user", "content": prompt}
47
+ ],
48
+ temperature=0.2
49
+ )
50
+ return resp.choices[0].message.content.strip()
51
 
 
 
 
 
 
 
 
52
 
53
+ def handle_query(query: str) -> str:
54
+ q = query.lower()
55
+ if any(k in q for k in ["max", "revenue", "today", "product"]):
56
+ return db_agent(query)
57
+ elif any(k in q for k in ["who", "what", "when", "where"]):
58
+ return web_search_agent(query)
59
+ else:
60
+ return llm_agent(query)
61
+
62
+ # --- Gradio UI ---
63
+ with gr.Blocks() as demo:
64
+ gr.Markdown("## Shop Voice-Box Assistant")
65
+ user_input = gr.Textbox(placeholder="Type your question here...", lines=2)
66
+ submit_btn = gr.Button("Submit")
67
+ response_box = gr.Textbox(label="Answer")
68
+ submit_btn.click(fn=handle_query, inputs=user_input, outputs=response_box)
 
69
 
 
70
  if __name__ == "__main__":
71
  demo.launch()