feat(pmid): retrieve PublicationTypeList from PubMed metadata#57
Conversation
Closes #56. Surface PubMed publication types (MeSH publication-type descriptors, e.g. "Case Reports", "Clinical Trial", "Review" — see https://www.nlm.nih.gov/mesh/pubtypes.html) end-to-end. - ReferenceContent gains a publication_types field. - PMIDSource fetches the article XML once and parses both MeSH terms and publication types from it (no extra NCBI round-trip): _fetch_pubmed_xml plus pure parsers _parse_mesh_terms / _parse_publication_types. - Persisted to and reloaded from the disk cache frontmatter. - Exposed in lookup json/yaml/text output. Tests written first: XML parse (present/absent), fetch() population with mocked Entrez.efetch, cache round-trip, plus doctests on the parsers. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
Claude finished @caufieldjh's task in 1m 39s —— View job PR Review: PublicationTypeList from PubMed metadata
Overall this is a clean, well-scoped change. It follows the repo's TDD conventions, adds real (mocked-Entrez) tests plus doctests, threads the new field consistently through model → source → cache → CLI, and the docstrings are genuinely helpful. Nice work. A few notes below, none blocking. 👍 Strengths
🔧 Minor suggestions (non-blocking)1. Redundant self-assignment in cache load — publication_types = frontmatter.get("publication_types")
if publication_types and isinstance(publication_types, list):
publication_types = publication_types # no-op branch
elif publication_types:
publication_types = [publication_types]
else:
publication_types = NoneThe def _as_optional_list(value):
if not value:
return None
return value if isinstance(value, list) else [value]Worth doing only if you want to tidy the trio together; otherwise consistency is a fine reason to leave it. 2. Still two efetch calls per PMID — 3. Test gap: empty Bugs / security / performanceNo correctness bugs spotted. No security concerns (read-only parsing of NCBI XML, values preserved verbatim). Performance is neutral-to-slightly-better (one fewer XML fetch than before). The Test coverage is solid for the happy paths and the round-trip; the only real gap is the empty-list edge case above. |
- Collapse the repeated authors/keywords/publication_types frontmatter list-coercion into a shared _as_optional_list helper (review note 1). - Add empty-list edge-case tests for _parse_publication_types and _parse_mesh_terms, covering the `return x if x else None` branch (note 3). Deferring note 2 (folding the abstract into the single article-XML fetch): the text-mode abstract fetch returns a richer formatted citation block than the raw AbstractText XML nodes and feeds supporting-text validation, so the swap is a behavior change rather than a mechanical cleanup — left as a follow-up, as the reviewer flagged it deferrable. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
Thanks for the review! Addressed in 9caecc9: Note 1 (redundant self-assignment) — collapsed the Note 3 (empty-list edge case) — added Note 2 (still two efetch calls) — deferring for now. The
|
|
Claude finished @caufieldjh's task in 1m 14s —— View job Follow-up review — fixes in 9caecc9 ✅I re-reviewed the commit that addressed my earlier notes. All three items are handled correctly.
Note 1 — list-coercion helper ✅
Note 3 — empty-element edge cases ✅
Note 2 — single-fetch optimizationReasonable deferral, and the reasoning in the commit message is sound: the Minor nit (non-blocking)
Nothing outstanding on my end. The change is complete, consistent, and the edge cases my earlier review flagged are now covered. LGTM 🚀 Note: I couldn't run the test suite here (test execution wasn't permitted in this job), so I'm relying on the reported |
Closes #56.
Retrieves PubMed's
PublicationTypeList— the MeSH publication-type descriptors that classify a source (e.g. "Case Reports", "Clinical Trial", "Review"; full list at https://www.nlm.nih.gov/mesh/pubtypes.html) — and surfaces it end-to-end.Changes
ReferenceContentgains apublication_types: Optional[list[str]]field, the single carrier for citation metadata.PMIDSourcenow fetches the article XML once and parses both MeSH terms and publication types from it, avoiding a second NCBI round-trip. Split into_fetch_pubmed_xml(fetch) plus pure parsers_parse_mesh_terms/_parse_publication_types.lookupjson / yaml / text output.Example
A real lookup of
PMID:33301246(the BNT162b2 trial paper) now caches:Notes
Journal Articletype that tags nearly every record — not filtered, since it's a legitimate value downstream consumers may want.Testing
Tests written first (TDD), following the repo's mocked-Entrez pattern: XML parse (present/absent),
fetch()population with mockedEntrez.efetch, disk-cache round-trip, plus doctests on the parsers. Verified live againstPMID:33301246.Full
just testgreen: 619 passed, mypy clean, ruff clean.🤖 Generated with Claude Code