Update app.py
Browse files
app.py
CHANGED
@@ -69,28 +69,43 @@ class VeterinaryLiteratureMiner:
|
|
69 |
|
70 |
def _search_pubmed(self, query: str, max_results: int) -> List[Dict]:
|
71 |
"""Search PubMed for veterinary papers"""
|
72 |
-
# Enhance query with veterinary terms
|
73 |
-
enhanced_query = f"({query}) AND (veterinary OR animal OR pet OR livestock OR zoo OR wildlife)"
|
74 |
-
|
75 |
-
# Search PubMed
|
76 |
-
search_url = "https://eutils.ncbi.nlm.nih.gov/entrez/eutils/esearch.fcgi"
|
77 |
-
search_params = {
|
78 |
-
"db": "pubmed",
|
79 |
-
"term": enhanced_query,
|
80 |
-
"retmax": max_results,
|
81 |
-
"retmode": "json",
|
82 |
-
"sort": "relevance"
|
83 |
-
}
|
84 |
-
|
85 |
try:
|
86 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
87 |
search_data = search_response.json()
|
|
|
|
|
|
|
|
|
88 |
|
89 |
-
if
|
90 |
-
return []
|
91 |
|
92 |
# Get detailed information
|
93 |
ids = search_data["esearchresult"]["idlist"]
|
|
|
|
|
94 |
fetch_url = "https://eutils.ncbi.nlm.nih.gov/entrez/eutils/efetch.fcgi"
|
95 |
fetch_params = {
|
96 |
"db": "pubmed",
|
@@ -98,13 +113,24 @@ class VeterinaryLiteratureMiner:
|
|
98 |
"retmode": "xml"
|
99 |
}
|
100 |
|
101 |
-
fetch_response = requests.get(fetch_url, params=fetch_params)
|
|
|
|
|
|
|
|
|
102 |
|
103 |
# Parse XML response
|
104 |
papers = self._parse_pubmed_xml(fetch_response.text)
|
|
|
|
|
105 |
return papers
|
106 |
|
|
|
|
|
|
|
|
|
107 |
except Exception as e:
|
|
|
108 |
return [{"error": f"Search failed: {str(e)}"}]
|
109 |
|
110 |
def _parse_pubmed_xml(self, xml_content: str) -> List[Dict]:
|
@@ -379,45 +405,66 @@ def create_veterinary_gradio_interface():
|
|
379 |
|
380 |
def search_and_analyze_vet(query, max_results, database):
|
381 |
"""Main function to search and analyze veterinary literature"""
|
382 |
-
|
383 |
-
|
384 |
-
|
385 |
-
|
386 |
-
|
387 |
-
|
388 |
-
|
389 |
-
|
390 |
-
|
391 |
-
|
392 |
-
|
393 |
-
|
394 |
-
|
395 |
-
|
396 |
-
|
397 |
-
|
398 |
-
|
399 |
-
|
400 |
-
|
401 |
-
|
402 |
-
|
403 |
-
|
404 |
-
|
405 |
-
"
|
406 |
-
|
407 |
-
|
408 |
-
|
409 |
-
|
410 |
-
|
411 |
-
|
412 |
-
|
413 |
-
|
414 |
-
|
415 |
-
|
416 |
-
|
417 |
-
|
418 |
-
|
419 |
-
|
420 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
421 |
|
422 |
# Create interface
|
423 |
with gr.Blocks(title="Veterinary Literature Mining Agent", theme=gr.themes.Soft()) as interface:
|
@@ -453,7 +500,7 @@ def create_veterinary_gradio_interface():
|
|
453 |
value="pubmed",
|
454 |
label="Database"
|
455 |
)
|
456 |
-
search_btn = gr.Button("🔍 Search Veterinary Literature", variant="primary")
|
457 |
|
458 |
with gr.Column(scale=1):
|
459 |
gr.Markdown("""
|
@@ -483,11 +530,12 @@ def create_veterinary_gradio_interface():
|
|
483 |
specialties_plot = gr.Plot(label="Veterinary Specialties")
|
484 |
conditions_plot = gr.Plot(label="Common Conditions")
|
485 |
|
486 |
-
# Connect the search function
|
487 |
search_btn.click(
|
488 |
-
search_and_analyze_vet,
|
489 |
inputs=[query_input, max_results, database_choice],
|
490 |
-
outputs=[summary_output, papers_output, year_plot, species_plot, specialties_plot, conditions_plot]
|
|
|
491 |
)
|
492 |
|
493 |
# Add examples
|
|
|
69 |
|
70 |
def _search_pubmed(self, query: str, max_results: int) -> List[Dict]:
|
71 |
"""Search PubMed for veterinary papers"""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
72 |
try:
|
73 |
+
print(f"Searching PubMed with query: {query}") # Debug print
|
74 |
+
|
75 |
+
# Enhance query with veterinary terms
|
76 |
+
enhanced_query = f"({query}) AND (veterinary OR animal OR pet OR livestock OR zoo OR wildlife)"
|
77 |
+
print(f"Enhanced query: {enhanced_query}") # Debug print
|
78 |
+
|
79 |
+
# Search PubMed
|
80 |
+
search_url = "https://eutils.ncbi.nlm.nih.gov/entrez/eutils/esearch.fcgi"
|
81 |
+
search_params = {
|
82 |
+
"db": "pubmed",
|
83 |
+
"term": enhanced_query,
|
84 |
+
"retmax": max_results,
|
85 |
+
"retmode": "json",
|
86 |
+
"sort": "relevance"
|
87 |
+
}
|
88 |
+
|
89 |
+
print("Making search request...") # Debug print
|
90 |
+
search_response = requests.get(search_url, params=search_params, timeout=30)
|
91 |
+
print(f"Search response status: {search_response.status_code}") # Debug print
|
92 |
+
|
93 |
+
if search_response.status_code != 200:
|
94 |
+
return [{"error": f"PubMed search failed with status {search_response.status_code}"}]
|
95 |
+
|
96 |
search_data = search_response.json()
|
97 |
+
print(f"Search data received: {search_data.get('esearchresult', {}).get('count', 0)} results") # Debug print
|
98 |
+
|
99 |
+
if "esearchresult" not in search_data:
|
100 |
+
return [{"error": "Invalid response from PubMed"}]
|
101 |
|
102 |
+
if not search_data["esearchresult"].get("idlist"):
|
103 |
+
return [{"error": "No papers found matching your query"}]
|
104 |
|
105 |
# Get detailed information
|
106 |
ids = search_data["esearchresult"]["idlist"]
|
107 |
+
print(f"Fetching details for {len(ids)} papers...") # Debug print
|
108 |
+
|
109 |
fetch_url = "https://eutils.ncbi.nlm.nih.gov/entrez/eutils/efetch.fcgi"
|
110 |
fetch_params = {
|
111 |
"db": "pubmed",
|
|
|
113 |
"retmode": "xml"
|
114 |
}
|
115 |
|
116 |
+
fetch_response = requests.get(fetch_url, params=fetch_params, timeout=60)
|
117 |
+
print(f"Fetch response status: {fetch_response.status_code}") # Debug print
|
118 |
+
|
119 |
+
if fetch_response.status_code != 200:
|
120 |
+
return [{"error": f"Failed to fetch paper details: {fetch_response.status_code}"}]
|
121 |
|
122 |
# Parse XML response
|
123 |
papers = self._parse_pubmed_xml(fetch_response.text)
|
124 |
+
print(f"Parsed {len(papers)} papers successfully") # Debug print
|
125 |
+
|
126 |
return papers
|
127 |
|
128 |
+
except requests.exceptions.Timeout:
|
129 |
+
return [{"error": "Request timed out. Please try again with fewer results."}]
|
130 |
+
except requests.exceptions.ConnectionError:
|
131 |
+
return [{"error": "Connection error. Please check your internet connection."}]
|
132 |
except Exception as e:
|
133 |
+
print(f"Error in _search_pubmed: {str(e)}") # Debug print
|
134 |
return [{"error": f"Search failed: {str(e)}"}]
|
135 |
|
136 |
def _parse_pubmed_xml(self, xml_content: str) -> List[Dict]:
|
|
|
405 |
|
406 |
def search_and_analyze_vet(query, max_results, database):
|
407 |
"""Main function to search and analyze veterinary literature"""
|
408 |
+
try:
|
409 |
+
print(f"Starting search with query: {query}") # Debug print
|
410 |
+
|
411 |
+
if not query.strip():
|
412 |
+
return "Please enter a search query.", None, None, None, None, None
|
413 |
+
|
414 |
+
# Search papers
|
415 |
+
print("Searching papers...") # Debug print
|
416 |
+
papers = miner.search_veterinary_literature(query, max_results, database)
|
417 |
+
print(f"Found {len(papers) if papers else 0} papers") # Debug print
|
418 |
+
|
419 |
+
if not papers:
|
420 |
+
return "No papers found. Try a different search query.", None, None, None, None, None
|
421 |
+
|
422 |
+
if papers[0].get("error"):
|
423 |
+
error_msg = papers[0].get("error", "Unknown error occurred")
|
424 |
+
return f"Search Error: {error_msg}", None, None, None, None, None
|
425 |
+
|
426 |
+
# Analyze papers
|
427 |
+
print("Analyzing papers...") # Debug print
|
428 |
+
analysis = miner.analyze_veterinary_papers(papers)
|
429 |
+
|
430 |
+
if analysis.get("error"):
|
431 |
+
return f"Analysis Error: {analysis['error']}", None, None, None, None, None
|
432 |
+
|
433 |
+
# Generate summary
|
434 |
+
print("Generating summary...") # Debug print
|
435 |
+
summary = miner.generate_veterinary_summary(papers, analysis)
|
436 |
+
|
437 |
+
# Create visualizations
|
438 |
+
print("Creating visualizations...") # Debug print
|
439 |
+
plots = miner.create_veterinary_visualizations(analysis)
|
440 |
+
|
441 |
+
# Create papers dataframe
|
442 |
+
print("Creating dataframe...") # Debug print
|
443 |
+
papers_df = pd.DataFrame([
|
444 |
+
{
|
445 |
+
"PMID": p.get("pmid", "N/A"),
|
446 |
+
"Title": p.get("title", "N/A")[:100] + "..." if len(p.get("title", "")) > 100 else p.get("title", "N/A"),
|
447 |
+
"Authors": p.get("authors", "N/A"),
|
448 |
+
"Journal": p.get("journal", "N/A"),
|
449 |
+
"Year": p.get("year", "N/A")
|
450 |
+
}
|
451 |
+
for p in papers
|
452 |
+
])
|
453 |
+
|
454 |
+
print("Search and analysis complete!") # Debug print
|
455 |
+
return (
|
456 |
+
summary,
|
457 |
+
papers_df,
|
458 |
+
plots.get("year_dist"),
|
459 |
+
plots.get("animal_species"),
|
460 |
+
plots.get("specialties"),
|
461 |
+
plots.get("conditions")
|
462 |
+
)
|
463 |
+
|
464 |
+
except Exception as e:
|
465 |
+
error_message = f"Unexpected error: {str(e)}"
|
466 |
+
print(f"Error in search_and_analyze_vet: {error_message}") # Debug print
|
467 |
+
return error_message, None, None, None, None, None
|
468 |
|
469 |
# Create interface
|
470 |
with gr.Blocks(title="Veterinary Literature Mining Agent", theme=gr.themes.Soft()) as interface:
|
|
|
500 |
value="pubmed",
|
501 |
label="Database"
|
502 |
)
|
503 |
+
search_btn = gr.Button("🔍 Search Veterinary Literature", variant="primary", size="lg")
|
504 |
|
505 |
with gr.Column(scale=1):
|
506 |
gr.Markdown("""
|
|
|
530 |
specialties_plot = gr.Plot(label="Veterinary Specialties")
|
531 |
conditions_plot = gr.Plot(label="Common Conditions")
|
532 |
|
533 |
+
# Connect the search function with progress indicator
|
534 |
search_btn.click(
|
535 |
+
fn=search_and_analyze_vet,
|
536 |
inputs=[query_input, max_results, database_choice],
|
537 |
+
outputs=[summary_output, papers_output, year_plot, species_plot, specialties_plot, conditions_plot],
|
538 |
+
show_progress=True
|
539 |
)
|
540 |
|
541 |
# Add examples
|