LogicDataSolutions commited on
Commit
c551113
·
verified ·
1 Parent(s): 81f58e5

Upload app.py

Browse files

Updated to use blocks.
Added additonal CPA colors.

Files changed (1) hide show
  1. app.py +287 -110
app.py CHANGED
@@ -1,111 +1,288 @@
1
- import gradio as gr
2
- import requests
3
- import os
4
- from fastapi import FastAPI
5
- from fastapi.middleware.cors import CORSMiddleware
6
- from ping import add_ping_route
7
-
8
-
9
- # Configuration
10
- LANGFLOW_API_URL = os.environ.get("LANGFLOW_API_URL", "")
11
- LANGFLOW_API_KEY = os.environ.get("LANGFLOW_API_KEY", "")
12
- HF_API_KEY = os.environ.get("HF_API_KEY", "")
13
-
14
- if not LANGFLOW_API_URL:
15
- print("FATAL: LANGFLOW_API_URL secret not found or is empty.")
16
- else:
17
- print("SUCCESS: LANGFLOW_API_URL loaded securely.")
18
-
19
- if not LANGFLOW_API_KEY:
20
- print("FATAL: LANGFLOW_API_KEY secret not found or is empty.")
21
- else:
22
- print("SUCCESS: LANGFLOW_API_KEY loaded securely.")
23
-
24
- if not HF_API_KEY:
25
- print("FATAL: HF_API_KEY secret not found or is empty.")
26
- else:
27
- print("SUCCESS: HF_API_KEY loaded securely.")
28
-
29
-
30
-
31
-
32
- # Function that calls the LangFlow chat
33
- def call_langflow(message, history):
34
- """
35
- Call Langflow API and return the response
36
- """
37
- headers = {
38
- "Content-Type": "application/json",
39
- }
40
-
41
- # Add API keys
42
- if HF_API_KEY:
43
- headers["Authorization"] = f"Bearer {HF_API_KEY}"
44
- if LANGFLOW_API_KEY:
45
- headers["x-api-key"] = f"{LANGFLOW_API_KEY}"
46
-
47
-
48
- # Adjust this payload based on your Langflow API structure
49
- payload = {
50
- "input_value": message,
51
- "output_type": "chat",
52
- "input_type": "chat",
53
- "tweaks": {}
54
- }
55
-
56
- try:
57
- response = requests.post(
58
- LANGFLOW_API_URL,
59
- json=payload,
60
- headers=headers,
61
- timeout=30
62
- )
63
- response.raise_for_status()
64
-
65
- # Parse response - adjust based on your API response structure
66
- data = response.json()
67
-
68
- # Common Langflow response structures:
69
- # Option 1: data["outputs"][0]["outputs"][0]["results"]["message"]["text"]
70
- # Option 2: data["result"]["message"]
71
- # Adjust the following line based on your actual response:
72
-
73
- bot_message = data["outputs"][0]["outputs"][0]["results"]["message"]["text"]
74
- return bot_message
75
-
76
- except requests.exceptions.RequestException as e:
77
- return f"Error connecting to Langflow: {str(e)}"
78
- except (KeyError, IndexError) as e:
79
- return f"Error parsing response: {str(e)}\nResponse: {data}"
80
-
81
- #Create FastAPI App for health check.
82
- fastapi_app = FastAPI(title="Chatbot with Ping API")
83
- # Optional CORS setup
84
- fastapi_app.add_middleware(
85
- CORSMiddleware,
86
- allow_origins=["*"],
87
- allow_credentials=True,
88
- allow_methods=["*"],
89
- allow_headers=["*"],
90
- )
91
- # Add /ping route from ping.py
92
- add_ping_route(fastapi_app, call_langflow)
93
-
94
-
95
-
96
- # Create Gradio Chat Interface
97
- chatui = gr.ChatInterface(
98
- fn=call_langflow,
99
- #title="CPA Chatbot POC",
100
- description="You can use this chatbot to answer questions related to Crown Pointe Academy policies.",
101
- examples=["Summarize the school's uniform policy", "Can a student wear earrings?"],
102
- css="""
103
- footer {display: none !important;}
104
- .footer {display: none !important;}
105
- #footer {display: none !important;}
106
- .svelte-1p1dq6v {display: none !important;}
107
- """
108
- )
109
-
110
- # Mount Gradio app to FastAPI at root path
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
111
  app = gr.mount_gradio_app(fastapi_app, chatui, path="/")
 
1
+ import gradio as gr
2
+ import requests
3
+ import os
4
+ from fastapi import FastAPI
5
+ from fastapi.middleware.cors import CORSMiddleware
6
+ from ping import add_ping_route
7
+
8
+ # ===== THEME COLOR VARIABLES =====
9
+ PRIMARY_COLOR = "#13406B" # CPA Dark Corporate Blue
10
+ SECONDARY_COLOR = "#CD9D5B" # CPA Muted Bronze/Tan
11
+ BACKGROUND_COLOR = "#f8fafc" # Light gray - page background
12
+ TEXT_COLOR = "#1e293b" # Dark slate - text color
13
+
14
+ # Configuration
15
+ LANGFLOW_API_URL = os.environ.get("LANGFLOW_API_URL", "")
16
+ LANGFLOW_API_KEY = os.environ.get("LANGFLOW_API_KEY", "")
17
+ HF_API_KEY = os.environ.get("HF_API_KEY", "")
18
+
19
+ if not LANGFLOW_API_URL:
20
+ print("FATAL: LANGFLOW_API_URL secret not found or is empty.")
21
+ else:
22
+ print("SUCCESS: LANGFLOW_API_URL loaded securely.")
23
+
24
+ if not LANGFLOW_API_KEY:
25
+ print("FATAL: LANGFLOW_API_KEY secret not found or is empty.")
26
+ else:
27
+ print("SUCCESS: LANGFLOW_API_KEY loaded securely.")
28
+
29
+ if not HF_API_KEY:
30
+ print("FATAL: HF_API_KEY secret not found or is empty.")
31
+ else:
32
+ print("SUCCESS: HF_API_KEY loaded securely.")
33
+
34
+
35
+ # Function that calls the LangFlow chat
36
+ def call_langflow_api(message):
37
+ """
38
+ Call Langflow API and return the response
39
+ """
40
+ headers = {
41
+ "Content-Type": "application/json",
42
+ }
43
+
44
+ # Add API keys
45
+ if HF_API_KEY:
46
+ headers["Authorization"] = f"Bearer {HF_API_KEY}"
47
+ if LANGFLOW_API_KEY:
48
+ headers["x-api-key"] = f"{LANGFLOW_API_KEY}"
49
+
50
+ # Adjust this payload based on your Langflow API structure
51
+ payload = {
52
+ "input_value": message,
53
+ "output_type": "chat",
54
+ "input_type": "chat",
55
+ "tweaks": {}
56
+ }
57
+
58
+ try:
59
+ response = requests.post(
60
+ LANGFLOW_API_URL,
61
+ json=payload,
62
+ headers=headers,
63
+ timeout=30
64
+ )
65
+ response.raise_for_status()
66
+
67
+ # Parse response - adjust based on your API response structure
68
+ data = response.json()
69
+
70
+ bot_message = data["outputs"][0]["outputs"][0]["results"]["message"]["text"]
71
+ return bot_message
72
+
73
+ except requests.exceptions.RequestException as e:
74
+ return f"Error connecting to Langflow: {str(e)}"
75
+ except (KeyError, IndexError) as e:
76
+ return f"Error parsing response: {str(e)}\nResponse: {data}"
77
+
78
+
79
+ #Create FastAPI App for health check.
80
+ fastapi_app = FastAPI(title="Chatbot with Ping API")
81
+ # Optional CORS setup
82
+ fastapi_app.add_middleware(
83
+ CORSMiddleware,
84
+ allow_origins=["*"],
85
+ allow_credentials=True,
86
+ allow_methods=["*"],
87
+ allow_headers=["*"],
88
+ )
89
+ # Add /ping route from ping.py
90
+ add_ping_route(fastapi_app, call_langflow_api)
91
+
92
+
93
+ # Custom CSS using theme variables
94
+ custom_css = f"""
95
+ /* Hide footer */
96
+ footer {{display: none !important;}}
97
+ .footer {{display: none !important;}}
98
+ #footer {{display: none !important;}}
99
+ .svelte-1p1dq6v {{display: none !important;}}
100
+
101
+ /* Main container background */
102
+ .gradio-container {{
103
+ background-color: {BACKGROUND_COLOR} !important;
104
+ font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
105
+ }}
106
+
107
+ /* Chatbot container styling */
108
+ #chatbot-window {{
109
+ background-color: {BACKGROUND_COLOR} !important;
110
+ border-radius: 12px !important;
111
+ box-shadow: 0 2px 8px rgba(0,0,0,0.1) !important;
112
+ border: 2px solid {PRIMARY_COLOR} !important;
113
+ }}
114
+ #chatbot-window .placeholder-content {{
115
+ background-color: {BACKGROUND_COLOR} !important;
116
+ }}
117
+ #chatbot-window .bubble-wrap {{
118
+ background-color: {BACKGROUND_COLOR} !important;
119
+ }}
120
+
121
+ /* Description text */
122
+ .description {{
123
+ color: {TEXT_COLOR} !important;
124
+ font-size: 16px !important;
125
+ margin-bottom: 20px !important;
126
+ }}
127
+
128
+ /* User messages */
129
+ #chatbot-window .message.user {{
130
+ background-color: {SECONDARY_COLOR} !important;
131
+ color: white !important;
132
+ border: none !important;
133
+ }}
134
+ #chatbot-window .flex-wrap {{
135
+ border: none !important;
136
+ }}
137
+ #chatbot-window .message.user p{{
138
+ color: white !important;
139
+ }}
140
+
141
+
142
+ /* Bot messages */
143
+ #chatbot-window .message.bot {{
144
+ background-color: {PRIMARY_COLOR} !important;
145
+ color: white !important;
146
+ border: none !important;
147
+ }}
148
+ #chatbot-window .message.bot p{{
149
+ color: white !important;
150
+ }}
151
+
152
+ /* Input textbox */
153
+ #input-textbox {{
154
+ background-color: {BACKGROUND_COLOR} !important;
155
+ }}
156
+
157
+ #input-textbox textarea{{
158
+ border: 2px solid {SECONDARY_COLOR} !important;
159
+ border-radius: 8px !important;
160
+ font-size: 16px !important;
161
+ color: {TEXT_COLOR} !important;
162
+ background-color: {BACKGROUND_COLOR} !important;
163
+ }}
164
+
165
+ #input-textbox textarea:focus {{
166
+ border-color: {PRIMARY_COLOR} !important;
167
+ box-shadow: 0 0 0 3px rgba(19, 64, 107, 0.1) !important;
168
+ }}
169
+
170
+ /* Buttons */
171
+ button {{
172
+ border-radius: 8px !important;
173
+ font-weight: 600 !important;
174
+ }}
175
+
176
+
177
+ /* Primary buttons (Send) */
178
+ #send-button {{
179
+ background-color: {PRIMARY_COLOR} !important;
180
+ color: white !important;
181
+ border: none !important;
182
+ }}
183
+
184
+ #send-button:hover {{
185
+ background-color: {SECONDARY_COLOR} !important;
186
+ }}
187
+
188
+ /* Secondary buttons (Clear) */
189
+ button.secondary {{
190
+ background-color: white !important;
191
+ color: {PRIMARY_COLOR} !important;
192
+ border: 2px solid {SECONDARY_COLOR} !important;
193
+ }}
194
+
195
+ button.secondary:hover {{
196
+ background-color: {BACKGROUND_COLOR} !important;
197
+ }}
198
+
199
+ /* Example buttons */
200
+ #example-buttons button {{
201
+ background-color: {PRIMARY_COLOR} !important;
202
+ color: white !important;
203
+ border: 2px solid {SECONDARY_COLOR} !important;
204
+ border-radius: 8px !important;
205
+ font-weight: 500 !important;
206
+ }}
207
+
208
+ #example-buttons button:hover {{
209
+ background-color: {SECONDARY_COLOR} !important;
210
+ }}
211
+
212
+ /* Example label text */
213
+ #example-buttons .label {{
214
+ color: {TEXT_COLOR} !important;
215
+ font-size: 16px !important;
216
+ }}
217
+ """
218
+
219
+
220
+ # Create custom Gradio interface with Blocks
221
+ with gr.Blocks(css=custom_css, analytics_enabled=False) as chatui:
222
+
223
+ # Description
224
+ gr.Markdown(
225
+ "Ask Cosmo the cougar questions related to Crown Pointe Academy policies.",
226
+ elem_classes="description"
227
+ )
228
+
229
+ # Chatbot component - MUST use type='messages'
230
+ chatbot = gr.Chatbot(
231
+ type='messages',
232
+ height=500,
233
+ elem_classes="chatbot",
234
+ elem_id="chatbot-window"
235
+ )
236
+
237
+ # Input row
238
+ with gr.Row():
239
+ msg = gr.Textbox(
240
+ label="",
241
+ placeholder="Type your message here...",
242
+ scale=4,
243
+ show_label=False,
244
+ elem_id="input-textbox"
245
+ )
246
+ submit = gr.Button(
247
+ "Send",
248
+ scale=1,
249
+ variant="primary",
250
+ elem_id="send-button"
251
+ )
252
+
253
+ # Example buttons
254
+ gr.Examples(
255
+ examples=[
256
+ "Summarize the school's uniform policy",
257
+ "Can a student wear earrings?"
258
+ ],
259
+ inputs=msg,
260
+ label="Try these examples:",
261
+ elem_id="example-buttons"
262
+ )
263
+
264
+ # Clear button
265
+ clear = gr.Button("Clear Chat", variant="secondary")
266
+
267
+ # Chat logic for messages format
268
+ def respond(message, chat_history):
269
+ if not message.strip():
270
+ return "", chat_history
271
+
272
+ # Get bot response
273
+ bot_message = call_langflow_api(message)
274
+
275
+ # Append messages in the new format
276
+ chat_history.append({"role": "user", "content": message})
277
+ chat_history.append({"role": "assistant", "content": bot_message})
278
+
279
+ return "", chat_history
280
+
281
+ # Event handlers - mark as non-API to avoid schema issues
282
+ msg.submit(respond, [msg, chatbot], [msg, chatbot], api_name=False)
283
+ submit.click(respond, [msg, chatbot], [msg, chatbot], api_name=False)
284
+ clear.click(lambda: [], None, chatbot, queue=False, api_name=False)
285
+
286
+
287
+ # Mount Gradio app to FastAPI at root path
288
  app = gr.mount_gradio_app(fastapi_app, chatui, path="/")