(paper: dict[str, Any])
| 564 | |
| 565 | |
| 566 | def normalize_semantic_scholar_paper(paper: dict[str, Any]) -> dict[str, Any]: |
| 567 | ext_ids = paper.get("externalIds") or {} |
| 568 | doi = normalize_whitespace(str(ext_ids.get("DOI", ""))) |
| 569 | arxiv_id = normalize_whitespace(str(ext_ids.get("ArXiv", ""))) |
| 570 | affiliations: list[str] = [] |
| 571 | authors: list[str] = [] |
| 572 | for author in paper.get("authors", []) or []: |
| 573 | if not isinstance(author, dict): |
| 574 | continue |
| 575 | name = normalize_whitespace(str(author.get("name", ""))) |
| 576 | if name: |
| 577 | authors.append(name) |
| 578 | raw_affs = author.get("affiliations", []) or [] |
| 579 | if isinstance(raw_affs, str): |
| 580 | raw_affs = [raw_affs] |
| 581 | for aff in raw_affs: |
| 582 | aff_name = normalize_whitespace(str(aff)) |
| 583 | if aff_name and aff_name not in affiliations: |
| 584 | affiliations.append(aff_name) |
| 585 | result = { |
| 586 | "title": normalize_whitespace(str(paper.get("title", ""))), |
| 587 | "abstract": normalize_whitespace(str(paper.get("abstract", ""))), |
| 588 | "authors": authors, |
| 589 | "affiliations": affiliations, |
| 590 | "venue": normalize_whitespace(str(paper.get("venue", ""))), |
| 591 | "year": normalize_whitespace(str(paper.get("year", ""))), |
| 592 | "doi": doi, |
| 593 | "arxiv_id": arxiv_id, |
| 594 | "source": "semantic_scholar", |
| 595 | "source_type": "semantic_scholar", |
| 596 | "source_url": normalize_whitespace(str(paper.get("url", ""))), |
| 597 | "metadata_sources": ["semantic_scholar"], |
| 598 | } |
| 599 | if arxiv_id and not result.get("pdf_url"): |
| 600 | result["pdf_url"] = f"https://arxiv.org/pdf/{arxiv_id}.pdf" |
| 601 | return result |
| 602 | |
| 603 | |
| 604 | def search_semantic_scholar(query: str, *, limit: int = 5) -> list[dict[str, Any]]: |
no test coverage detected