Skip to main content

PyPI - Version PyPI - Types PyPI - Python Version CI docs

pmid-to-citation

Fetch PubMed records from the NCBI Entrez API by PMID and render them as citation/reference text.

Status: pre-1.0. The public API may change between minor releases.

Installation

pip install pmid-to-citation

Quick start

tool and email are required, and deliberately have no defaults: the Entrez usage guidelines require every request to identify its caller, and a library must not answer that on its user's behalf.

import asyncio
from pmid_to_citation import fetch_citation

citation = asyncio.run(fetch_citation(1, tool="my-app", email="me@example.org"))
# 'Makar, A. B., McMartin, K. E., Palese, M. & Tephly, T. R. Formate assay in
#  body fluids: application in methanol poisoning. <i>Biochem Med</i>
#  <b>13</b>, 117–26 (1975).'

The rendered text is an HTML fragment — the Nature style italicises journal names, emboldens volume numbers, and & arrives as &amp;. Treat it as markup, not as plain text.

The three layers

Fetching and formatting are separate, and each layer is usable on its own.

1. Client — talks to Entrez over HTTP, and knows nothing about citations. Reuse one client for several records rather than reconnecting per PMID:

from pmid_to_citation import EntrezClient

async with EntrezClient(tool="my-app", email="me@example.org") as client:
    record = await client.get_record(31341288)
    raw = await client.get_record_text(31341288)  # unparsed MEDLINE text

An NCBI_API_KEY in the environment is picked up automatically; it raises the rate limit from 3 to 10 requests per second.

Many PMIDs at once

EFetch accepts many identifiers per call, so fetching a reference list costs a handful of requests rather than one per PMID:

from pmid_to_citation import fetch_citations

wanted = [1, 31341288, 35642643]
citations = await fetch_citations(wanted, tool="my-app", email="me@example.org")

fetch_records and EntrezClient.get_records do the same for records. All three return a mapping keyed by PMID, and batch requests concurrently at the rate the Entrez guidelines permit.

PMIDs that Entrez does not know are absent from the result rather than raising. Entrez omits them silently, and one retracted or mistyped identifier should not defeat a request for hundreds:

records = await fetch_records(wanted, tool="my-app", email="me@example.org")
missing = [pmid for pmid in wanted if pmid not in records]

Identifiers are split into batches of batch_size (200 by default); raising it switches those requests to POST, as NCBI asks for long lists. Duplicates are requested once.

2. Record models — validated, normalised models of a PubMed record, with no knowledge of HTTP or of output formats. Parse text you obtained anywhere:

from pmid_to_citation import parse_medline, parse_medline_file

record = parse_medline(raw)
record = parse_medline_file("record.txt")
records = parse_medline_records(multi_record_text)  # a multi-PMID response

record.title       # 'Formate assay in body fluids: application in methanol poisoning.'
record.authors[0]  # Author(last_name='Makar', initials='AB', ...)
record.other_fields  # any MEDLINE tag this library does not model, kept verbatim

3. Styles — pure functions from a record to text, with no I/O. Compiling a style is expensive, so reuse a formatter:

from pmid_to_citation import CitationFormatter, CitationStyle

formatter = CitationFormatter(CitationStyle.NATURE)
formatter.format_citation(record)
formatter.format_citations([record, other_record])  # reuses the compiled style

Rendering goes through citeproc-py and a Citation Style Language definition, which is what will make further styles cheap to add. That is an implementation detail: no CSL type appears in the public API.

Errors

Every failure raises a subclass of PmidToCitationError, so one except clause catches anything this library reports:

Exception Raised when
EntrezError Entrez is unreachable or reports an HTTP error
RecordNotFoundError Entrez holds no record for the requested PMID
RecordParseError A response cannot be interpreted as a MEDLINE record
CitationFormatError A record cannot be rendered in the requested style
UnknownStyleError No definition is installed for the requested style

RecordNotFoundError is an EntrezError; UnknownStyleError is a CitationFormatError.

Typing

The package ships py.typed and is checked with pyright in strict mode, so the annotations are part of the published contract.

Contributing

Contributions are welcome! See CONTRIBUTING.md for the development setup, the commit message convention, and how releases are cut.

Security

To report a vulnerability, see SECURITY.md.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pmid_to_citation-0.1.0.tar.gz (118.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pmid_to_citation-0.1.0-py3-none-any.whl (32.9 kB view details)

Uploaded Python 3

File details

Details for the file pmid_to_citation-0.1.0.tar.gz.

File metadata

  • Download URL: pmid_to_citation-0.1.0.tar.gz
  • Upload date:
  • Size: 118.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for pmid_to_citation-0.1.0.tar.gz
Algorithm Hash digest
SHA256 a972aa536908fb20ef21104fb3c0bf2cf7eec3c1f1a907a3157fe145a65baf04
MD5 159978596be171dcf95c803e0ce16882
BLAKE2b-256 f39e5f79dfd2e0e817833aa8817e93e4a4b0248d5df3518d94ceead4acc4128e

See more details on using hashes here.

Provenance

The following attestation bundles were made for pmid_to_citation-0.1.0.tar.gz:

Publisher: release-please.yml on medgen-mainz/pmid-to-citation

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pmid_to_citation-0.1.0-py3-none-any.whl.

File metadata

File hashes

Hashes for pmid_to_citation-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 4470eff7468d0543f555ad9825cd795f5312d917f4cdec4f1d4f0d7d244a71f0
MD5 2c37530480c4f94196d33c21baafb540
BLAKE2b-256 3538b0804faa0a87df8421345796eff37d1d972bfdbb3d2d7f8adde3d958992d

See more details on using hashes here.

Provenance

The following attestation bundles were made for pmid_to_citation-0.1.0-py3-none-any.whl:

Publisher: release-please.yml on medgen-mainz/pmid-to-citation

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

0.1.1

2 files

This release

0.1.0 This release

2 files

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page