File size: 2,215 Bytes
1411075
 
b94ef99
1411075
94b3916
 
 
b94ef99
94b3916
b94ef99
94b3916
1411075
 
94b3916
1411075
 
94b3916
 
 
 
 
 
 
b94ef99
94b3916
 
 
 
 
 
b94ef99
1411075
94b3916
1411075
94b3916
b94ef99
1411075
94b3916
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
# genesis/api_clients/pubmed_api.py
import requests
from xml.etree import ElementTree as ET

NCBI_EUTILS_BASE = "https://eutils.ncbi.nlm.nih.gov/entrez/eutils"

def search_pubmed(query: str, max_results: int = 10, api_key: str = None):
    """
    Search PubMed for a given query and return a list of PMIDs.
    """
    params = {
        "db": "pubmed",
        "term": query,
        "retmode": "json",
        "retmax": max_results,
    }
    if api_key:
        params["api_key"] = api_key

    response = requests.get(f"{NCBI_EUTILS_BASE}/esearch.fcgi", params=params)
    response.raise_for_status()
    data = response.json()
    return data.get("esearchresult", {}).get("idlist", [])


def fetch_pubmed_details(pmids: list, api_key: str = None):
    """
    Fetch detailed article data for given PMIDs.
    """
    if not pmids:
        return []

    params = {
        "db": "pubmed",
        "id": ",".join(pmids),
        "retmode": "xml"
    }
    if api_key:
        params["api_key"] = api_key

    response = requests.get(f"{NCBI_EUTILS_BASE}/efetch.fcgi", params=params)
    response.raise_for_status()
    return parse_pubmed_xml(response.text)


def parse_pubmed_xml(xml_text: str):
    """
    Parse PubMed XML into structured dicts.
    """
    root = ET.fromstring(xml_text)
    articles = []

    for article in root.findall(".//PubmedArticle"):
        title_el = article.find(".//ArticleTitle")
        abstract_el = article.find(".//AbstractText")
        journal_el = article.find(".//Journal/Title")
        year_el = article.find(".//PubDate/Year")

        articles.append({
            "title": title_el.text if title_el is not None else None,
            "abstract": abstract_el.text if abstract_el is not None else None,
            "journal": journal_el.text if journal_el is not None else None,
            "year": year_el.text if year_el is not None else None,
        })

    return articles


def search_and_fetch(query: str, max_results: int = 5, api_key: str = None):
    """
    Convenience function: search and fetch article details.
    """
    pmids = search_pubmed(query, max_results=max_results, api_key=api_key)
    return fetch_pubmed_details(pmids, api_key=api_key)