Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -78,7 +78,7 @@ def tavily_search(
|
|
78 |
if response.status_code == 200:
|
79 |
result = response.json()
|
80 |
|
81 |
-
# Format the response as clean HTML
|
82 |
html_result = f"""<!DOCTYPE html>
|
83 |
<html>
|
84 |
<head>
|
@@ -89,25 +89,30 @@ def tavily_search(
|
|
89 |
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
90 |
line-height: 1.6;
|
91 |
color: #333;
|
92 |
-
max-width: 1200px
|
93 |
-
|
94 |
-
|
|
|
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;
|
@@ -116,38 +121,40 @@ def tavily_search(
|
|
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;
|
@@ -156,10 +163,11 @@ def tavily_search(
|
|
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);
|
@@ -167,60 +175,71 @@ def tavily_search(
|
|
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:
|
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:
|
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 |
.image-section {{
|
217 |
-
margin-top: 20px
|
218 |
}}
|
219 |
.image-grid {{
|
220 |
display: grid;
|
221 |
-
grid-template-columns: repeat(auto-fill, minmax(
|
222 |
-
gap: 15px
|
223 |
-
margin-top: 15px
|
224 |
}}
|
225 |
.image-item {{
|
226 |
border-radius: 8px;
|
@@ -229,14 +248,23 @@ def tavily_search(
|
|
229 |
}}
|
230 |
.image-item img {{
|
231 |
width: 100%;
|
232 |
-
height: 150px
|
233 |
object-fit: cover;
|
234 |
}}
|
235 |
.image-description {{
|
236 |
-
padding: 10px
|
237 |
background: white;
|
238 |
-
font-size: 12px
|
239 |
color: #666;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
240 |
}}
|
241 |
</style>
|
242 |
</head>
|
@@ -264,7 +292,7 @@ def tavily_search(
|
|
264 |
for i, item in enumerate(result["results"], 1):
|
265 |
title = item.get('title', 'No Title').replace('<', '<').replace('>', '>')
|
266 |
url = item.get('url', 'No URL')
|
267 |
-
content = item.get('content', 'No content available')[:
|
268 |
content = content.replace('<', '<').replace('>', '>')
|
269 |
score = item.get('score', 0)
|
270 |
|
@@ -349,8 +377,22 @@ country_options = [
|
|
349 |
"yemen", "zambia", "zimbabwe"
|
350 |
]
|
351 |
|
352 |
-
# Create the Gradio interface
|
353 |
-
with gr.Blocks(title="Tavily Search API", theme=gr.themes.Soft()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
354 |
gr.Markdown("# π Tavily Search API Interface")
|
355 |
gr.Markdown("Search the web using Tavily's powerful search API with customizable parameters.")
|
356 |
|
@@ -358,63 +400,50 @@ with gr.Blocks(title="Tavily Search API", theme=gr.themes.Soft()) as app:
|
|
358 |
with gr.Accordion("π API Documentation & Parameter Options", open=False):
|
359 |
gr.Markdown("""
|
360 |
## Available Options
|
361 |
-
|
362 |
### **topic**: The category of the search
|
363 |
- **news**: Useful for retrieving real-time updates, particularly about politics, sports, and major current events covered by mainstream media sources
|
364 |
- **general**: For broader, more general-purpose searches that may include a wide range of sources
|
365 |
|
366 |
**Available options**: `general`, `news`
|
367 |
-
|
368 |
### **search_depth**: The depth of the search
|
369 |
- **advanced**: Tailored to retrieve the most relevant sources and content snippets for your query (costs 2 API Credits)
|
370 |
- **basic**: Provides generic content snippets from each source (costs 1 API Credit)
|
371 |
|
372 |
**Available options**: `basic`, `advanced`
|
373 |
-
|
374 |
### **chunks_per_source**: Content snippets control
|
375 |
Chunks are short content snippets (maximum 500 characters each) pulled directly from the source. Use this to define the maximum number of relevant chunks returned per source and to control the content length. Chunks will appear in the content field as: `<chunk 1> [...] <chunk 2> [...] <chunk 3>`.
|
376 |
|
377 |
**Note**: Available only when `search_depth` is `advanced`
|
378 |
|
379 |
**Required range**: 1 β€ x β€ 3
|
380 |
-
|
381 |
### **max_results**: Maximum number of search results
|
382 |
The maximum number of search results to return.
|
383 |
|
384 |
**Required range**: 0 β€ x β€ 20
|
385 |
-
|
386 |
### **time_range**: Time filtering
|
387 |
The time range back from the current date to filter results. Useful when looking for sources that have published data.
|
388 |
|
389 |
**Available options**: `day`, `week`, `month`, `year`, `d`, `w`, `m`, `y`
|
390 |
-
|
391 |
### **days**: Days back for news searches
|
392 |
Number of days back from the current date to include. Available only if topic is `news`.
|
393 |
|
394 |
**Required range**: x β₯ 1
|
395 |
-
|
396 |
### **include_answer**: LLM-generated answer
|
397 |
Include an LLM-generated answer to the provided query.
|
398 |
- `basic` or `true`: Returns a quick answer
|
399 |
- `advanced`: Returns a more detailed answer
|
400 |
-
|
401 |
### **include_raw_content**: Raw HTML content
|
402 |
Include the cleaned and parsed HTML content of each search result.
|
403 |
- `markdown` or `true`: Returns search result content in markdown format
|
404 |
- `text`: Returns the plain text from the results (may increase latency)
|
405 |
-
|
406 |
### **include_images**: Image search
|
407 |
Also perform an image search and include the results in the response.
|
408 |
-
|
409 |
### **include_image_descriptions**: Image descriptions
|
410 |
When `include_images` is true, also add a descriptive text for each image.
|
411 |
-
|
412 |
### **include_domains**: Domain inclusion
|
413 |
A list of domains to specifically include in the search results.
|
414 |
-
|
415 |
### **exclude_domains**: Domain exclusion
|
416 |
A list of domains to specifically exclude from the search results.
|
417 |
-
|
418 |
### **country**: Country-specific boosting
|
419 |
Boost search results from a specific country. This will prioritize content from the selected country in the search results. Available only if topic is `general`.
|
420 |
|
@@ -539,7 +568,7 @@ with gr.Blocks(title="Tavily Search API", theme=gr.themes.Soft()) as app:
|
|
539 |
# Search Button
|
540 |
search_btn = gr.Button("π Search", variant="primary", size="lg")
|
541 |
|
542 |
-
# Results Section
|
543 |
gr.Markdown("## π Search Results")
|
544 |
results = gr.HTML(
|
545 |
label="Results",
|
|
|
78 |
if response.status_code == 200:
|
79 |
result = response.json()
|
80 |
|
81 |
+
# Format the response as clean HTML with fixed width
|
82 |
html_result = f"""<!DOCTYPE html>
|
83 |
<html>
|
84 |
<head>
|
|
|
89 |
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
90 |
line-height: 1.6;
|
91 |
color: #333;
|
92 |
+
max-width: 100%; /* Changed from 1200px to 100% */
|
93 |
+
width: 100%; /* Added fixed width */
|
94 |
+
margin: 0; /* Changed from 0 auto to 0 */
|
95 |
+
padding: 15px; /* Reduced from 20px */
|
96 |
background: #f8f9fa;
|
97 |
+
box-sizing: border-box; /* Added box-sizing */
|
98 |
+
overflow-x: hidden; /* Prevent horizontal scroll */
|
99 |
}}
|
100 |
.container {{
|
101 |
background: white;
|
102 |
border-radius: 12px;
|
103 |
+
padding: 20px; /* Reduced from 30px */
|
104 |
box-shadow: 0 4px 6px rgba(0,0,0,0.1);
|
105 |
+
max-width: 100%; /* Added max-width */
|
106 |
+
overflow: hidden; /* Prevent overflow */
|
107 |
}}
|
108 |
.header {{
|
109 |
border-bottom: 3px solid #4CAF50;
|
110 |
+
padding-bottom: 15px; /* Reduced from 20px */
|
111 |
+
margin-bottom: 20px; /* Reduced from 30px */
|
112 |
}}
|
113 |
.search-title {{
|
114 |
color: #2c3e50;
|
115 |
+
font-size: 24px; /* Reduced from 28px */
|
116 |
font-weight: 700;
|
117 |
margin: 0;
|
118 |
display: flex;
|
|
|
121 |
}}
|
122 |
.search-query {{
|
123 |
color: #7f8c8d;
|
124 |
+
font-size: 14px; /* Reduced from 16px */
|
125 |
margin-top: 8px;
|
126 |
font-style: italic;
|
127 |
+
word-break: break-word; /* Added word break */
|
128 |
}}
|
129 |
.answer-section {{
|
130 |
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
131 |
color: white;
|
132 |
+
padding: 20px; /* Reduced from 25px */
|
133 |
border-radius: 10px;
|
134 |
+
margin-bottom: 20px; /* Reduced from 30px */
|
135 |
box-shadow: 0 4px 15px rgba(102, 126, 234, 0.3);
|
136 |
}}
|
137 |
.answer-title {{
|
138 |
+
font-size: 18px; /* Reduced from 20px */
|
139 |
font-weight: 600;
|
140 |
+
margin-bottom: 12px; /* Reduced from 15px */
|
141 |
display: flex;
|
142 |
align-items: center;
|
143 |
gap: 8px;
|
144 |
}}
|
145 |
.answer-content {{
|
146 |
+
font-size: 14px; /* Reduced from 16px */
|
147 |
+
line-height: 1.6; /* Reduced from 1.7 */
|
148 |
+
word-break: break-word; /* Added word break */
|
149 |
}}
|
150 |
.results-section {{
|
151 |
+
margin-top: 20px; /* Reduced from 30px */
|
152 |
}}
|
153 |
.results-header {{
|
154 |
+
font-size: 20px; /* Reduced from 22px */
|
155 |
font-weight: 600;
|
156 |
color: #2c3e50;
|
157 |
+
margin-bottom: 15px; /* Reduced from 20px */
|
158 |
display: flex;
|
159 |
align-items: center;
|
160 |
gap: 8px;
|
|
|
163 |
background: #fff;
|
164 |
border: 1px solid #e1e8ed;
|
165 |
border-radius: 8px;
|
166 |
+
padding: 15px; /* Reduced from 20px */
|
167 |
+
margin-bottom: 15px; /* Reduced from 20px */
|
168 |
transition: all 0.3s ease;
|
169 |
box-shadow: 0 2px 4px rgba(0,0,0,0.05);
|
170 |
+
overflow: hidden; /* Prevent overflow */
|
171 |
}}
|
172 |
.result-item:hover {{
|
173 |
transform: translateY(-2px);
|
|
|
175 |
border-color: #4CAF50;
|
176 |
}}
|
177 |
.result-title {{
|
178 |
+
font-size: 16px; /* Reduced from 18px */
|
179 |
font-weight: 600;
|
180 |
color: #1a73e8;
|
181 |
margin-bottom: 8px;
|
182 |
text-decoration: none;
|
183 |
+
word-break: break-word; /* Added word break */
|
184 |
+
display: block;
|
185 |
}}
|
186 |
.result-title:hover {{
|
187 |
text-decoration: underline;
|
188 |
}}
|
189 |
.result-url {{
|
190 |
color: #34a853;
|
191 |
+
font-size: 12px; /* Reduced from 14px */
|
192 |
+
margin-bottom: 10px; /* Reduced from 12px */
|
193 |
word-break: break-all;
|
194 |
+
overflow: hidden;
|
195 |
+
text-overflow: ellipsis;
|
196 |
+
white-space: nowrap; /* Added to prevent wrapping */
|
197 |
}}
|
198 |
.result-content {{
|
199 |
color: #5f6368;
|
200 |
+
line-height: 1.5; /* Reduced from 1.6 */
|
201 |
+
margin-bottom: 10px; /* Reduced from 12px */
|
202 |
+
font-size: 13px; /* Added smaller font size */
|
203 |
+
word-break: break-word; /* Added word break */
|
204 |
+
max-height: 150px; /* Added max height */
|
205 |
+
overflow: hidden; /* Added overflow hidden */
|
206 |
}}
|
207 |
.result-score {{
|
208 |
background: #e8f5e8;
|
209 |
color: #2d5a2d;
|
210 |
+
padding: 3px 10px; /* Reduced padding */
|
211 |
border-radius: 20px;
|
212 |
+
font-size: 11px; /* Reduced from 12px */
|
213 |
font-weight: 500;
|
214 |
display: inline-block;
|
215 |
}}
|
216 |
.divider {{
|
217 |
height: 1px;
|
218 |
background: linear-gradient(90deg, transparent, #ddd, transparent);
|
219 |
+
margin: 20px 0; /* Reduced from 30px */
|
220 |
}}
|
221 |
.metadata {{
|
222 |
background: #f8f9fa;
|
223 |
border-radius: 8px;
|
224 |
+
padding: 15px; /* Reduced from 20px */
|
225 |
+
margin-top: 20px; /* Reduced from 30px */
|
226 |
border-left: 4px solid #4CAF50;
|
227 |
+
font-size: 13px; /* Added smaller font size */
|
228 |
}}
|
229 |
.metadata-title {{
|
230 |
font-weight: 600;
|
231 |
color: #2c3e50;
|
232 |
+
margin-bottom: 8px; /* Reduced from 10px */
|
233 |
+
font-size: 14px; /* Added font size */
|
234 |
}}
|
235 |
.image-section {{
|
236 |
+
margin-top: 15px; /* Reduced from 20px */
|
237 |
}}
|
238 |
.image-grid {{
|
239 |
display: grid;
|
240 |
+
grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); /* Reduced from 200px */
|
241 |
+
gap: 10px; /* Reduced from 15px */
|
242 |
+
margin-top: 10px; /* Reduced from 15px */
|
243 |
}}
|
244 |
.image-item {{
|
245 |
border-radius: 8px;
|
|
|
248 |
}}
|
249 |
.image-item img {{
|
250 |
width: 100%;
|
251 |
+
height: 120px; /* Reduced from 150px */
|
252 |
object-fit: cover;
|
253 |
}}
|
254 |
.image-description {{
|
255 |
+
padding: 8px; /* Reduced from 10px */
|
256 |
background: white;
|
257 |
+
font-size: 11px; /* Reduced from 12px */
|
258 |
color: #666;
|
259 |
+
word-break: break-word; /* Added word break */
|
260 |
+
}}
|
261 |
+
|
262 |
+
/* Responsive adjustments */
|
263 |
+
@media (max-width: 768px) {{
|
264 |
+
.container {{ padding: 10px; }}
|
265 |
+
.search-title {{ font-size: 20px; }}
|
266 |
+
.result-item {{ padding: 10px; }}
|
267 |
+
.image-grid {{ grid-template-columns: repeat(auto-fill, minmax(120px, 1fr)); }}
|
268 |
}}
|
269 |
</style>
|
270 |
</head>
|
|
|
292 |
for i, item in enumerate(result["results"], 1):
|
293 |
title = item.get('title', 'No Title').replace('<', '<').replace('>', '>')
|
294 |
url = item.get('url', 'No URL')
|
295 |
+
content = item.get('content', 'No content available')[:600] + '...' # Reduced from 800
|
296 |
content = content.replace('<', '<').replace('>', '>')
|
297 |
score = item.get('score', 0)
|
298 |
|
|
|
377 |
"yemen", "zambia", "zimbabwe"
|
378 |
]
|
379 |
|
380 |
+
# Create the Gradio interface with fixed layout
|
381 |
+
with gr.Blocks(title="Tavily Search API", theme=gr.themes.Soft(), css="""
|
382 |
+
/* Custom CSS to prevent interface squeezing */
|
383 |
+
.gradio-container {
|
384 |
+
max-width: none !important;
|
385 |
+
}
|
386 |
+
.contain {
|
387 |
+
max-width: none !important;
|
388 |
+
}
|
389 |
+
#search_results {
|
390 |
+
max-height: 600px !important;
|
391 |
+
overflow-y: auto !important;
|
392 |
+
border: 1px solid #e0e0e0 !important;
|
393 |
+
border-radius: 8px !important;
|
394 |
+
}
|
395 |
+
""") as app:
|
396 |
gr.Markdown("# π Tavily Search API Interface")
|
397 |
gr.Markdown("Search the web using Tavily's powerful search API with customizable parameters.")
|
398 |
|
|
|
400 |
with gr.Accordion("π API Documentation & Parameter Options", open=False):
|
401 |
gr.Markdown("""
|
402 |
## Available Options
|
|
|
403 |
### **topic**: The category of the search
|
404 |
- **news**: Useful for retrieving real-time updates, particularly about politics, sports, and major current events covered by mainstream media sources
|
405 |
- **general**: For broader, more general-purpose searches that may include a wide range of sources
|
406 |
|
407 |
**Available options**: `general`, `news`
|
|
|
408 |
### **search_depth**: The depth of the search
|
409 |
- **advanced**: Tailored to retrieve the most relevant sources and content snippets for your query (costs 2 API Credits)
|
410 |
- **basic**: Provides generic content snippets from each source (costs 1 API Credit)
|
411 |
|
412 |
**Available options**: `basic`, `advanced`
|
|
|
413 |
### **chunks_per_source**: Content snippets control
|
414 |
Chunks are short content snippets (maximum 500 characters each) pulled directly from the source. Use this to define the maximum number of relevant chunks returned per source and to control the content length. Chunks will appear in the content field as: `<chunk 1> [...] <chunk 2> [...] <chunk 3>`.
|
415 |
|
416 |
**Note**: Available only when `search_depth` is `advanced`
|
417 |
|
418 |
**Required range**: 1 β€ x β€ 3
|
|
|
419 |
### **max_results**: Maximum number of search results
|
420 |
The maximum number of search results to return.
|
421 |
|
422 |
**Required range**: 0 β€ x β€ 20
|
|
|
423 |
### **time_range**: Time filtering
|
424 |
The time range back from the current date to filter results. Useful when looking for sources that have published data.
|
425 |
|
426 |
**Available options**: `day`, `week`, `month`, `year`, `d`, `w`, `m`, `y`
|
|
|
427 |
### **days**: Days back for news searches
|
428 |
Number of days back from the current date to include. Available only if topic is `news`.
|
429 |
|
430 |
**Required range**: x β₯ 1
|
|
|
431 |
### **include_answer**: LLM-generated answer
|
432 |
Include an LLM-generated answer to the provided query.
|
433 |
- `basic` or `true`: Returns a quick answer
|
434 |
- `advanced`: Returns a more detailed answer
|
|
|
435 |
### **include_raw_content**: Raw HTML content
|
436 |
Include the cleaned and parsed HTML content of each search result.
|
437 |
- `markdown` or `true`: Returns search result content in markdown format
|
438 |
- `text`: Returns the plain text from the results (may increase latency)
|
|
|
439 |
### **include_images**: Image search
|
440 |
Also perform an image search and include the results in the response.
|
|
|
441 |
### **include_image_descriptions**: Image descriptions
|
442 |
When `include_images` is true, also add a descriptive text for each image.
|
|
|
443 |
### **include_domains**: Domain inclusion
|
444 |
A list of domains to specifically include in the search results.
|
|
|
445 |
### **exclude_domains**: Domain exclusion
|
446 |
A list of domains to specifically exclude from the search results.
|
|
|
447 |
### **country**: Country-specific boosting
|
448 |
Boost search results from a specific country. This will prioritize content from the selected country in the search results. Available only if topic is `general`.
|
449 |
|
|
|
568 |
# Search Button
|
569 |
search_btn = gr.Button("π Search", variant="primary", size="lg")
|
570 |
|
571 |
+
# Results Section with fixed height
|
572 |
gr.Markdown("## π Search Results")
|
573 |
results = gr.HTML(
|
574 |
label="Results",
|