Spaces:
Running
Running
KevinIsInCoding Claude Sonnet 4.6 commited on
Commit ·
83263a0
1
Parent(s): 45900d6
fix(pmc): add rich progress bar to get_pmcids (499 calls, ~3 min)
Browse files- ingestion/pmc.py +36 -24
- scripts/ingest_papers.py +1 -2
ingestion/pmc.py
CHANGED
|
@@ -30,38 +30,50 @@ def _sleep() -> None:
|
|
| 30 |
def get_pmcids(pmids: list[str]) -> dict[str, str]:
|
| 31 |
"""
|
| 32 |
Map PubMed IDs to PMC IDs for papers with Open Access full text.
|
| 33 |
-
Sends one PMID at a time
|
| 34 |
-
|
| 35 |
Returns {pmid: pmcid}.
|
| 36 |
"""
|
| 37 |
_configure_entrez()
|
| 38 |
if not pmids:
|
| 39 |
return {}
|
| 40 |
|
|
|
|
| 41 |
result: dict[str, str] = {}
|
| 42 |
-
for pmid in pmids:
|
| 43 |
-
for attempt in range(3):
|
| 44 |
-
try:
|
| 45 |
-
handle = Entrez.elink(dbfrom="pubmed", db="pmc", id=pmid)
|
| 46 |
-
link_sets = Entrez.read(handle)
|
| 47 |
-
handle.close()
|
| 48 |
-
break
|
| 49 |
-
except Exception as exc:
|
| 50 |
-
if attempt == 2:
|
| 51 |
-
_logger.debug(f"elink failed for PMID {pmid}: {exc}")
|
| 52 |
-
link_sets = []
|
| 53 |
-
break
|
| 54 |
-
time.sleep(2 ** attempt)
|
| 55 |
-
|
| 56 |
-
for ls in link_sets:
|
| 57 |
-
for db_link in ls.get("LinkSetDb", []):
|
| 58 |
-
if db_link.get("DbTo") == "pmc":
|
| 59 |
-
links = db_link.get("Link", [])
|
| 60 |
-
if links:
|
| 61 |
-
result[pmid] = str(links[0]["Id"])
|
| 62 |
-
break
|
| 63 |
|
| 64 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 65 |
|
| 66 |
_logger.info("PMC ID lookup", extra={"data": {"pmids": len(pmids), "found": len(result)}})
|
| 67 |
return result
|
|
|
|
| 30 |
def get_pmcids(pmids: list[str]) -> dict[str, str]:
|
| 31 |
"""
|
| 32 |
Map PubMed IDs to PMC IDs for papers with Open Access full text.
|
| 33 |
+
Sends one PMID at a time — batch elink merges all results into one
|
| 34 |
+
LinkSet with no per-ID mapping, making it unusable for this purpose.
|
| 35 |
Returns {pmid: pmcid}.
|
| 36 |
"""
|
| 37 |
_configure_entrez()
|
| 38 |
if not pmids:
|
| 39 |
return {}
|
| 40 |
|
| 41 |
+
from rich.progress import Progress, SpinnerColumn, BarColumn, TaskProgressColumn, TimeRemainingColumn, TextColumn
|
| 42 |
result: dict[str, str] = {}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 43 |
|
| 44 |
+
with Progress(
|
| 45 |
+
SpinnerColumn(),
|
| 46 |
+
TextColumn("[progress.description]{task.description}"),
|
| 47 |
+
BarColumn(),
|
| 48 |
+
TaskProgressColumn(),
|
| 49 |
+
TimeRemainingColumn(),
|
| 50 |
+
) as progress:
|
| 51 |
+
task = progress.add_task("Looking up PMC IDs...", total=len(pmids))
|
| 52 |
+
|
| 53 |
+
for pmid in pmids:
|
| 54 |
+
for attempt in range(3):
|
| 55 |
+
try:
|
| 56 |
+
handle = Entrez.elink(dbfrom="pubmed", db="pmc", id=pmid)
|
| 57 |
+
link_sets = Entrez.read(handle)
|
| 58 |
+
handle.close()
|
| 59 |
+
break
|
| 60 |
+
except Exception as exc:
|
| 61 |
+
if attempt == 2:
|
| 62 |
+
_logger.debug(f"elink failed for PMID {pmid}: {exc}")
|
| 63 |
+
link_sets = []
|
| 64 |
+
break
|
| 65 |
+
time.sleep(2 ** attempt)
|
| 66 |
+
|
| 67 |
+
for ls in link_sets:
|
| 68 |
+
for db_link in ls.get("LinkSetDb", []):
|
| 69 |
+
if db_link.get("DbTo") == "pmc":
|
| 70 |
+
links = db_link.get("Link", [])
|
| 71 |
+
if links:
|
| 72 |
+
result[pmid] = str(links[0]["Id"])
|
| 73 |
+
break
|
| 74 |
+
|
| 75 |
+
_sleep()
|
| 76 |
+
progress.advance(task)
|
| 77 |
|
| 78 |
_logger.info("PMC ID lookup", extra={"data": {"pmids": len(pmids), "found": len(result)}})
|
| 79 |
return result
|
scripts/ingest_papers.py
CHANGED
|
@@ -69,9 +69,8 @@ def main() -> None:
|
|
| 69 |
|
| 70 |
# Step 3: Enrich with PMC full text
|
| 71 |
if not args.skip_fulltext:
|
| 72 |
-
console.print("[cyan]Looking up PMC IDs for Open Access full text...[/cyan]")
|
| 73 |
all_pmids = [p.pmid for p in papers]
|
| 74 |
-
pmcid_map = pmc.get_pmcids(all_pmids)
|
| 75 |
console.print(f"[green]{len(pmcid_map)} papers have PMC full text available[/green]")
|
| 76 |
|
| 77 |
pmid_to_paper = {p.pmid: p for p in papers}
|
|
|
|
| 69 |
|
| 70 |
# Step 3: Enrich with PMC full text
|
| 71 |
if not args.skip_fulltext:
|
|
|
|
| 72 |
all_pmids = [p.pmid for p in papers]
|
| 73 |
+
pmcid_map = pmc.get_pmcids(all_pmids) # shows its own progress bar
|
| 74 |
console.print(f"[green]{len(pmcid_map)} papers have PMC full text available[/green]")
|
| 75 |
|
| 76 |
pmid_to_paper = {p.pmid: p for p in papers}
|