Spaces:
Running
Running
File size: 6,695 Bytes
5d3056e |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 |
import gradio as gr
import requests
import pandas as pd
import io
from docx import Document
import tempfile
import os
os.system("pip install python-docx")
API_BASE_URL = "https://pubmed-api-jwfq.onrender.com/search_pubmed"
global_df = None # Global variable to store search results for export
def fetch_pubmed_articles(query, max_results=10, page=1, sort_by="Year", filter_journal="All", min_year=None, max_year=None):
"""
Fetches PubMed articles and applies sorting and filtering.
"""
try:
url = f"{API_BASE_URL}?query={query}&max_results={max_results}&page={page}"
response = requests.get(url)
if response.status_code != 200:
return f"β οΈ API Error: {response.status_code} - {response.text}", None
articles = response.json()
if not articles:
return "No articles found for this query.", None
for article in articles:
try:
article["Year"] = int(article["Year"])
except:
article["Year"] = 0
# Apply journal filtering
if filter_journal and filter_journal != "All":
articles = [a for a in articles if filter_journal.lower() in a['Journal'].lower()]
# Apply year filtering
if min_year:
articles = [a for a in articles if a["Year"] >= int(min_year)]
if max_year:
articles = [a for a in articles if a["Year"] <= int(max_year)]
# Apply sorting
if sort_by == "Year":
articles.sort(key=lambda x: x["Year"], reverse=True)
elif sort_by == "Title":
articles.sort(key=lambda x: x["Title"])
elif sort_by == "Journal":
articles.sort(key=lambda x: x["Journal"])
# Format results
formatted_results = []
for article in articles:
formatted_results.append(
f"## π° {article['Title']}\n"
f"π **<span style='color:blue'>{article['Journal']}</span>** ({article['Year']})\n"
f"π¨βπ¬ **<span style='color:gray'>{article['Authors']}</span>**\n"
f"π [Read on PubMed]({article['PubMed_URL']})\n\n"
f"<details><summary>π **Show Abstract**</summary>\n{article['Abstract']}\n</details>"
f"\n---\n"
)
df = pd.DataFrame(articles)
return "\n\n".join(formatted_results), df
except Exception as e:
return f"β οΈ Error fetching data: {str(e)}", None
def export_results(df, format_type):
"""
Exports search results as a CSV or DOCX file.
- Returns the file path instead of BytesIO to avoid TypeError in Gradio.
"""
if df is None or df.empty:
return None
temp_file = tempfile.NamedTemporaryFile(delete=False, suffix=f".{format_type.lower()}")
temp_file_path = temp_file.name # Store the temporary file path
if format_type == "CSV":
df.to_csv(temp_file_path, index=False)
elif format_type == "DOCX":
doc = Document()
doc.add_heading("PubMed Search Results", level=1)
for _, row in df.iterrows():
doc.add_heading(row["Title"], level=2)
doc.add_paragraph(f"π Journal: {row['Journal']} ({row['Year']})")
doc.add_paragraph(f"π¨βπ¬ Authors: {row['Authors']}")
doc.add_paragraph(f"π Link: {row['PubMed_URL']}")
doc.add_paragraph(f"π Abstract: {row['Abstract']}")
doc.add_paragraph("---")
doc.save(temp_file_path)
temp_file.close() # Close the file before returning the path
return temp_file_path # Return file path instead of BytesIO
with gr.Blocks() as app:
gr.Markdown("""
# π **PubMed Search Tool with Advanced Features**
## π **How to Use This App**
1οΈβ£ **Enter a Search Query** *(e.g., "Deep Learning in Psychiatry")*
2οΈβ£ **Set the Number of Results & Page Number** *(Default: 10 results per page)*
3οΈβ£ **Choose Sorting Option** *(Year, Title, or Journal - Default: Year)*
4οΈβ£ **(Optional) Filter by Journal Name** *(e.g., "Nature", "JAMA")*
5οΈβ£ **(Optional) Filter by Year Range** *(Set min & max year, e.g., 2015 - 2023)*
6οΈβ£ **Click "π Search" to fetch results**
7οΈβ£ **Click "π Export as CSV" or "π Export as Word DOCX" to save articles**
8οΈβ£ **Click "π Show Abstract" under each result to expand full abstract**
## β οΈ **Important Notes**
- **Sorting & Filtering can be combined** *(e.g., show only "Nature" articles from 2020-2024, sorted by Title)*
""")
with gr.Row():
query_input = gr.Textbox(label="π Search Query", placeholder="Enter topic (e.g., 'Neural Networks in Psychiatry')", lines=1)
with gr.Row():
max_results_input = gr.Slider(1, 50, value=10, step=1, label="π Number of Results per Page")
page_input = gr.Slider(1, 200, value=1, step=1, label="π Page Number")
with gr.Row():
sort_input = gr.Dropdown(choices=["Year", "Title", "Journal"], value="Year", label="π Sort By")
journal_filter_input = gr.Textbox(label="π― Filter by Journal (Optional)", placeholder="Enter journal name or leave blank")
with gr.Row():
min_year_input = gr.Number(label="π
Min Year", value=None)
max_year_input = gr.Number(label="π
Max Year", value=None)
with gr.Row():
search_button = gr.Button("π Search")
export_csv_button = gr.Button("π Export as CSV")
export_docx_button = gr.Button("π Export as Word DOCX")
results_output = gr.HTML()
export_csv_output = gr.File(label="Download CSV")
export_docx_output = gr.File(label="Download Word DOCX")
def search_and_display(query, max_results, page, sort_by, journal_filter, min_year, max_year):
global global_df
result_text, df = fetch_pubmed_articles(query, max_results, page, sort_by, journal_filter, min_year, max_year)
global_df = df
return result_text
def export_csv():
if global_df is not None:
return export_results(global_df, "CSV")
def export_docx():
if global_df is not None:
return export_results(global_df, "DOCX")
search_button.click(search_and_display,
inputs=[query_input, max_results_input, page_input, sort_input, journal_filter_input, min_year_input, max_year_input],
outputs=results_output)
export_csv_button.click(export_csv, outputs=export_csv_output)
export_docx_button.click(export_docx, outputs=export_docx_output)
if __name__ == "__main__":
app.launch(inbrowser=True)
|