Spaces:
Sleeping
Sleeping
| """PubMed search tool wrapping NCBI Entrez API via Biopython.""" | |
| import os | |
| from xml.etree import ElementTree | |
| from agents import function_tool | |
| from Bio import Entrez | |
| Entrez.email = os.environ.get("NCBI_EMAIL", "user@example.com") | |
| def _fetch_details(id_list: list[str], max_results: int = 3) -> list[dict]: | |
| """Fetch paper metadata for a list of PubMed IDs.""" | |
| if not id_list: | |
| return [] | |
| ids = id_list[:max_results] | |
| handle = Entrez.efetch(db="pubmed", id=",".join(ids), rettype="xml", retmode="xml") | |
| raw = handle.read() | |
| handle.close() | |
| root = ElementTree.fromstring(raw) | |
| papers = [] | |
| for article in root.findall(".//PubmedArticle"): | |
| medline = article.find(".//MedlineCitation") | |
| art = medline.find(".//Article") if medline is not None else None | |
| if art is None: | |
| continue | |
| title_el = art.find("ArticleTitle") | |
| title = title_el.text if title_el is not None and title_el.text else "No title" | |
| abstract_el = art.find(".//AbstractText") | |
| abstract = abstract_el.text if abstract_el is not None and abstract_el.text else "No abstract available" | |
| pmid_el = medline.find("PMID") | |
| pmid = pmid_el.text if pmid_el is not None else "" | |
| # Extract DOI from ArticleIdList | |
| doi = "" | |
| for aid in article.findall(".//ArticleId"): | |
| if aid.get("IdType") == "doi": | |
| doi = aid.text or "" | |
| break | |
| papers.append( | |
| { | |
| "title": title, | |
| "abstract": abstract[:500], | |
| "pmid": pmid, | |
| "doi": doi, | |
| "url": f"https://pubmed.ncbi.nlm.nih.gov/{pmid}/", | |
| } | |
| ) | |
| return papers | |
| def pubmed_search(query: str, max_results: int = 3) -> str: | |
| """Search PubMed for papers matching the query. Returns titles, abstracts, PMIDs, and DOIs. | |
| Args: | |
| query: The search query for PubMed. | |
| max_results: Maximum number of papers to return (default 3). | |
| """ | |
| handle = Entrez.esearch(db="pubmed", term=query, retmax=max_results, sort="relevance") | |
| record = Entrez.read(handle) | |
| handle.close() | |
| id_list = record.get("IdList", []) | |
| if not id_list: | |
| return f"No PubMed results found for: {query}" | |
| papers = _fetch_details(id_list, max_results) | |
| if not papers: | |
| return f"No PubMed results found for: {query}" | |
| lines = [] | |
| for i, p in enumerate(papers, 1): | |
| lines.append( | |
| f"[PubMed {i}]\n" | |
| f"Title: {p['title']}\n" | |
| f"Abstract: {p['abstract']}\n" | |
| f"PMID: {p['pmid']}\n" | |
| f"DOI: {p['doi']}\n" | |
| f"URL: {p['url']}\n" | |
| ) | |
| return "\n".join(lines) | |