BibSpire
A Python tool to update .bib file entries with INSPIRE-HEP citations while preserving reference keys.
Overview
BibSpire reads a .bib file, searches each entry on inspire-hep.net, and replaces the entries with the official INSPIRE citations while keeping the same reference keys. This ensures your bibliography has the most accurate and complete citation information from INSPIRE-HEP.
Features
- Automatic INSPIRE Search: Searches INSPIRE-HEP for each bibliography entry
- Key Preservation: Keeps original reference keys while updating content
- Multiple Search Strategies: Uses title, author, eprint, and DOI for matching
- Robust Parsing: Handles complex BibTeX formats with nested braces
- Error Handling: Gracefully handles missing entries and API errors
- Rate Limiting: Configurable delays between API requests
- Code Quality: Enforced with Ruff linting and formatting
- Comprehensive Testing: Full test suite with unit and integration tests
Installation
From PyPI (Recommended)
pip install bibspire
From Source (Development)
# Clone the repository
git clone https://github.com/lorenzennio/bibspire.git
cd bibspire
# Install the Pixi-managed development environment
pixi install
From Built Package
# Build and install
pixi run build-package
pip install dist/bibspire-1.0.0-py3-none-any.whl
Usage
Command Line Interface
# Basic usage - update file in place
bibspire input.bib
# Save to different file
bibspire input.bib -o output.bib
# Verbose output
bibspire input.bib -v
# Custom delay between API requests
bibspire input.bib -d 2.0
# Show help
bibspire --help
To keep a specific entry unchanged, add a bibspire_skip field to that entry:
@article{manual2026,
title = {Entry Managed Manually},
bibspire_skip = {true},
}
Run as Python Module
python -m bibspire input.bib -o output.bib -v
Programmatic Usage
from bibspire import BibSpire, BibParser
# Create BibSpire instance
bibspire = BibSpire(delay=1.0, verbose=True)
# Update a bibliography file
bibspire.update_bib_file("input.bib", "output.bib")
# Or work with entries directly
entries = BibParser.parse_bib_file("input.bib")
updated_entries = bibspire.update_entries(entries)
Testing
The project includes a comprehensive test suite:
# Run fast unit and integration tests
pixi run test
# Run all tests including slow real API tests
pixi run test-all
# Run only slow tests (real API calls)
pixi run test-slow
# Run tests with coverage
pixi run test-cov
Test Categories
- Unit Tests (
test_core.py,test_cli.py): Fast tests with mocked dependencies - Integration Tests (
test_integration.py): Tests with mocked HTTP responses - Slow Tests (
test_slow.py): Real API calls to INSPIRE-HEP (marked asslow)
Development
Building and Testing
# Use Makefile targets
make help # Show all available targets
make all # Install deps, install pre-commit, run checks, and build
make check # Run linting, formatting, and fast tests
make ci # Run full CI checks with coverage
make pre-commit-install # Install pre-commit hooks
make pre-commit-run # Run pre-commit on all files
make test # Run fast tests only
make test-cov # Run fast tests with coverage
make lint # Run linting
make format # Format code
# Manual commands
pixi install # Install the development environment
pixi run test-all # Run tests
pixi run test-cov-all # Run tests with coverage
pixi run lint # Run linting
pixi run format # Format code
pixi run build-package # Build package
Pre-commit Hooks
This project uses pre-commit hooks to ensure code quality. The hooks automatically run:
- Code linting and formatting with Ruff
- Trailing whitespace removal
- End-of-file fixes
- YAML and TOML validation
- Tests
To set up pre-commit hooks:
# Install and activate pre-commit hooks
pixi run pre-commit-install
# Run pre-commit on all files manually
pixi run pre-commit-run
Once installed, the hooks will run automatically on every commit. If any hook fails, the commit will be rejected until the issues are fixed.
Publishing
Manual Publishing
# Build and check package artifacts
pixi run build-package
pixi run check-package
# Upload to PyPI (requires account and authentication)
pixi run twine upload dist/*
Automatic Publishing
The package is automatically published to PyPI when a new version tag is pushed:
git tag v1.0.1
git push origin v1.0.1
This triggers the release workflow which:
- Builds the package
- Checks package integrity
- Publishes to PyPI
- Creates a GitHub release
Project Structure
bibspire/
├── .github/workflows/ # CI/CD workflows
├── src/bibspire/ # Main package
│ ├── __init__.py # Package exports
│ ├── __main__.py # Module entry point
│ ├── cli.py # Command-line interface
│ └── core.py # Core functionality
├── tests/ # Test suite
│ ├── conftest.py # Test fixtures
│ ├── test_core.py # Core functionality tests
│ ├── test_cli.py # CLI tests
│ ├── test_integration.py # Integration tests
│ └── test_slow.py # Slow API tests
├── pyproject.toml # Package and Pixi workspace configuration
├── pixi.lock # Locked development environment
├── Makefile # Development commands
└── README.md # This file
Example
Given an input .bib file:
@article{mykey2023,
title = {Observation of a new particle in the search for the Standard Model Higgs boson},
author = {Aad, G. and others},
year = {2012}
}
BibSpire will search INSPIRE, find the official record, and replace it with:
@article{mykey2023,
author = {Aad, Georges and others},
collaboration = {ATLAS},
title = {{Observation of a new particle in the search for the Standard Model Higgs boson with the ATLAS detector at the LHC}},
eprint = {1207.7214},
archivePrefix = {arXiv},
primaryClass = {hep-ex},
doi = {10.1016/j.physletb.2012.08.020},
journal = {Phys. Lett. B},
volume = {716},
pages = {1--29},
year = {2012}
}
Note how the reference key mykey2023 is preserved while all other fields are updated with official INSPIRE data.
Dependencies
- Python ≥ 3.8
- requests ≥ 2.25.0
Development Dependencies
- Pixi ≥ 0.55.0
- pytest ≥ 6.0.0
- pytest-mock ≥ 3.6.0
- responses ≥ 0.21.0
- ruff ≥ 0.1.0 (linting and formatting)
- build ≥ 0.8.0 (package building)
Contributing
- Fork the repository
- Create a feature branch
- Add tests for your changes
- Run the test suite:
pixi run test-all - Run linting:
pixi run lint - Format code:
pixi run format - Submit a pull request
Code Quality
This project uses Ruff for linting and code formatting. The configuration includes:
- Linting: Enforces Python best practices, code style, and catches common errors
- Formatting: Consistent code style with 88-character line length
- Import sorting: Automatic import organization and cleanup
- Type checking: Basic type hint validation
Run pixi run check to run all quality checks before submitting changes.
Continuous Integration
This project uses GitHub Actions for automated testing and quality assurance:
CI Workflow
- Linting: Ruff checks for code quality and style
- Multi-Python Testing: Pixi environments run tests on Python 3.8-3.12
- Coverage: Code coverage reporting with Codecov integration
- Integration Tests: Slow tests run on main branch and when labeled
- Package Building: Validates package can be built locally
Workflows
ci.yml: Main CI pipeline for PRs and pushesrelease.yml: Automated publishing on version tags
Quality Gates
All PRs must pass:
- Ruff linting (no violations)
- Code formatting check
- Test suite
- Package build validation
To trigger slow integration tests, add the run-slow-tests label to your PR.
License
MIT License - see LICENSE file for details.
Troubleshooting
Command Not Found
If bibspire command is not found:
# Use full path or activate virtual environment
/path/to/venv/bin/bibspire input.bib
# Or run as module
python -m bibspire input.bib
API Rate Limiting
If you encounter rate limiting:
# Increase delay between requests
bibspire input.bib -d 2.0
Test Failures
If tests fail:
# Check dependencies
pixi install
# Run specific test
pixi run pytest tests/test_core.py::TestBibEntry::test_init -v
Metadata
Release files for bibspire 1.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| bibspire-1.2.0.tar.gz | 56.0 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| bibspire-1.2.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 68.1 kB
Release files / bibspire-1.2.0.tar.gz
| Download URL | bibspire-1.2.0.tar.gz |
|---|---|
| Size | 56.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
cc0e9cfdb6e99e99ad6fe02f3f62235a5a131fdf59723feb2ca00fc2eaf1db9a
|
|
BLAKE2b-256 checksum How to use checksums |
24e7c8d9823500ca2bd8959783ac3da7f82ca6520e42dff4115ef622cd893219
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Release files / bibspire-1.2.0-py3-none-any.whl
| Download URL | bibspire-1.2.0-py3-none-any.whl |
|---|---|
| Size | 12.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
73ca95c7da1980b6f59dc0dd59647bbef2c70b463fc656dbf4cf1090abcf3680
|
|
BLAKE2b-256 checksum How to use checksums |
737507bdbc8a95b16b6cfb6185ebed011b0b67f876d44f4e845264a159eb163b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|