PanagiotisMark commited on
Commit
69ade12
Β·
verified Β·
1 Parent(s): 1c17745

Create gradio_app.py

Browse files
Files changed (1) hide show
  1. gradio_app.py +321 -0
gradio_app.py ADDED
@@ -0,0 +1,321 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import gradio as gr
3
+ import json
4
+ import pandas as pd
5
+ import requests as req
6
+
7
+ # Retrieve HF space secrets
8
+ auth_key = os.getenv('AUTH_KEY')
9
+ api_url = os.getenv('API_URL')
10
+ api_port = os.getenv('API_PORT')
11
+ FEEDBACK_IP = os.getenv('FEEDBACK_IP')
12
+ FEEDBACK_PORT = os.getenv('FEEDBACK_PORT')
13
+ FEEDBACK_PATH = os.getenv('FEEDBACK_PATH')
14
+ API_KEY = os.getenv('API_KEY')
15
+
16
+ HEADERS = {
17
+ 'Content-Type': 'application/json'
18
+ }
19
+
20
+ # Define feedback function to send like/dislike feedback
21
+ def send_feedback(request_data, response_data, like_reaction, dislike_reaction):
22
+ print("Sending feedback...", request_data, response_data, like_reaction, dislike_reaction)
23
+ # Construct the feedback payload
24
+ feedback_payload = {
25
+ "tool_id": 3,
26
+ "request": json.dumps(request_data),
27
+ "result": json.dumps(response_data),
28
+ "like": like_reaction,
29
+ "dislike": dislike_reaction
30
+ }
31
+ headers = {
32
+ 'Content-Type': 'application/json',
33
+ 'x-api-key': API_KEY
34
+ }
35
+ try:
36
+ # Construct feedback URL and send the POST request
37
+ feedback_url = f"http://{FEEDBACK_IP}:{FEEDBACK_PORT}{FEEDBACK_PATH}"
38
+ response = req.post(feedback_url, json=feedback_payload, headers=headers)
39
+ response.raise_for_status() # Raise an error for bad responses
40
+ print("Feedback sent successfully.")
41
+ return {"message": "Feedback sent successfully"}
42
+ except req.RequestException as e:
43
+ print("Error sending feedback:", e)
44
+ return {"error": str(e)}
45
+
46
+ # Define feedback toggle functionality
47
+ def toggle_feedback(request_data, response_data, like_clicked, dislike_clicked):
48
+ print("Toggling feedback...", like_clicked, dislike_clicked)
49
+
50
+ # Determine feedback type
51
+ like_reaction = True if like_clicked else False
52
+ dislike_reaction = True if dislike_clicked else False
53
+
54
+ # Send feedback to the backend
55
+ feedback_response = send_feedback(request_data, response_data, like_reaction, dislike_reaction)
56
+
57
+ # Return appropriate message based on the feedback response
58
+ if 'error' in feedback_response:
59
+ return f"Failed to send feedback: {feedback_response['error']}"
60
+ else:
61
+ return "Feedback sent successfully!"
62
+
63
+ # Define the functions to handle the inputs and outputs
64
+ def news_analysis(text):
65
+ try:
66
+ response = req.post(
67
+ f"{api_url}:{api_port}/news_analysis",
68
+ json={
69
+ 'doc_id': '1',
70
+ 'text': text,
71
+ 'auth_key': auth_key
72
+ },
73
+ headers=HEADERS
74
+ )
75
+ response.raise_for_status()
76
+ # Prepare results for JSON output
77
+ json_results = response.json()
78
+ # Normalize the JSON data
79
+ dataframe_results = pd.json_normalize(json_results, sep='_')
80
+ return json_results, dataframe_results
81
+ except Exception as e:
82
+ results = {'error': str(e)}
83
+ return results, pd.DataFrame()
84
+
85
+ def claim_verification(text):
86
+ try:
87
+ response = req.post(
88
+ f"{api_url}:{api_port}/claim_verification",
89
+ json={
90
+ 'doc_id': '1',
91
+ 'text': text,
92
+ 'auth_key': auth_key
93
+ },
94
+ headers=HEADERS
95
+ )
96
+ response.raise_for_status()
97
+ # Prepare results for JSON output
98
+ json_results = response.json()
99
+ # Normalize the JSON data
100
+ dataframe_results = pd.json_normalize(json_results, sep='_')
101
+ return json_results, dataframe_results
102
+ except Exception as e:
103
+ results = {'error': str(e)}
104
+ return results, pd.DataFrame()
105
+
106
+ # Define reusable feedback and export binding function
107
+ def bind_feedback_buttons(like_button, dislike_button, json_output, feedback_message):
108
+ like_button.click(
109
+ toggle_feedback,
110
+ inputs=[json_output, json_output, gr.Textbox(visible=False, value='True'), gr.Textbox(visible=False, value='False')],
111
+ outputs=[feedback_message]
112
+ )
113
+
114
+ dislike_button.click(
115
+ toggle_feedback,
116
+ inputs=[json_output, json_output, gr.Textbox(visible=False, value='False'), gr.Textbox(visible=False, value='True')],
117
+ outputs=[feedback_message]
118
+ )
119
+
120
+ def bind_export_buttons(export_csv_button, export_json_button, table_output, json_output):
121
+ export_csv_button.click(
122
+ export_results,
123
+ inputs=[table_output, gr.Textbox(visible=False, value='csv'), json_output],
124
+ outputs=[gr.File()]
125
+ )
126
+
127
+ export_json_button.click(
128
+ export_results,
129
+ inputs=[table_output, gr.Textbox(visible=False, value='json'), json_output],
130
+ outputs=[gr.File()]
131
+ )
132
+
133
+ # export function for results
134
+ def export_results(results, export_type, original_json):
135
+ print("Exporting results...", export_type)
136
+ try:
137
+ if export_type == 'csv':
138
+ # Ensure results is a DataFrame before exporting
139
+ try:
140
+ if not isinstance(results, pd.DataFrame):
141
+ results = pd.DataFrame(results)
142
+ except ValueError as e:
143
+ print("Error converting results to DataFrame:", e)
144
+ return gr.File(None), f"Error: Unable to convert results to DataFrame - {str(e)}"
145
+
146
+ csv_file_path = "exported_results.csv"
147
+ results.to_csv(csv_file_path, index=False)
148
+ print("CSV export successful:", csv_file_path)
149
+ return gr.File(csv_file_path)
150
+
151
+ elif export_type == 'json':
152
+ # Ensure original_json is serializable
153
+ if not isinstance(original_json, (dict, list)):
154
+ raise ValueError("Invalid data for JSON export")
155
+
156
+ json_file_path = "exported_results.json"
157
+ with open(json_file_path, "w") as f:
158
+ json.dump(original_json, f, indent=4)
159
+ print("JSON export successful:", json_file_path)
160
+ return gr.File(json_file_path)
161
+
162
+ else:
163
+ print("Error: Unsupported export type or no data available.")
164
+ return gr.File(None), "Error: Unsupported export type or no data available."
165
+ except (IOError, ValueError) as e:
166
+ print("Error during export:", e)
167
+ return gr.File(None), f"Error: {str(e)}"
168
+
169
+ # CSS for styling the interface
170
+ common_css = """
171
+ .unpadded_box {
172
+ display: none !important;
173
+ }
174
+
175
+ #like-dislike-container, #claim-like-dislike-container {
176
+ display: flex;
177
+ justify-content: flex-start;
178
+ margin-top: 20px; /* Increased margin to add more space between rows */
179
+ gap: 15px; /* Add gap between like and dislike buttons */
180
+ }
181
+
182
+ #like-btn, #dislike-btn, #like-claim-btn, #dislike-claim-btn, #export-csv-btn, #export-json-btn,
183
+ #export-claim-csv-btn, #export-claim-json-btn, #submit-btn, #submit-claim-btn {
184
+ background-color: #e0e0e0;
185
+ font-size: 18px;
186
+ border-radius: 8px;
187
+ padding: 12px; /* Increased padding for better look and feel */
188
+ margin: 10px; /* Added margin for spacing between buttons */
189
+ max-width: 250px;
190
+ cursor: pointer;
191
+ border: 1px solid transparent;
192
+ transition: background-color 0.3s, box-shadow 0.3s; /* Smooth hover transition */
193
+ }
194
+
195
+ #like-btn:hover, #dislike-btn:hover, #like-claim-btn:hover, #dislike-claim-btn:hover,
196
+ #submit-btn:hover, #submit-claim-btn:hover, #export-csv-btn:hover, #export-json-btn:hover,
197
+ #export-claim-csv-btn:hover, #export-claim-json-btn:hover {
198
+ background-color: #d0d0d0;
199
+ box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.1); /* Add shadow on hover for depth effect */
200
+ }
201
+
202
+ .active {
203
+ background-color: #c0c0c0;
204
+ font-weight: bold;
205
+ border-color: #000;
206
+ }
207
+
208
+ .feedback-message {
209
+ font-size: 16px; /* Slightly larger for readability */
210
+ color: #4CAF50;
211
+ margin-top: 10px; /* Space between feedback message and buttons */
212
+ }
213
+
214
+ .gr-textbox, .gr-markdown {
215
+ margin-top: 15px; /* Space between input elements and titles */
216
+ }
217
+
218
+ #export-container {
219
+ margin-top: 20px; /* Add space above the export container */
220
+ gap: 15px; /* Add gap between export buttons */
221
+ }
222
+
223
+ .output-container {
224
+ margin-top: 30px; /* Add space above the output container */
225
+ }
226
+
227
+ .gr-row {
228
+ margin-top: 20px; /* Spacing for each row */
229
+ }
230
+ """
231
+
232
+ # Define the interface for the first tab (News Analysis)
233
+ with gr.Blocks(css=common_css) as news_analysis_mode:
234
+ # Input fields for news analysis
235
+ gr.Markdown("### News Analysis")
236
+ gr.Markdown("Classify the domain of a news article and detect major claims.")
237
+ news_text_input = gr.Textbox(lines=10, label="News Article Text", placeholder="Enter the news article text")
238
+ news_submit_button = gr.Button("Submit", elem_id="submit-btn")
239
+
240
+ # Group related elements in a single container
241
+ with gr.Group(visible=False, elem_id="output-container") as output_container:
242
+ # Output fields for displaying results
243
+ table_output = gr.DataFrame(label="Table View", elem_id="table_view", interactive=False)
244
+ json_view_output = gr.JSON(label="JSON View", elem_id="json_view")
245
+
246
+ # Feedback buttons container for user reaction
247
+ reaction_label = gr.Markdown("**Reaction**")
248
+ with gr.Row(elem_id="like-dislike-container"):
249
+ like_button = gr.Button("πŸ‘ Like", elem_id="like-btn")
250
+ dislike_button = gr.Button("πŸ‘Ž Dislike", elem_id="dislike-btn")
251
+ feedback_message = gr.Markdown("")
252
+
253
+ # Export options container
254
+ export_label = gr.Markdown("**Export Options**")
255
+ with gr.Row(elem_id="export-container"):
256
+ export_csv_button = gr.Button("πŸ“„ Export as CSV", elem_id="export-csv-btn")
257
+ export_json_button = gr.Button("πŸ“ Export as JSON", elem_id="export-json-btn")
258
+
259
+ # Bind export buttons to export function for News Analysis mode
260
+ bind_export_buttons(export_csv_button, export_json_button, table_output, json_view_output)
261
+
262
+ # Bind submit button to analyze input function
263
+ news_submit_button.click(
264
+ news_analysis,
265
+ inputs=[news_text_input],
266
+ outputs=[json_view_output, table_output] # Ensure both outputs are specified here
267
+ ).then(
268
+ lambda: gr.update(visible=True), # Show entire container after the first request
269
+ inputs=[],
270
+ outputs=[output_container]
271
+ )
272
+
273
+ # Bind feedback buttons for News Analysis Mode
274
+ bind_feedback_buttons(like_button, dislike_button, json_view_output, feedback_message)
275
+
276
+ # Define the interface for the second tab (Claim Verification)
277
+ with gr.Blocks(css=common_css) as claim_verification_mode:
278
+ gr.Markdown("### Claim Verification")
279
+ gr.Markdown("Verify claims made in a news article.")
280
+ claim_text_input = gr.Textbox(lines=10, label="Claim Text", placeholder="Enter the claim text")
281
+ claim_submit_button = gr.Button("Submit", elem_id="submit-claim-btn")
282
+
283
+ # Group related elements in a single container
284
+ with gr.Group(visible=False) as claim_output_container:
285
+ table_claim_output = gr.DataFrame(label="Table View", elem_id="table_view_claim", interactive=False)
286
+ json_claim_output = gr.JSON(label="JSON View", elem_id="json_view_claim")
287
+
288
+ claim_reaction_label = gr.Markdown("**Reaction**")
289
+ with gr.Row(elem_id="claim-like-dislike-container"):
290
+ like_claim_button = gr.Button("πŸ‘ Like", elem_id="like-claim-btn")
291
+ dislike_claim_button = gr.Button("πŸ‘Ž Dislike", elem_id="dislike-claim-btn")
292
+ claim_feedback_message = gr.Markdown("")
293
+
294
+ claim_export_label = gr.Markdown("**Export Options**")
295
+ with gr.Row(elem_id="export-claim-container"):
296
+ export_claim_csv_button = gr.Button("πŸ“„ Export as CSV", elem_id="export-claim-csv-btn")
297
+ export_claim_json_button = gr.Button("πŸ“ Export as JSON", elem_id="export-claim-json-btn")
298
+
299
+ # Bind the submit button to the function for verifying the claim text
300
+ claim_submit_button.click(
301
+ claim_verification,
302
+ inputs=[claim_text_input],
303
+ outputs=[json_claim_output, table_claim_output]
304
+ ).then(
305
+ lambda: gr.update(visible=True), # Show entire container after the first request
306
+ inputs=[],
307
+ outputs=[claim_output_container]
308
+ )
309
+
310
+ # Bind feedback buttons for Claim Verification Mode
311
+ bind_feedback_buttons(like_claim_button, dislike_claim_button, json_claim_output, claim_feedback_message)
312
+
313
+ # Bind export buttons to export function for Claim Verification Mode
314
+ bind_export_buttons(export_claim_csv_button, export_claim_json_button, table_claim_output, json_claim_output)
315
+
316
+ # Combine the tabs into one interface
317
+ with gr.Blocks(css=common_css) as demo:
318
+ gr.TabbedInterface([news_analysis_mode, claim_verification_mode], ["News Analysis", "Claim Verification"])
319
+
320
+ # Launch the interface
321
+ demo.queue().launch(server_name="0.0.0.0", server_port=7860)