arjunanand13 commited on
Commit
b12e5fe
·
verified ·
1 Parent(s): 4332d02

Create app.py

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