Vedant104 commited on
Commit
2eb9abd
·
verified ·
1 Parent(s): 19ab6b8

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +191 -0
app.py ADDED
@@ -0,0 +1,191 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import requests
3
+ import pandas as pd
4
+ import time
5
+ from llama_cpp import Llama
6
+ from huggingface_hub import hf_hub_download
7
+
8
+ # =========================
9
+ # LOAD GGUF MODEL
10
+ # =========================
11
+ print("Downloading GGUF model...")
12
+
13
+ model_path = hf_hub_download(
14
+ repo_id="bartowski/Qwen2.5-1.5B-Instruct-GGUF",
15
+ filename="qwen2.5-1.5b-instruct-q4_k_m.gguf"
16
+ )
17
+
18
+ print("Loading model...")
19
+
20
+ llm = Llama(
21
+ model_path=model_path,
22
+ n_ctx=1024,
23
+ n_threads=4,
24
+ n_batch=512,
25
+ verbose=False
26
+ )
27
+
28
+ # =========================
29
+ # ENV VARIABLES (use HF Secrets ideally)
30
+ # =========================
31
+ client_id = "sb-cap1-3c4588e0trial-dev!t617058"
32
+ client_secret = "acbe78be-ead5-4b12-b3b4-32fdb27d0f5f$hFj-hDXxwHkNHC-CAvv-OKSr3KH96nLL4KqwIg7M8D8="
33
+ token_url = "https://3c4588e0trial.authentication.us10.hana.ondemand.com/oauth/token"
34
+ cap_service_url_customers = "https://3c4588e0trial-dev-cap1-srv.cfapps.us10-001.hana.ondemand.com/odata/v4/sales/Customers?$top=2"
35
+ cap_service_url_products = "https://3c4588e0trial-dev-cap1-srv.cfapps.us10-001.hana.ondemand.com/odata/v4/sales/Products?$top=2"
36
+ cap_service_url_saleorders = "https://3c4588e0trial-dev-cap1-srv.cfapps.us10-001.hana.ondemand.com/odata/v4/sales/SalesOrders?$top=2"
37
+ cap_service_url_saleorderitems = "https://3c4588e0trial-dev-cap1-srv.cfapps.us10-001.hana.ondemand.com/odata/v4/sales/SalesOrderItems?$top=2"
38
+ # =========================
39
+ # GLOBAL CACHE
40
+ # =========================
41
+ access_token = None
42
+ cached_data = None
43
+ last_refresh = 0
44
+
45
+ # =========================
46
+ # TOKEN FUNCTION
47
+ # =========================
48
+ def generate_token():
49
+ global access_token
50
+
51
+ response = requests.post(
52
+ token_url,
53
+ data={"grant_type": "client_credentials"},
54
+ auth=(client_id, client_secret)
55
+ )
56
+
57
+ if response.status_code != 200:
58
+ return None
59
+
60
+ access_token = response.json().get("access_token")
61
+ return access_token
62
+
63
+ # =========================
64
+ # FETCH SAP DATA
65
+ # =========================
66
+ def fetch_sap_data():
67
+ global access_token
68
+
69
+ if not access_token:
70
+ generate_token()
71
+
72
+ headers = {
73
+ "Authorization": f"Bearer {access_token}",
74
+ "Accept": "application/json"
75
+ }
76
+
77
+ res1 = requests.get(cap_service_url_customers, headers=headers)
78
+ res2 = requests.get(cap_service_url_products, headers=headers)
79
+ res3 = requests.get(cap_service_url_saleorders, headers=headers)
80
+ res4 = requests.get(cap_service_url_saleorderitems, headers=headers)
81
+
82
+ # Retry if token expired
83
+ if res1.status_code in [401, 403]:
84
+ access_token = None
85
+ generate_token()
86
+ headers["Authorization"] = f"Bearer {access_token}"
87
+
88
+ res1 = requests.get(cap_service_url_customers, headers=headers)
89
+ res2 = requests.get(cap_service_url_products, headers=headers)
90
+ res3 = requests.get(cap_service_url_saleorders, headers=headers)
91
+ res4 = requests.get(cap_service_url_saleorderitems, headers=headers)
92
+
93
+ df_customers = pd.DataFrame(res1.json()["value"])
94
+ df_products = pd.DataFrame(res2.json()["value"])
95
+ df_saleorders = pd.DataFrame(res3.json()["value"])
96
+ df_saleorderitems = pd.DataFrame(res4.json()["value"])
97
+
98
+ # Reduce columns (IMPORTANT for speed)
99
+ df_customers = df_customers[["ID","name","country","industry"]]
100
+ df_products = df_products[["ID","name","category","price","currency"]]
101
+ df_saleorders = df_saleorders[["ID","customer_ID","orderDate","status"]]
102
+ df_saleorderitems = df_saleorderitems[["ID","parent_ID","product_ID","quantity","netAmount"]]
103
+
104
+ return df_customers, df_products, df_saleorders, df_saleorderitems
105
+
106
+ # =========================
107
+ # CACHE FUNCTION
108
+ # =========================
109
+ def get_cached_data():
110
+ global cached_data, last_refresh
111
+
112
+ # Refresh every 5 minutes
113
+ if time.time() - last_refresh > 3000 or cached_data is None:
114
+ cached_data = fetch_sap_data()
115
+ last_refresh = time.time()
116
+
117
+ return cached_data
118
+
119
+ # =========================
120
+ # MAIN LLM FUNCTION
121
+ # =========================
122
+ def generate_response(user_prompt):
123
+ try:
124
+ df_customers, df_products, df_saleorders, df_saleorderitems = get_cached_data()
125
+
126
+ # Convert to compact text (IMPORTANT)
127
+ customers_text = df_customers.to_string(index=False)
128
+ products_text = df_products.to_string(index=False)
129
+ saleorders_text = df_saleorders.to_string(index=False)
130
+ saleorderitems_text = df_saleorderitems.to_string(index=False)
131
+
132
+ prompt = f"""
133
+ You are a Corporate SAP Assistant.
134
+
135
+ Customers:
136
+ {customers_text}
137
+
138
+ Products:
139
+ {products_text}
140
+
141
+ Orders:
142
+ {saleorders_text}
143
+
144
+ Order Items:
145
+ {saleorderitems_text}
146
+
147
+ Rules:
148
+ - Answer ONLY using given data
149
+ - If not found say: "I could not find that information in the current SAP database."
150
+ - Use bullet points
151
+
152
+ User: {user_prompt}
153
+ Assistant:
154
+ """
155
+
156
+ output = llm(
157
+ prompt,
158
+ max_tokens=100,
159
+ temperature=0.3,
160
+ top_p=0.7,
161
+ stop=["User:", "Assistant:"]
162
+ )
163
+
164
+ response = output["choices"][0]["text"].strip()
165
+ return response
166
+
167
+ except Exception as e:
168
+ return f"Error: {str(e)}"
169
+
170
+ # =========================
171
+ # GRADIO UI
172
+ # =========================
173
+ with gr.Blocks() as demo:
174
+
175
+ user_input = gr.Textbox(label="User Question")
176
+
177
+ output = gr.Textbox(label="Response")
178
+
179
+ btn = gr.Button("Generate")
180
+
181
+ btn.click(
182
+ fn=generate_response,
183
+ inputs=[user_input],
184
+ outputs=output,
185
+ api_name="predict"
186
+ )
187
+
188
+ # REQUIRED for API exposure
189
+ demo.queue()
190
+
191
+ demo.launch()