fetchbib 0.6.0
Resolve DOIs and search queries into formatted BibTeX entries.
Requires Python: >=3.9

# fetchbib

A command-line tool to resolve DOIs and free-text search queries into formatted BibTeX entries.
Powered by [doi.org](https://www.doi.org/), [arXiv](https://arxiv.org/), and the [OpenAlex API](https://openalex.org/).

## Features

- Resolve DOIs to formatted BibTeX (bare DOIs or full URLs)
- Search by paper title via OpenAlex API
- Native arXiv support (arXiv DOIs route to arxiv.org)
- Batch processing from file or command line
- Write output to file (overwrite or append)
- Configurable: exclude ISSN/DOI fields, protect title capitalization

## Quick Start

Fetch BibTeX by DOI (bare or full URL, including arXiv):

```bash
fbib 10.1073/pnas.2322823121
fbib https://doi.org/10.1073/pnas.2322823121
fbib 10.48550/arXiv.2410.21554
```

```bibtex
@article{DeVerna_2024,
  author = {DeVerna, Matthew R. and Yan, Harry Yaojun and Yang, Kai-Cheng and Menczer, Filippo},
  DOI = {10.1073/pnas.2322823121},
  ISSN = {1091-6490},
  journal = {Proceedings of the National Academy of Sciences},
  month = dec,
  number = {50},
  publisher = {Proceedings of the National Academy of Sciences},
  title = {Fact-checking information from large language models can decrease headline discernment},
  url = {http://dx.doi.org/10.1073/pnas.2322823121},
  volume = {121},
  year = {2024}
}
```

Search by free text by including text between quotes:

```bash
fbib "Fact-checking information from large language models can decrease headline discernment"
```

> **Note**: OpenAlex searches titles and abstracts. Full or partial paper titles work best.
> Use `-n` to return multiple results if needed.
> See [Specify number of free-text matches](#specify-number-of-free-text-matches) section below.

## Installation

### `pip`

```bash
pip install fetchbib
```

### `uv`

```bash
uv tool install fetchbib
```

Requires Python 3.9+.

## Usage

```
fbib [-h] [-f FILE] [-o OUTPUT] [-a] [-n MAX_RESULTS]
     [--config-api-key KEY] [--config-protect-titles]
     [--config-exclude-issn] [--config-exclude-doi]
     [inputs ...]
```

### Flexible input

`fbib` accepts DOIs in any format — bare, full URL, or free-text search queries — and you can mix them freely.
Inputs are comma-separated, so all of the following work:

```bash
# Multiple positional arguments
fbib 10.1609/icwsm.v5i1.14126 10.1093/jcmc/zmz022

# Comma-separated string
fbib "10.1609/icwsm.v5i1.14126, 10.1093/jcmc/zmz022"

# Full DOI URLs
fbib "https://doi.org/10.1609/icwsm.v5i1.14126, https://doi.org/10.1093/jcmc/zmz022"

# Mix DOIs, URLs, and search queries
fbib 10.1609/icwsm.v5i1.14126 "Fact-checking information from large language models"
```

From a file (`--file`), each line is treated the same way — one entry per line, or comma-separated on a single line:

```bash
fbib --file dois.txt
```

Duplicate inputs are automatically removed.

### Write to a file

Overwrite (default):

```bash
fbib --output refs.bib 10.1609/icwsm.v5i1.14126
```

Append to an existing `.bib` file:

```bash
fbib --append --output refs.bib 10.1093/jcmc/zmz022
```

### Specify number of free-text matches

Free-text searches return 1 result by default. Use `-n` to control the limit (1-100):

```bash
# Get 3 results (see the correct result in position #2)
fbib -n 3 "Fact-checking information from large language models can decrease"
```

## Configuration

Settings are stored in `~/.config/fetchbib/config.json` and persist across sessions.

### OpenAlex API Key

OpenAlex allows unauthenticated requests but with limited daily credits. For higher limits, get a free API key at [openalex.org](https://openalex.org/):

```bash
fbib --config-api-key YOUR_API_KEY
```

You can also use the `OPENALEX_API_KEY` environment variable, which takes precedence over the config file:

```bash
OPENALEX_API_KEY=your_key fbib "search query"
```

### Protect titles

BibTeX processors may change title capitalization. Enable title protection to wrap titles in double braces, preserving the original case:

```bash
fbib --config-protect-titles
```

This transforms the below:

- `title = {A {GPU} Study}` becomes `title = {{A GPU Study}}` and
- `title = {An Important Study}` becomes `title = {{An Important Study}}`.

Run again to toggle off.

### Exclude ISSN

Remove the ISSN field from returned BibTeX entries:

```bash
fbib --config-exclude-issn
```

Run again to toggle off.

### Exclude DOI

Remove the DOI field from returned BibTeX entries (the DOI is typically already included in the URL field):

```bash
fbib --config-exclude-doi
```

Run again to toggle off.

## Development

Clone the repo and sync dependencies with [uv](https://docs.astral.sh/uv/):

```bash
git clone https://github.com/mr-devs/fetchbib.git
cd fetchbib
uv tool install -e . # OR pip install -e .
```

> The `-e` flag (`uv tool install -e .`), it performs an editable installation.
> This means any changes you make to the local source code are immediately reflected when you run the command, without needing to reinstall.

Run unit tests:

```bash
uv run pytest
```

Run integration tests (hits live APIs):

```bash
uv run pytest -m integration
```