File size: 2,561 Bytes
1411075
a5bfe49
026bd38
 
 
94b3916
026bd38
 
a5bfe49
 
b94ef99
026bd38
b94ef99
94b3916
1411075
 
026bd38
 
1411075
026bd38
9fbaf8f
026bd38
 
94b3916
a5bfe49
94b3916
026bd38
94b3916
a5bfe49
b94ef99
026bd38
94b3916
1411075
a5bfe49
026bd38
 
1411075
026bd38
9fbaf8f
a5bfe49
026bd38
 
 
94b3916
026bd38
 
 
 
 
 
 
 
a5bfe49
 
026bd38
 
 
a5bfe49
026bd38
a5bfe49
 
 
026bd38
a5bfe49
026bd38
 
 
 
a5bfe49
 
9fbaf8f
026bd38
94b3916
026bd38
94b3916
a5bfe49
ec0d077
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
# genesis/api_clients/pubmed_api.py
import os
import requests
from typing import List, Dict, Optional
from xml.etree import ElementTree as ET

NCBI_API_KEY = os.getenv("NCBI_API_KEY")  # Optional but increases rate limits
NCBI_BASE = "https://eutils.ncbi.nlm.nih.gov/entrez/eutils"

def search_pubmed(query: str, max_results: int = 10) -> List[str]:
    """
    Search PubMed and return a list of PMIDs.
    """
    params = {
        "db": "pubmed",
        "term": query,
        "retmax": max_results,
        "api_key": NCBI_API_KEY
    }
    r = requests.get(f"{NCBI_BASE}/esearch.fcgi", params=params)
    r.raise_for_status()
    root = ET.fromstring(r.text)
    return [id_tag.text for id_tag in root.findall(".//Id")]

def fetch_pubmed_details(pmids: List[str]) -> List[Dict]:
    """
    Fetch detailed information for a list of PMIDs.
    """
    if not pmids:
        return []
    
    params = {
        "db": "pubmed",
        "id": ",".join(pmids),
        "retmode": "xml",
        "api_key": NCBI_API_KEY
    }
    r = requests.get(f"{NCBI_BASE}/efetch.fcgi", params=params)
    r.raise_for_status()
    
    root = ET.fromstring(r.text)
    articles = []

    for article in root.findall(".//PubmedArticle"):
        title = article.findtext(".//ArticleTitle", default="No title")
        abstract = " ".join([t.text for t in article.findall(".//AbstractText") if t.text])
        journal = article.findtext(".//Title", default="Unknown Journal")
        pub_date = article.findtext(".//PubDate/Year", default="Unknown Year")
        doi = None
        for id_tag in article.findall(".//ArticleId"):
            if id_tag.attrib.get("IdType") == "doi":
                doi = id_tag.text
        authors = []
        for author in article.findall(".//Author"):
            last = author.findtext("LastName")
            fore = author.findtext("ForeName")
            if last and fore:
                authors.append(f"{fore} {last}")
        pmid = article.findtext(".//PMID")
        articles.append({
            "pmid": pmid,
            "title": title,
            "abstract": abstract,
            "journal": journal,
            "pub_date": pub_date,
            "doi": doi,
            "authors": authors,
            "url": f"https://pubmed.ncbi.nlm.nih.gov/{pmid}/"
        })
    return articles

def search_and_fetch(query: str, max_results: int = 10) -> List[Dict]:
    """
    Convenience function: Search and fetch results in one step.
    """
    pmids = search_pubmed(query, max_results)
    return fetch_pubmed_details(pmids)