shukdevdatta123 commited on
Commit
3d9ad47
Β·
verified Β·
1 Parent(s): 8cc3aa8

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +214 -222
app.py CHANGED
@@ -79,203 +79,199 @@ def tavily_search(
79
  result = response.json()
80
 
81
  # Format the response as clean HTML
82
- html_result = """
83
- <!DOCTYPE html>
84
- <html>
85
- <head>
86
- <meta charset="UTF-8">
87
- <title>Tavily Search Results</title>
88
- <style>
89
- body {
90
- font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
91
- line-height: 1.6;
92
- color: #333;
93
- max-width: 1200px;
94
- margin: 0 auto;
95
- padding: 20px;
96
- background: #f8f9fa;
97
- }
98
- .container {
99
- background: white;
100
- border-radius: 12px;
101
- padding: 30px;
102
- box-shadow: 0 4px 6px rgba(0,0,0,0.1);
103
- }
104
- .header {
105
- border-bottom: 3px solid #4CAF50;
106
- padding-bottom: 20px;
107
- margin-bottom: 30px;
108
- }
109
- .search-title {
110
- color: #2c3e50;
111
- font-size: 28px;
112
- font-weight: 700;
113
- margin: 0;
114
- display: flex;
115
- align-items: center;
116
- gap: 10px;
117
- }
118
- .search-query {
119
- color: #7f8c8d;
120
- font-size: 16px;
121
- margin-top: 8px;
122
- font-style: italic;
123
- }
124
- .answer-section {
125
- background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
126
- color: white;
127
- padding: 25px;
128
- border-radius: 10px;
129
- margin-bottom: 30px;
130
- box-shadow: 0 4px 15px rgba(102, 126, 234, 0.3);
131
- }
132
- .answer-title {
133
- font-size: 20px;
134
- font-weight: 600;
135
- margin-bottom: 15px;
136
- display: flex;
137
- align-items: center;
138
- gap: 8px;
139
- }
140
- .answer-content {
141
- font-size: 16px;
142
- line-height: 1.7;
143
- }
144
- .results-section {
145
- margin-top: 30px;
146
- }
147
- .results-header {
148
- font-size: 22px;
149
- font-weight: 600;
150
- color: #2c3e50;
151
- margin-bottom: 20px;
152
- display: flex;
153
- align-items: center;
154
- gap: 8px;
155
- }
156
- .result-item {
157
- background: #fff;
158
- border: 1px solid #e1e8ed;
159
- border-radius: 8px;
160
- padding: 20px;
161
- margin-bottom: 20px;
162
- transition: all 0.3s ease;
163
- box-shadow: 0 2px 4px rgba(0,0,0,0.05);
164
- }
165
- .result-item:hover {
166
- transform: translateY(-2px);
167
- box-shadow: 0 8px 25px rgba(0,0,0,0.1);
168
- border-color: #4CAF50;
169
- }
170
- .result-title {
171
- font-size: 18px;
172
- font-weight: 600;
173
- color: #1a73e8;
174
- margin-bottom: 8px;
175
- text-decoration: none;
176
- }
177
- .result-title:hover {
178
- text-decoration: underline;
179
- }
180
- .result-url {
181
- color: #34a853;
182
- font-size: 14px;
183
- margin-bottom: 12px;
184
- word-break: break-all;
185
- }
186
- .result-content {
187
- color: #5f6368;
188
- line-height: 1.6;
189
- margin-bottom: 12px;
190
- }
191
- .result-score {
192
- background: #e8f5e8;
193
- color: #2d5a2d;
194
- padding: 4px 12px;
195
- border-radius: 20px;
196
- font-size: 12px;
197
- font-weight: 500;
198
- display: inline-block;
199
- }
200
- .divider {
201
- height: 1px;
202
- background: linear-gradient(90deg, transparent, #ddd, transparent);
203
- margin: 30px 0;
204
- }
205
- .metadata {
206
- background: #f8f9fa;
207
- border-radius: 8px;
208
- padding: 20px;
209
- margin-top: 30px;
210
- border-left: 4px solid #4CAF50;
211
- }
212
- .metadata-title {
213
- font-weight: 600;
214
- color: #2c3e50;
215
- margin-bottom: 10px;
216
- }
217
- .json-container {
218
- background: #2d3748;
219
- color: #e2e8f0;
220
- padding: 20px;
221
- border-radius: 8px;
222
- overflow-x: auto;
223
- font-family: 'Monaco', 'Consolas', monospace;
224
- font-size: 12px;
225
- line-height: 1.5;
226
- max-height: 400px;
227
- overflow-y: auto;
228
- }
229
- .image-section {
230
- margin-top: 20px;
231
- }
232
- .image-grid {
233
- display: grid;
234
- grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
235
- gap: 15px;
236
- margin-top: 15px;
237
- }
238
- .image-item {
239
- border-radius: 8px;
240
- overflow: hidden;
241
- box-shadow: 0 2px 8px rgba(0,0,0,0.1);
242
- }
243
- .image-item img {
244
- width: 100%;
245
- height: 150px;
246
- object-fit: cover;
247
- }
248
- .image-description {
249
- padding: 10px;
250
- background: white;
251
- font-size: 12px;
252
- color: #666;
253
- }
254
- </style>
255
- </head>
256
- <body>
257
- <div class="container">
258
- <div class="header">
259
- <h1 class="search-title">πŸ” Tavily Search Results</h1>
260
- <div class="search-query">Query: "{}"</div>
261
- </div>
262
- """.format(query.replace('"', '&quot;'))
263
 
264
  # Add answer section if available
265
  if "answer" in result and result["answer"]:
266
  html_result += f"""
267
- <div class="answer-section">
268
- <div class="answer-title">πŸ“‹ AI Generated Answer</div>
269
- <div class="answer-content">{result['answer']}</div>
270
- </div>
271
- """
272
 
273
  # Add search results
274
  if "results" in result and result["results"]:
275
  html_result += f"""
276
- <div class="results-section">
277
- <div class="results-header">πŸ“Š Found {len(result['results'])} Results</div>
278
- """
279
 
280
  for i, item in enumerate(result["results"], 1):
281
  title = item.get('title', 'No Title').replace('<', '&lt;').replace('>', '&gt;')
@@ -285,53 +281,49 @@ def tavily_search(
285
  score = item.get('score', 0)
286
 
287
  html_result += f"""
288
- <div class="result-item">
289
- <a href="{url}" target="_blank" class="result-title">{i}. {title}</a>
290
- <div class="result-url">{url}</div>
291
- <div class="result-content">{content}</div>
292
- {f'<span class="result-score">⭐ Score: {score:.3f}</span>' if score else ''}
293
- </div>
294
- """
295
 
296
  html_result += "</div>"
297
 
298
  # Add images if available
299
  if "images" in result and result.get("images"):
300
  html_result += """
301
- <div class="image-section">
302
- <div class="results-header">πŸ–ΌοΈ Related Images</div>
303
- <div class="image-grid">
304
- """
305
  for img in result["images"][:6]: # Limit to 6 images
306
  img_url = img.get('url', '')
307
  img_title = img.get('title', 'Image').replace('<', '&lt;').replace('>', '&gt;')
308
  html_result += f"""
309
- <div class="image-item">
310
- <img src="{img_url}" alt="{img_title}" loading="lazy">
311
- <div class="image-description">{img_title}</div>
312
- </div>
313
- """
314
  html_result += "</div></div>"
315
 
316
  # Add metadata
317
  html_result += f"""
318
- <div class="divider"></div>
319
- <div class="metadata">
320
- <div class="metadata-title">πŸ”§ Response Metadata</div>
321
- <div><strong>Results Count:</strong> {len(result.get('results', []))}</div>
322
- <div><strong>Query:</strong> {query}</div>
323
- <div><strong>Search Depth:</strong> {search_depth}</div>
324
- <div><strong>Topic:</strong> {topic}</div>
325
- </div>
326
-
327
- <div class="metadata">
328
- <div class="metadata-title">πŸ“„ Raw JSON Response</div>
329
- <div class="json-container">{json.dumps(result, indent=2).replace('<', '&lt;').replace('>', '&gt;')}</div>
330
- </div>
331
- </div>
332
- </body>
333
- </html>
334
- """
335
 
336
  return html_result
337
 
 
79
  result = response.json()
80
 
81
  # Format the response as clean HTML
82
+ html_result = f"""<!DOCTYPE html>
83
+ <html>
84
+ <head>
85
+ <meta charset="UTF-8">
86
+ <title>Tavily Search Results</title>
87
+ <style>
88
+ body {{
89
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
90
+ line-height: 1.6;
91
+ color: #333;
92
+ max-width: 1200px;
93
+ margin: 0 auto;
94
+ padding: 20px;
95
+ background: #f8f9fa;
96
+ }}
97
+ .container {{
98
+ background: white;
99
+ border-radius: 12px;
100
+ padding: 30px;
101
+ box-shadow: 0 4px 6px rgba(0,0,0,0.1);
102
+ }}
103
+ .header {{
104
+ border-bottom: 3px solid #4CAF50;
105
+ padding-bottom: 20px;
106
+ margin-bottom: 30px;
107
+ }}
108
+ .search-title {{
109
+ color: #2c3e50;
110
+ font-size: 28px;
111
+ font-weight: 700;
112
+ margin: 0;
113
+ display: flex;
114
+ align-items: center;
115
+ gap: 10px;
116
+ }}
117
+ .search-query {{
118
+ color: #7f8c8d;
119
+ font-size: 16px;
120
+ margin-top: 8px;
121
+ font-style: italic;
122
+ }}
123
+ .answer-section {{
124
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
125
+ color: white;
126
+ padding: 25px;
127
+ border-radius: 10px;
128
+ margin-bottom: 30px;
129
+ box-shadow: 0 4px 15px rgba(102, 126, 234, 0.3);
130
+ }}
131
+ .answer-title {{
132
+ font-size: 20px;
133
+ font-weight: 600;
134
+ margin-bottom: 15px;
135
+ display: flex;
136
+ align-items: center;
137
+ gap: 8px;
138
+ }}
139
+ .answer-content {{
140
+ font-size: 16px;
141
+ line-height: 1.7;
142
+ }}
143
+ .results-section {{
144
+ margin-top: 30px;
145
+ }}
146
+ .results-header {{
147
+ font-size: 22px;
148
+ font-weight: 600;
149
+ color: #2c3e50;
150
+ margin-bottom: 20px;
151
+ display: flex;
152
+ align-items: center;
153
+ gap: 8px;
154
+ }}
155
+ .result-item {{
156
+ background: #fff;
157
+ border: 1px solid #e1e8ed;
158
+ border-radius: 8px;
159
+ padding: 20px;
160
+ margin-bottom: 20px;
161
+ transition: all 0.3s ease;
162
+ box-shadow: 0 2px 4px rgba(0,0,0,0.05);
163
+ }}
164
+ .result-item:hover {{
165
+ transform: translateY(-2px);
166
+ box-shadow: 0 8px 25px rgba(0,0,0,0.1);
167
+ border-color: #4CAF50;
168
+ }}
169
+ .result-title {{
170
+ font-size: 18px;
171
+ font-weight: 600;
172
+ color: #1a73e8;
173
+ margin-bottom: 8px;
174
+ text-decoration: none;
175
+ }}
176
+ .result-title:hover {{
177
+ text-decoration: underline;
178
+ }}
179
+ .result-url {{
180
+ color: #34a853;
181
+ font-size: 14px;
182
+ margin-bottom: 12px;
183
+ word-break: break-all;
184
+ }}
185
+ .result-content {{
186
+ color: #5f6368;
187
+ line-height: 1.6;
188
+ margin-bottom: 12px;
189
+ }}
190
+ .result-score {{
191
+ background: #e8f5e8;
192
+ color: #2d5a2d;
193
+ padding: 4px 12px;
194
+ border-radius: 20px;
195
+ font-size: 12px;
196
+ font-weight: 500;
197
+ display: inline-block;
198
+ }}
199
+ .divider {{
200
+ height: 1px;
201
+ background: linear-gradient(90deg, transparent, #ddd, transparent);
202
+ margin: 30px 0;
203
+ }}
204
+ .metadata {{
205
+ background: #f8f9fa;
206
+ border-radius: 8px;
207
+ padding: 20px;
208
+ margin-top: 30px;
209
+ border-left: 4px solid #4CAF50;
210
+ }}
211
+ .metadata-title {{
212
+ font-weight: 600;
213
+ color: #2c3e50;
214
+ margin-bottom: 10px;
215
+ }}
216
+ .json-container {{
217
+ background: #2d3748;
218
+ color: #e2e8f0;
219
+ padding: 20px;
220
+ border-radius: 8px;
221
+ overflow-x: auto;
222
+ font-family: 'Monaco', 'Consolas', monospace;
223
+ font-size: 12px;
224
+ line-height: 1.5;
225
+ max-height: 400px;
226
+ overflow-y: auto;
227
+ }}
228
+ .image-section {{
229
+ margin-top: 20px;
230
+ }}
231
+ .image-grid {{
232
+ display: grid;
233
+ grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
234
+ gap: 15px;
235
+ margin-top: 15px;
236
+ }}
237
+ .image-item {{
238
+ border-radius: 8px;
239
+ overflow: hidden;
240
+ box-shadow: 0 2px 8px rgba(0,0,0,0.1);
241
+ }}
242
+ .image-item img {{
243
+ width: 100%;
244
+ height: 150px;
245
+ object-fit: cover;
246
+ }}
247
+ .image-description {{
248
+ padding: 10px;
249
+ background: white;
250
+ font-size: 12px;
251
+ color: #666;
252
+ }}
253
+ </style>
254
+ </head>
255
+ <body>
256
+ <div class="container">
257
+ <div class="header">
258
+ <h1 class="search-title">πŸ” Tavily Search Results</h1>
259
+ <div class="search-query">Query: "{query.replace('"', '&quot;')}"</div>
260
+ </div>"""
 
 
261
 
262
  # Add answer section if available
263
  if "answer" in result and result["answer"]:
264
  html_result += f"""
265
+ <div class="answer-section">
266
+ <div class="answer-title">πŸ“‹ AI Generated Answer</div>
267
+ <div class="answer-content">{result['answer']}</div>
268
+ </div>"""
 
269
 
270
  # Add search results
271
  if "results" in result and result["results"]:
272
  html_result += f"""
273
+ <div class="results-section">
274
+ <div class="results-header">πŸ“Š Found {len(result['results'])} Results</div>"""
 
275
 
276
  for i, item in enumerate(result["results"], 1):
277
  title = item.get('title', 'No Title').replace('<', '&lt;').replace('>', '&gt;')
 
281
  score = item.get('score', 0)
282
 
283
  html_result += f"""
284
+ <div class="result-item">
285
+ <a href="{url}" target="_blank" class="result-title">{i}. {title}</a>
286
+ <div class="result-url">{url}</div>
287
+ <div class="result-content">{content}</div>
288
+ {f'<span class="result-score">⭐ Score: {score:.3f}</span>' if score else ''}
289
+ </div>"""
 
290
 
291
  html_result += "</div>"
292
 
293
  # Add images if available
294
  if "images" in result and result.get("images"):
295
  html_result += """
296
+ <div class="image-section">
297
+ <div class="results-header">πŸ–ΌοΈ Related Images</div>
298
+ <div class="image-grid">"""
 
299
  for img in result["images"][:6]: # Limit to 6 images
300
  img_url = img.get('url', '')
301
  img_title = img.get('title', 'Image').replace('<', '&lt;').replace('>', '&gt;')
302
  html_result += f"""
303
+ <div class="image-item">
304
+ <img src="{img_url}" alt="{img_title}" loading="lazy">
305
+ <div class="image-description">{img_title}</div>
306
+ </div>"""
 
307
  html_result += "</div></div>"
308
 
309
  # Add metadata
310
  html_result += f"""
311
+ <div class="divider"></div>
312
+ <div class="metadata">
313
+ <div class="metadata-title">πŸ”§ Response Metadata</div>
314
+ <div><strong>Results Count:</strong> {len(result.get('results', []))}</div>
315
+ <div><strong>Query:</strong> {query}</div>
316
+ <div><strong>Search Depth:</strong> {search_depth}</div>
317
+ <div><strong>Topic:</strong> {topic}</div>
318
+ </div>
319
+
320
+ <div class="metadata">
321
+ <div class="metadata-title">πŸ“„ Raw JSON Response</div>
322
+ <div class="json-container">{json.dumps(result, indent=2).replace('<', '&lt;').replace('>', '&gt;')}</div>
323
+ </div>
324
+ </div>
325
+ </body>
326
+ </html>"""
 
327
 
328
  return html_result
329