heymenn commited on
Commit
8d05399
·
verified ·
1 Parent(s): 3fef2d2

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +188 -74
app.py CHANGED
@@ -45,21 +45,75 @@ async def process_constraints(constraints: InputConstraints):
45
 
46
 
47
  def make_json_serializable(data):
48
- """
49
- Recursively convert tensors to floats in a data structure
50
- so it can be passed to json.dumps.
51
- """
52
  if isinstance(data, dict):
53
  return {k: make_json_serializable(v) for k, v in data.items()}
54
  elif isinstance(data, list):
55
  return [make_json_serializable(item) for item in data]
56
  elif isinstance(data, tuple):
57
  return tuple(make_json_serializable(item) for item in data)
58
- elif hasattr(data, 'item'): # torch.Tensor with single value
59
  return float(data.item())
60
  else:
61
  return data
62
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
63
  def process_input_gradio(problem_description: str):
64
  """
65
  Processes the input problem description step-by-step for Gradio.
@@ -95,49 +149,38 @@ def process_input_gradio(problem_description: str):
95
  best_technologies = get_technologies_by_id(best_technologies_id, global_tech)
96
 
97
  # Format outputs for Gradio
98
- matrix_display = matrix #.tolist() # Convert numpy array to list of lists for better Gradio display
 
 
 
 
 
 
 
 
99
 
100
- result_similarities_display = {
101
- item['id2']: f"{item['constraint']['title']} ({item['similarity'].item():.3f})"
102
- for item in result_similarities
103
- }
104
-
105
-
106
- # Convert to JSON-safe format
107
- safe_best_combinations = make_json_serializable(best_combinations)
108
- safe_best_technologies = make_json_serializable(best_technologies)
109
-
110
- # Now this will work safely:
111
- best_combinations_display = json.dumps(safe_best_combinations, indent=2)
112
- best_technologies_display = json.dumps(safe_best_technologies, indent=2)
113
-
114
- print("best combinations")
115
- print(best_combinations_display)
116
- print("\nbest technologies")
117
- print(best_technologies_display)
118
-
119
  return (
120
  prompt,
121
- "\n".join(f"'{k}': {v}" for k, v in constraints.items()),
122
- best_combinations_display,
123
- ", ".join(map(str, best_technologies_id)),
124
- best_technologies_display
125
  )
126
 
 
127
  # --- Gradio Interface Setup ---
128
- # Define the input and output components
129
  input_problem = gr.Textbox(
130
  label="Enter Problem Description",
131
  placeholder="e.g., Develop a secure and scalable e-commerce platform with real-time analytics."
132
  )
133
 
134
  output_prompt = gr.Textbox(label="1. Generated Prompt", interactive=False)
135
- output_constraints = gr.Textbox(label="2. Retrieved Constraints", interactive=False)
136
- output_best_combinations = gr.JSON(label="7. Best Technology Combinations Found")
137
  output_selected_ids = gr.Textbox(label="8. Selected Technology IDs", interactive=False)
138
- output_final_technologies = gr.JSON(label="9. Final Best Technologies")
139
 
140
- # Custom CSS for a professional look
141
  custom_css = """
142
  /* General Body and Font Styling */
143
  body {
@@ -225,20 +268,105 @@ body {
225
  font-size: 1.1em;
226
  }
227
 
228
- /* JSON Output Specific Styling */
229
- .gradio-container .json-display {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
230
  background-color: #f8f9fa;
 
231
  border: 1px solid #e9ecef;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
232
  border-radius: 8px;
233
  padding: 15px;
234
- font-family: 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, Courier, monospace;
235
- color: #212529;
236
- white-space: pre-wrap; /* Preserve whitespace and wrap long lines */
237
- overflow-x: auto; /* Allow horizontal scrolling if content is too wide */
238
- max-height: 400px; /* Limit height and add scroll */
 
 
 
 
 
 
 
 
 
239
  }
240
 
241
- /* Responsive adjustments (Gradio handles a lot, but for specific tweaks) */
 
 
 
 
 
 
 
 
 
 
242
  @media (max-width: 768px) {
243
  .gradio-container {
244
  padding: 15px;
@@ -250,53 +378,41 @@ body {
250
  width: 100%;
251
  padding: 15px;
252
  }
 
 
 
253
  }
254
-
255
- /* Optional: Logo and Branding Placeholder */
256
- /* You would typically add an image element in your gr.Blocks() for a logo */
257
- /* Example if you have a logo image: */
258
- /* .logo {
259
- display: block;
260
- margin: 0 auto 20px auto;
261
- max-width: 200px;
262
- height: auto;
263
- } */
264
  """
265
 
266
  # Create the Gradio Blocks demo with custom theme and CSS
267
  with gr.Blocks(
268
- theme=gr.themes.Soft(), # A modern, soft theme from Gradio
269
  css=custom_css
270
  ) as gradio_app_blocks:
271
- # Optional: Add your logo here
272
- # gr.Image("path/to/your/logo.png", width=150, show_label=False, container=False, elem_classes="logo")
273
-
274
  gr.Markdown("# Insight Finder: Step-by-Step Technology Selection")
275
  gr.Markdown("## Enter a problem description to see how relevant technologies are identified through various processing steps.")
276
 
277
- with gr.Row(): # Use a row for better layout on wider screens
278
- with gr.Column(scale=2): # Input takes more space
279
  input_problem.render()
280
- with gr.Column(scale=1): # Button in a smaller column
281
- gr.Markdown("Click to start the analysis:")
282
- process_button = gr.Button("Process Problem", elem_id="process_button")
283
-
284
-
285
- gr.Markdown("---") # Separator for visual clarity
286
 
 
287
  gr.Markdown("### Processing Steps & Results:")
288
 
289
- # Group outputs into columns for better organization
290
  with gr.Row():
291
  with gr.Column():
292
  output_prompt.render()
293
- output_constraints.render()
294
  with gr.Column():
295
- output_best_combinations.render()
296
- output_selected_ids.render()
297
- output_final_technologies.render()
298
 
299
- # Link the button to the processing function
300
  process_button.click(
301
  fn=process_input_gradio,
302
  inputs=input_problem,
@@ -307,6 +423,4 @@ with gr.Blocks(
307
  output_selected_ids,
308
  output_final_technologies
309
  ]
310
- )
311
-
312
- gr.mount_gradio_app(app, gradio_app_blocks, path="/gradio")
 
45
 
46
 
47
  def make_json_serializable(data):
 
 
 
 
48
  if isinstance(data, dict):
49
  return {k: make_json_serializable(v) for k, v in data.items()}
50
  elif isinstance(data, list):
51
  return [make_json_serializable(item) for item in data]
52
  elif isinstance(data, tuple):
53
  return tuple(make_json_serializable(item) for item in data)
54
+ elif hasattr(data, 'item'):
55
  return float(data.item())
56
  else:
57
  return data
58
+
59
+ # --- Helper functions to format HTML outputs ---
60
+ def format_constraints_html(constraints: dict) -> str:
61
+ html_content = "<div class='constraints-container'>"
62
+ for title, description in constraints.items():
63
+ html_content += f"""
64
+ <div class='constraint-item'>
65
+ <p><span class='constraint-title'>{title}:</span> <span class='constraint-description'>{description}</span></p>
66
+ </div>
67
+ """
68
+ html_content += "</div>"
69
+ return html_content
70
+
71
+ def format_best_combinations_html(combinations_data: list) -> str:
72
+ html_content = "<div class='combinations-outer-container'>"
73
+ for i, combination in enumerate(combinations_data):
74
+ problem_title = combination.get("problem", {}).get("title", f"Problem {i+1}")
75
+ technologies = combination.get("technologies", [])
76
+
77
+ html_content += f"""
78
+ <div class='problem-card'>
79
+ <h3 class='problem-card-title'>{problem_title}</h3>
80
+ <div class='technologies-inner-container'>
81
+ """
82
+ for tech_info_score in technologies:
83
+ tech_info = tech_info_score[0] # The dictionary part
84
+ if isinstance(tech_info, dict):
85
+ html_content += f"""
86
+ <div class='technology-card'>
87
+ <h4 class='tech-card-title'>{tech_info.get('title', 'N/A')}</h4>
88
+ <p><strong>Purpose:</strong> {tech_info.get('purpose', 'N/A')}</p>
89
+ <p><strong>Components:</strong> {tech_info.get('key_components', 'N/A')}</p>
90
+ <p><strong>Advantages:</strong> {tech_info.get('advantages', 'N/A')}</p>
91
+ <p><strong>Limitations:</strong> {tech_info.get('limitations', 'N/A')}</p>
92
+ </div>
93
+ """
94
+ html_content += """
95
+ </div>
96
+ </div>
97
+ """
98
+ html_content += "</div>"
99
+ return html_content
100
+
101
+ def format_final_technologies_html(technologies_list: list) -> str:
102
+ html_content = "<div class='final-tech-container'>"
103
+ for tech_info in technologies_list:
104
+ if isinstance(tech_info, dict):
105
+ html_content += f"""
106
+ <div class='final-tech-card'>
107
+ <h4 class='final-tech-title'>{tech_info.get('title', 'N/A')}</h4>
108
+ <p><strong>Purpose:</strong> {tech_info.get('purpose', 'N/A')}</p>
109
+ <p><strong>Components:</strong> {tech_info.get('key_components', 'N/A')}</p>
110
+ <p><strong>Advantages:</strong> {tech_info.get('advantages', 'N/A')}</p>
111
+ <p><strong>Limitations:</strong> {tech_info.get('limitations', 'N/A')}</p>
112
+ </div>
113
+ """
114
+ html_content += "</div>"
115
+ return html_content
116
+
117
  def process_input_gradio(problem_description: str):
118
  """
119
  Processes the input problem description step-by-step for Gradio.
 
149
  best_technologies = get_technologies_by_id(best_technologies_id, global_tech)
150
 
151
  # Format outputs for Gradio
152
+ # For Constraints:
153
+ constraints_html = format_constraints_html(constraints_dict)
154
+
155
+ # For Best Combinations:
156
+ best_combinations_html = format_best_combinations_html(best_combinations)
157
+
158
+ # For Final Technologies:
159
+ final_technologies_html = format_final_technologies_html(best_technologies)
160
+
161
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
162
  return (
163
  prompt,
164
+ constraints_html, # Output HTML for constraints
165
+ best_combinations_html, # Output HTML for best combinations
166
+ ", ".join(map(str, best_technologies_id)), # Still a simple text list
167
+ final_technologies_html # Output HTML for final technologies
168
  )
169
 
170
+
171
  # --- Gradio Interface Setup ---
 
172
  input_problem = gr.Textbox(
173
  label="Enter Problem Description",
174
  placeholder="e.g., Develop a secure and scalable e-commerce platform with real-time analytics."
175
  )
176
 
177
  output_prompt = gr.Textbox(label="1. Generated Prompt", interactive=False)
178
+ output_constraints = gr.HTML(label="2. Retrieved Constraints") # Changed to HTML
179
+ output_best_combinations = gr.HTML(label="7. Best Technology Combinations Found") # Changed to HTML
180
  output_selected_ids = gr.Textbox(label="8. Selected Technology IDs", interactive=False)
181
+ output_final_technologies = gr.HTML(label="9. Final Best Technologies") # Changed to HTML
182
 
183
+ # Custom CSS for a professional look and specific output styling
184
  custom_css = """
185
  /* General Body and Font Styling */
186
  body {
 
268
  font-size: 1.1em;
269
  }
270
 
271
+ /* --- Specific Styling for Outputs --- */
272
+
273
+ /* 2. Retrieved Constraints Styling */
274
+ .constraints-container {
275
+ padding: 15px;
276
+ background-color: #f8f9fa;
277
+ border-radius: 8px;
278
+ border: 1px solid #e9ecef;
279
+ font-family: 'Georgia', serif; /* Different font */
280
+ line-height: 1.6;
281
+ max-height: 300px;
282
+ overflow-y: auto;
283
+ }
284
+ .constraint-item {
285
+ margin-bottom: 10px;
286
+ padding-bottom: 10px;
287
+ border-bottom: 1px dashed #e0e0e0;
288
+ }
289
+ .constraint-item:last-child {
290
+ border-bottom: none;
291
+ margin-bottom: 0;
292
+ padding-bottom: 0;
293
+ }
294
+ .constraint-title {
295
+ font-weight: bold;
296
+ color: #004085; /* Darker blue for constraint titles */
297
+ font-size: 1.1em;
298
+ }
299
+ .constraint-description {
300
+ color: #333;
301
+ font-size: 1em;
302
+ }
303
+
304
+ /* 7. Best Technology Combinations Found & 9. Final Best Technologies Styling */
305
+ .combinations-outer-container, .final-tech-container {
306
+ padding: 15px;
307
  background-color: #f8f9fa;
308
+ border-radius: 8px;
309
  border: 1px solid #e9ecef;
310
+ max-height: 500px; /* Adjust as needed */
311
+ overflow-y: auto;
312
+ font-family: 'Trebuchet MS', 'Lucida Grande', 'Lucida Sans Unicode', 'Lucida Sans', Tahoma, sans-serif; /* Different font */
313
+ }
314
+
315
+ .problem-card {
316
+ background-color: #ffffff;
317
+ border: 1px solid #cfe2ff; /* Light blue border for problem card */
318
+ border-radius: 10px;
319
+ padding: 20px;
320
+ margin-bottom: 20px;
321
+ box-shadow: 0 4px 10px rgba(0, 0, 0, 0.05);
322
+ }
323
+ .problem-card-title {
324
+ color: #0056b3; /* Deep blue for problem title */
325
+ font-size: 1.4em;
326
+ margin-top: 0;
327
+ margin-bottom: 15px;
328
+ border-bottom: 2px solid #cfe2ff;
329
+ padding-bottom: 10px;
330
+ }
331
+
332
+ .technologies-inner-container {
333
+ display: grid;
334
+ grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); /* Responsive grid for technologies */
335
+ gap: 15px;
336
+ }
337
+
338
+ .technology-card, .final-tech-card {
339
+ background-color: #f0faff; /* Very light blue for technology cards */
340
+ border: 1px solid #b0d9ff; /* Slightly darker blue border */
341
  border-radius: 8px;
342
  padding: 15px;
343
+ box-shadow: 0 2px 5px rgba(0, 0, 0, 0.05);
344
+ transition: transform 0.2s ease-in-out;
345
+ }
346
+
347
+ .technology-card:hover, .final-tech-card:hover {
348
+ transform: translateY(-3px);
349
+ }
350
+
351
+ .tech-card-title, .final-tech-title {
352
+ color: #007bff; /* Gradio's primary blue */
353
+ font-size: 1.2em;
354
+ margin-top: 0;
355
+ margin-bottom: 10px;
356
+ font-weight: 600;
357
  }
358
 
359
+ .technology-card p, .final-tech-card p {
360
+ font-size: 0.95em;
361
+ line-height: 1.5;
362
+ margin-bottom: 5px;
363
+ color: #555;
364
+ }
365
+ .technology-card p strong, .final-tech-card p strong {
366
+ color: #004085; /* Darker blue for bold labels */
367
+ }
368
+
369
+ /* Responsive adjustments */
370
  @media (max-width: 768px) {
371
  .gradio-container {
372
  padding: 15px;
 
378
  width: 100%;
379
  padding: 15px;
380
  }
381
+ .technologies-inner-container {
382
+ grid-template-columns: 1fr; /* Stack columns on smaller screens */
383
+ }
384
  }
 
 
 
 
 
 
 
 
 
 
385
  """
386
 
387
  # Create the Gradio Blocks demo with custom theme and CSS
388
  with gr.Blocks(
389
+ theme=gr.themes.Soft(),
390
  css=custom_css
391
  ) as gradio_app_blocks:
 
 
 
392
  gr.Markdown("# Insight Finder: Step-by-Step Technology Selection")
393
  gr.Markdown("## Enter a problem description to see how relevant technologies are identified through various processing steps.")
394
 
395
+ with gr.Row():
396
+ with gr.Column(scale=2):
397
  input_problem.render()
398
+ with gr.Column(scale=1):
399
+ gr.Box(
400
+ gr.Markdown("Click to start the analysis:"),
401
+ process_button := gr.Button("Process Problem", elem_id="process_button")
402
+ )
 
403
 
404
+ gr.Markdown("---")
405
  gr.Markdown("### Processing Steps & Results:")
406
 
 
407
  with gr.Row():
408
  with gr.Column():
409
  output_prompt.render()
410
+ output_constraints.render() # Renders HTML
411
  with gr.Column():
412
+ output_selected_ids.render() # This remains a Textbox
413
+ output_best_combinations.render() # Renders HTML
414
+ output_final_technologies.render() # Renders HTML
415
 
 
416
  process_button.click(
417
  fn=process_input_gradio,
418
  inputs=input_problem,
 
423
  output_selected_ids,
424
  output_final_technologies
425
  ]
426
+ )