Skip to main content

orcid2bib

PyPI Python versions License: EUPL-1.2 GitHub

Fetch all public works from an ORCID profile and compile them into a single BibTeX (.bib) file. This package also ships bibdiff, a tool for comparing BibTeX files.

Repository: github.com/cdruee/orcid2bib

For each work, orcid2bib builds a BibTeX entry from the ORCID record:

  • Entry type is guessed from the ORCID work type (e.g. journal-article@article, conference-paper@inproceedings, book-chapter@incollection, dissertation-thesis@phdthesis, preprint/working-paper@unpublished, etc.), falling back to @misc for anything unrecognized. Only standard (plain-LaTeX) BibTeX entry types are used.
  • Author is taken from the work's ORCID contributors (author-role entries).
  • Journal / booktitle, year, title, and DOI are filled from ORCID where present.
  • If a DOI is found, it's resolved (via doi.org content negotiation for CSL-JSON metadata) to fetch author, journal, year, volume, number, pages, and keywords — overriding the ORCID values with the DOI-sourced ones where available, since publisher metadata is usually more complete and accurate. Use -n/--no-doi-lookup to skip this and rely on ORCID data only.
  • Pages are normalized to BibTeX's first--last double-dash form (publisher metadata often uses a single hyphen or an en/em dash instead, which most BibTeX-aware tools — including Sphinx's sphinxcontrib-bibtex — don't recognize as a range).
  • Each entry's provenance note (Retrieved via ORCID API put-code ...) is stored in a comment field rather than note, since note is rendered by most BibTeX styles and comment generally isn't — keeping it out of the way of the actual reference text.

Install

pip install orcid2bib

Development / latest version

To install the unreleased development version directly from GitHub instead:

pip install "git+https://github.com/cdruee/orcid2bib.git"

Or clone and install it as an editable install (recommended if you're working on the code):

git clone https://github.com/cdruee/orcid2bib.git
cd orcid2bib
pip install -e ".[dev]"

Prebuilt sdist/wheel files for each release are also attached to the corresponding GitHub Release, if you'd rather install one of those directly instead of going through the PyPI index.

Usage

orcid2bib 0000-0002-0103-4275

Options:

usage: orcid2bib [-h] [-o FILE] [--delay SECONDS] [-n] [-v] [--version] orcid_id

positional arguments:
  orcid_id              ORCID iD of the profile to fetch, e.g. 0000-0002-0103-4275

options:
  -h, --help             show this help message and exit
  -o FILE, --output FILE
                          Output .bib file path (default: <orcid_id>_publications.bib)
  --delay SECONDS        Delay between ORCID API requests, in seconds (default: 0.2)
  -n, --no-doi-lookup    Disable resolving each work's DOI for extra metadata (author,
                          journal, year, volume, number, pages, keywords). By default,
                          DOI-resolved data overrides ORCID's own fields where available.
  -v, --verbose          Print diagnostic details per work: detected entry type, DOI
                          found, DOI-lookup requests/responses, and why fields were or
                          weren't overridden.
  --version              show program's version number and exit

Example with a custom output path:

orcid2bib 0000-0002-0103-4275 -o my_publications.bib

Example skipping DOI lookups (ORCID data only, faster, no extra network calls):

orcid2bib 0000-0002-0103-4275 -n

Example diagnosing why DOI enrichment isn't showing up:

orcid2bib 0000-0002-0103-4275 -v

As a library

from orcid2bib import run

run("0000-0002-0103-4275", output_filename="my_publications.bib")

bibdiff

bibdiff compares two BibTeX files: it validates their syntax, flags likely duplicate entries within each file, matches corresponding entries across the two files, and shows a field-by-field diff for each matched pair.

bibdiff mylibrary.bib exported_from_zotero.bib

It follows classic diff(1) conventions: normal output is just the differences — no section headers, no duplicate listing, no summary. Add -v/--verbose for all of that plus progress details.

How matching works, in order of confidence:

  1. Identical citation key.
  2. Identical DOI (or, failing that, ISBN), normalized (case, https://doi.org/ prefix, hyphens).
  3. A weighted, typo- and abbreviation-tolerant score combining whichever of first author, year, title, and journal/booktitle/pages are available. This also tolerates first-name initials (J. Smith vs John Smith) and abbreviated venue names (J. Am. Chem. Soc. vs Journal of the American Chemical Society).

The same scoring is used to detect probable duplicates within a single file (shown with -v).

Options:

usage: bibdiff [-h] [-c | -y] [-q] [-s] [-N] [--match-threshold SCORE]
               [--possible-threshold SCORE] [-o FILE] [-v] [-d]
               [--color] [--version]
               first second

positional arguments:
  first                 First .bib file
  second                Second .bib file

options:
  -h, --help            show this help message and exit
  -c, --context         Show field differences in context-diff style (default:
                        unified diff)
  -y, --side-by-side    Show field differences side by side (default: unified
                        diff)
  -q, --brief           Report only whether entries differ, one line per pair:
                        "KEY1 KEY2 differ", or "KEY1 KEY2 renamed" if only the
                        citation key differs. With -s, also reports "KEY1 KEY2
                        are identical".
  -s, --report-identical-files
                        Also report matched pairs with no differences at all
                        (same citation key, all fields identical). Omitted by
                        default.
  -N, --new-file        Treat an entry missing on one side as blank there and
                        diff it against the blank, instead of listing it under
                        'only in ...'.
  --match-threshold SCORE
                        Minimum score (0-1) to treat two entries as a
                        confirmed match (default: 0.75)
  --possible-threshold SCORE
                        Minimum score (0-1) to flag two entries as a possible
                        match needing review (default: 0.55)
  -o FILE, --output FILE
                        Write the report to a file instead of stdout
  -v, --verbose         Also print progress details, possible-duplicate
                        listings, section headers/counts, and a final summary.
                        Normal output has none of these.
  -d, --debug           Also print the score breakdown (per-component scores
                        and weights) for every match, possible match, and
                        duplicate pair found
  --color               Colorize output (green=added, red=removed) when
                        writing to a terminal, as diff(1)'s --color=auto does.
  --version             show program's version number and exit

Entries found only in one file are reported as only in FILE: KEY (Title), so it's always clear which side an entry belongs to.

The process exits 0 if the two files are equivalent, 1 if any differences were found (mirroring diff's exit codes), and 2 on a syntax/parse error.

Example with a side-by-side field comparison and color:

bibdiff mylibrary.bib exported_from_zotero.bib -y --color

Example: a quick one-line-per-entry summary of what changed:

bibdiff mylibrary.bib exported_from_zotero.bib -q

Example seeing exactly how each score was computed:

bibdiff mylibrary.bib exported_from_zotero.bib -v -d

Contributing

Bug reports and pull requests are welcome at github.com/cdruee/orcid2bib/issues.

Versioning

The package version is derived automatically from git tags via setuptools_scm — there's no version number to edit by hand. To release a new version, tag the commit:

git tag v1.2.3
git push --tags

and the next build/install picks up 1.2.3 automatically (orcid2bib --version / bibdiff --version / orcid2bib.__version__ all reflect it). Between tags, or with uncommitted changes, the version includes a .devN+g<hash> (and .d<date> if the tree is dirty) suffix so it's always clear a build didn't come from a clean tagged commit. Building from a source tree with no git history at all (e.g. a bare zip export) falls back to 0.0.0 rather than failing.

License

Copyright (C) 2026 Clemens Drüe druee@uni-trier.de

Licensed under the EUPL-1.2 (European Union Public Licence, version 1.2). See LICENSE for the full text.

Author

Clemens Drüe (druee@uni-trier.de)

Acknowledgments

Developed with the assistance of Claude Sonnet 5 (Anthropic).

Download files

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

Source Distribution

orcid2bib-0.4.4.tar.gz (47.7 kB view details)

Uploaded Source

Built Distribution

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

orcid2bib-0.4.4-py3-none-any.whl (37.1 kB view details)

Uploaded Python 3

File details

Details for the file orcid2bib-0.4.4.tar.gz.

File metadata

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

File hashes

Hashes for orcid2bib-0.4.4.tar.gz
Algorithm Hash digest
SHA256 1a07e045f60afa538e032b48bad27fcdcb511fa1037069c9a32c556c086a1c21
MD5 94569a594343cceac1ea581f67df6330
BLAKE2b-256 15a282a9fcffca47d71572f02879fe8d35c50f7cc7e175f73a4c4af24b8a5b79

See more details on using hashes here.

Provenance

The following attestation bundles were made for orcid2bib-0.4.4.tar.gz:

Publisher: release.yml on cdruee/orcid2bib

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

File details

Details for the file orcid2bib-0.4.4-py3-none-any.whl.

File metadata

  • Download URL: orcid2bib-0.4.4-py3-none-any.whl
  • Upload date:
  • Size: 37.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for orcid2bib-0.4.4-py3-none-any.whl
Algorithm Hash digest
SHA256 1fec9334a49fca89256388322e5758558112b4ed6123e771140c513036e3c085
MD5 d94f571a69a74a1706b1e254d5b8fe01
BLAKE2b-256 0d781dc5e797db8eb725fc255a4d96ee732bbad245b9bc99a19b4aba30a34890

See more details on using hashes here.

Provenance

The following attestation bundles were made for orcid2bib-0.4.4-py3-none-any.whl:

Publisher: release.yml on cdruee/orcid2bib

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

Supported by

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