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).

Metadata

Release files for orcid2bib 0.4.4

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for orcid2bib 0.4.4
File Size Uploaded
orcid2bib-0.4.4.tar.gz 47.7 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for orcid2bib 0.4.4
File Interpreter ABI Platform
orcid2bib-0.4.4-py3-none-any.whl Python 3 none any Details

Total release size: 84.7 kB

Release files / orcid2bib-0.4.4.tar.gz

Download URL orcid2bib-0.4.4.tar.gz
Size 47.7 kB
Tags Source
SHA-256 checksum
How to use checksums
1a07e045f60afa538e032b48bad27fcdcb511fa1037069c9a32c556c086a1c21
BLAKE2b-256 checksum
How to use checksums
15a282a9fcffca47d71572f02879fe8d35c50f7cc7e175f73a4c4af24b8a5b79
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 11, 2026.

Transparency log

Release files / orcid2bib-0.4.4-py3-none-any.whl

Download URL orcid2bib-0.4.4-py3-none-any.whl
Size 37.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
1fec9334a49fca89256388322e5758558112b4ed6123e771140c513036e3c085
BLAKE2b-256 checksum
How to use checksums
0d781dc5e797db8eb725fc255a4d96ee732bbad245b9bc99a19b4aba30a34890
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 11, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.4.4 This release

2 release files

0.4.3

2 release files

0.4.2

2 release files

0.4.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page