Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -13,6 +13,7 @@ translations = {
|
|
| 13 |
"language_option": "English",
|
| 14 |
"language_label": "Language",
|
| 15 |
"results_title": "Search Results",
|
|
|
|
| 16 |
"error_message": "An error occurred while fetching data from PubMed.",
|
| 17 |
"no_results": "No articles found for the given query.",
|
| 18 |
"col_index": "Index",
|
|
@@ -20,7 +21,7 @@ translations = {
|
|
| 20 |
"col_abstract": "Abstract",
|
| 21 |
"col_authors": "Authors",
|
| 22 |
"col_link": "Link",
|
| 23 |
-
"spinner_searching": "Searching PubMed and fetching articles...",
|
| 24 |
"spinner_translating": "Translating results to Chinese...",
|
| 25 |
"translation_warning": "Could not translate an entry. Displaying original text."
|
| 26 |
},
|
|
@@ -31,6 +32,7 @@ translations = {
|
|
| 31 |
"language_option": "中文",
|
| 32 |
"language_label": "语言",
|
| 33 |
"results_title": "检索结果",
|
|
|
|
| 34 |
"error_message": "从 PubMed 获取数据时出错。",
|
| 35 |
"no_results": "未找到相关文献。",
|
| 36 |
"col_index": "序号",
|
|
@@ -38,7 +40,7 @@ translations = {
|
|
| 38 |
"col_abstract": "文献摘要",
|
| 39 |
"col_authors": "文献作者",
|
| 40 |
"col_link": "文献链接",
|
| 41 |
-
"spinner_searching": "正在检索 PubMed 并获取文献...",
|
| 42 |
"spinner_translating": "正在将结果翻译成中文...",
|
| 43 |
"translation_warning": "部分条目翻译失败,将显示原文。"
|
| 44 |
}
|
|
@@ -47,10 +49,10 @@ translations = {
|
|
| 47 |
def get_translation(lang, key):
|
| 48 |
return translations[lang][key]
|
| 49 |
|
| 50 |
-
@st.cache_data(ttl=3600)
|
| 51 |
def search_pubmed(query, retmax=200):
|
| 52 |
"""
|
| 53 |
-
使用PubMed API进行检索
|
| 54 |
"""
|
| 55 |
base_url = "https://eutils.ncbi.nlm.nih.gov/entrez/eutils/"
|
| 56 |
search_url = f"{base_url}esearch.fcgi?db=pubmed&term={query}&retmax={retmax}"
|
|
@@ -64,14 +66,15 @@ def search_pubmed(query, retmax=200):
|
|
| 64 |
st.error(f"Error during PubMed ID search: {e}")
|
| 65 |
return []
|
| 66 |
|
| 67 |
-
@st.cache_data(ttl=3600)
|
| 68 |
-
def fetch_articles(_id_list):
|
| 69 |
"""
|
| 70 |
根据ID列表获取文献详情
|
| 71 |
"""
|
| 72 |
if not _id_list:
|
| 73 |
return None
|
| 74 |
base_url = "https://eutils.ncbi.nlm.nih.gov/entrez/eutils/"
|
|
|
|
| 75 |
ids = ",".join(_id_list)
|
| 76 |
fetch_url = f"{base_url}efetch.fcgi?db=pubmed&id={ids}&rettype=xml"
|
| 77 |
try:
|
|
@@ -117,7 +120,6 @@ def parse_articles(xml_data):
|
|
| 117 |
def main():
|
| 118 |
st.set_page_config(layout="wide", page_title="PubMed Search Tool")
|
| 119 |
|
| 120 |
-
# 语言选择
|
| 121 |
lang = st.sidebar.radio(
|
| 122 |
get_translation("en", "language_label") + " / " + get_translation("zh", "language_label"),
|
| 123 |
("en", "zh"),
|
|
@@ -125,48 +127,45 @@ def main():
|
|
| 125 |
)
|
| 126 |
|
| 127 |
st.title(get_translation(lang, "title"))
|
| 128 |
-
|
| 129 |
-
# 搜索框
|
| 130 |
search_query = st.text_input("", placeholder=get_translation(lang, "search_placeholder"))
|
| 131 |
|
| 132 |
if st.button(get_translation(lang, "search_button")):
|
| 133 |
if search_query:
|
| 134 |
with st.spinner(get_translation(lang, "spinner_searching")):
|
| 135 |
-
|
|
|
|
|
|
|
|
|
|
| 136 |
if id_list:
|
| 137 |
-
xml_data = fetch_articles(tuple(id_list))
|
| 138 |
-
if xml_data
|
| 139 |
-
articles = parse_articles(xml_data)
|
| 140 |
-
else:
|
| 141 |
-
articles = []
|
| 142 |
else:
|
| 143 |
articles = []
|
| 144 |
|
| 145 |
if articles:
|
| 146 |
st.subheader(get_translation(lang, "results_title"))
|
|
|
|
|
|
|
| 147 |
df = pd.DataFrame(articles)
|
| 148 |
|
| 149 |
-
# 如果是中文,则进行翻译
|
| 150 |
if lang == 'zh':
|
| 151 |
with st.spinner(get_translation(lang, "spinner_translating")):
|
| 152 |
translator = Translator()
|
| 153 |
-
# 创建一个新的DataFrame来存储翻译结果
|
| 154 |
df_translated = df.copy()
|
| 155 |
for index, row in df.iterrows():
|
| 156 |
try:
|
| 157 |
-
# 翻译标题
|
| 158 |
if row['Title'] != "No Title":
|
| 159 |
df_translated.at[index, 'Title'] = translator.translate(row['Title'], dest='zh-cn').text
|
| 160 |
-
# 翻译摘要
|
| 161 |
if row['Abstract'] != "No Abstract":
|
| 162 |
df_translated.at[index, 'Abstract'] = translator.translate(row['Abstract'], dest='zh-cn').text
|
| 163 |
except Exception:
|
| 164 |
-
|
| 165 |
-
|
|
|
|
|
|
|
| 166 |
continue
|
| 167 |
df = df_translated
|
| 168 |
-
|
| 169 |
-
|
| 170 |
df.index = range(1, len(df) + 1)
|
| 171 |
df.rename(columns={
|
| 172 |
"Title": get_translation(lang, "col_title"),
|
|
@@ -175,7 +174,6 @@ def main():
|
|
| 175 |
"Link": get_translation(lang, "col_link")
|
| 176 |
}, inplace=True)
|
| 177 |
df.index.name = get_translation(lang, "col_index")
|
| 178 |
-
|
| 179 |
st.dataframe(df)
|
| 180 |
else:
|
| 181 |
st.warning(get_translation(lang, "no_results"))
|
|
|
|
| 13 |
"language_option": "English",
|
| 14 |
"language_label": "Language",
|
| 15 |
"results_title": "Search Results",
|
| 16 |
+
"showing_results": "Showing {count} articles.",
|
| 17 |
"error_message": "An error occurred while fetching data from PubMed.",
|
| 18 |
"no_results": "No articles found for the given query.",
|
| 19 |
"col_index": "Index",
|
|
|
|
| 21 |
"col_abstract": "Abstract",
|
| 22 |
"col_authors": "Authors",
|
| 23 |
"col_link": "Link",
|
| 24 |
+
"spinner_searching": "Searching PubMed and fetching up to 200 articles...",
|
| 25 |
"spinner_translating": "Translating results to Chinese...",
|
| 26 |
"translation_warning": "Could not translate an entry. Displaying original text."
|
| 27 |
},
|
|
|
|
| 32 |
"language_option": "中文",
|
| 33 |
"language_label": "语言",
|
| 34 |
"results_title": "检索结果",
|
| 35 |
+
"showing_results": "共找到 {count} 篇文献。",
|
| 36 |
"error_message": "从 PubMed 获取数据时出错。",
|
| 37 |
"no_results": "未找到相关文献。",
|
| 38 |
"col_index": "序号",
|
|
|
|
| 40 |
"col_abstract": "文献摘要",
|
| 41 |
"col_authors": "文献作者",
|
| 42 |
"col_link": "文献链接",
|
| 43 |
+
"spinner_searching": "正在检索 PubMed 并获取最多 200 篇文献...",
|
| 44 |
"spinner_translating": "正在将结果翻译成中文...",
|
| 45 |
"translation_warning": "部分条目翻译失败,将显示原文。"
|
| 46 |
}
|
|
|
|
| 49 |
def get_translation(lang, key):
|
| 50 |
return translations[lang][key]
|
| 51 |
|
| 52 |
+
@st.cache_data(ttl=3600)
|
| 53 |
def search_pubmed(query, retmax=200):
|
| 54 |
"""
|
| 55 |
+
使用PubMed API进行检索,并明确指定retmax
|
| 56 |
"""
|
| 57 |
base_url = "https://eutils.ncbi.nlm.nih.gov/entrez/eutils/"
|
| 58 |
search_url = f"{base_url}esearch.fcgi?db=pubmed&term={query}&retmax={retmax}"
|
|
|
|
| 66 |
st.error(f"Error during PubMed ID search: {e}")
|
| 67 |
return []
|
| 68 |
|
| 69 |
+
@st.cache_data(ttl=3600)
|
| 70 |
+
def fetch_articles(_id_list):
|
| 71 |
"""
|
| 72 |
根据ID列表获取文献详情
|
| 73 |
"""
|
| 74 |
if not _id_list:
|
| 75 |
return None
|
| 76 |
base_url = "https://eutils.ncbi.nlm.nih.gov/entrez/eutils/"
|
| 77 |
+
# PubMed efetch有URL长度限制,分批获取更稳妥,但为简化,此处仍一次性获取
|
| 78 |
ids = ",".join(_id_list)
|
| 79 |
fetch_url = f"{base_url}efetch.fcgi?db=pubmed&id={ids}&rettype=xml"
|
| 80 |
try:
|
|
|
|
| 120 |
def main():
|
| 121 |
st.set_page_config(layout="wide", page_title="PubMed Search Tool")
|
| 122 |
|
|
|
|
| 123 |
lang = st.sidebar.radio(
|
| 124 |
get_translation("en", "language_label") + " / " + get_translation("zh", "language_label"),
|
| 125 |
("en", "zh"),
|
|
|
|
| 127 |
)
|
| 128 |
|
| 129 |
st.title(get_translation(lang, "title"))
|
|
|
|
|
|
|
| 130 |
search_query = st.text_input("", placeholder=get_translation(lang, "search_placeholder"))
|
| 131 |
|
| 132 |
if st.button(get_translation(lang, "search_button")):
|
| 133 |
if search_query:
|
| 134 |
with st.spinner(get_translation(lang, "spinner_searching")):
|
| 135 |
+
# *** 关键修正点 ***
|
| 136 |
+
# 明确传入 retmax=200
|
| 137 |
+
id_list = search_pubmed(search_query, retmax=200)
|
| 138 |
+
|
| 139 |
if id_list:
|
| 140 |
+
xml_data = fetch_articles(tuple(id_list))
|
| 141 |
+
articles = parse_articles(xml_data) if xml_data else []
|
|
|
|
|
|
|
|
|
|
| 142 |
else:
|
| 143 |
articles = []
|
| 144 |
|
| 145 |
if articles:
|
| 146 |
st.subheader(get_translation(lang, "results_title"))
|
| 147 |
+
st.info(get_translation(lang, "showing_results").format(count=len(articles)))
|
| 148 |
+
|
| 149 |
df = pd.DataFrame(articles)
|
| 150 |
|
|
|
|
| 151 |
if lang == 'zh':
|
| 152 |
with st.spinner(get_translation(lang, "spinner_translating")):
|
| 153 |
translator = Translator()
|
|
|
|
| 154 |
df_translated = df.copy()
|
| 155 |
for index, row in df.iterrows():
|
| 156 |
try:
|
|
|
|
| 157 |
if row['Title'] != "No Title":
|
| 158 |
df_translated.at[index, 'Title'] = translator.translate(row['Title'], dest='zh-cn').text
|
|
|
|
| 159 |
if row['Abstract'] != "No Abstract":
|
| 160 |
df_translated.at[index, 'Abstract'] = translator.translate(row['Abstract'], dest='zh-cn').text
|
| 161 |
except Exception:
|
| 162 |
+
# 只警告一次
|
| 163 |
+
if 'translation_warning_shown' not in st.session_state:
|
| 164 |
+
st.warning(get_translation(lang, "translation_warning"), icon="⚠️")
|
| 165 |
+
st.session_state.translation_warning_shown = True
|
| 166 |
continue
|
| 167 |
df = df_translated
|
| 168 |
+
|
|
|
|
| 169 |
df.index = range(1, len(df) + 1)
|
| 170 |
df.rename(columns={
|
| 171 |
"Title": get_translation(lang, "col_title"),
|
|
|
|
| 174 |
"Link": get_translation(lang, "col_link")
|
| 175 |
}, inplace=True)
|
| 176 |
df.index.name = get_translation(lang, "col_index")
|
|
|
|
| 177 |
st.dataframe(df)
|
| 178 |
else:
|
| 179 |
st.warning(get_translation(lang, "no_results"))
|