Development setup
Clone and install
Use Python 3.11–3.14 and uv. Python 3.12 is
the primary CI environment; some optional model-serving runtimes have narrower
Python and platform support. Install libmagic on Linux/macOS if your system
does not already provide it (see Installation).
git clone https://github.com/scienceverse/bibr.git
cd bibr
uv sync --locked --extra all --all-groups
--extra all selects the cloud + ML superset (batch, cache, demo,
mcp, torch). The hardware-specific serving extras (local, vllm,
local-mlx, gpu) are opt-in; --all-extras also resolves if you want
every one, subject to their platform markers. local is an Apple Silicon
serving extra; it does not install a universal in-process OCR engine.
For core code or documentation work without local ML models:
Tests set placeholder configuration in tests/conftest.py and mock external
services. API keys and model downloads are needed only for the live workflows
you choose to run. Use uv run bibr setup to configure one of those workflows.
Running tests
This selects the main CI suite. Core-only CI also runs the non-slow suite with
uv run --locked pytest -m "not slow"; tests that need absent optional
dependencies should use pytest.importorskip(). Slow tests are excluded by
the -m expression, not by pytest's default configuration. Read a slow test's
requirements before enabling it: it may need model downloads, an OCR service,
GPU hardware, or LLM credentials.
Linting and formatting
bibr uses Ruff for both. Line length is 100 characters, double quotes, Python 3.11+ target.
Previewing the docs
Some reference pages (reference/settings.md, reference/cli.md,
reference/schema.md) are generated at build time from scripts/docs_ref_core.py
reading live code and docstrings — don't edit the built output directly. To
change what those pages say, edit scripts/docs_ref_core.py or the
docstrings/field descriptions it reads from. The docs build also validates
internal links; add pages to mkdocs.yml when they should appear in navigation.
For the documentation contracts and CLI examples:
Conventions
- Line length 100, double quotes,
py311+ target (seepyproject.tomlfor the full Ruff rule set) - Lazy
__getattr__imports in__init__.pyfor subpackages with heavy dependencies (transformers, torch, etc.), soimport bibrstays light - Exceptions derive from
BibrError; use the appropriate input, processing, upstream-service, or configuration error inbibr/exceptions.py Settingsinbibr/config.pylazily exposesGlobalSettings; settings can also be passed explicitly to pipeline instances. Read environment variables and.envthrough this configuration layer
Publishing a release
The release workflow builds the wheel and source archive once, checks their
contents and PyPI metadata, and installs the wheel in a clean environment. It
publishes those same files through PyPI Trusted Publishing with attestations.
The package description comes from pyproject.toml; the PyPI project page
comes from README.md. Update both before releasing, including installation
instructions and links that work outside GitHub.
The registered PyPI publisher must match these values:
| Setting | Value |
|---|---|
| PyPI project | bibr |
| GitHub owner/repository | scienceverse/bibr |
| Workflow filename | release.yml |
| GitHub environment | pypi |
The pypi environment allows v* tags. No PyPI API token is needed. Keep the
repository variable PUBLISH_PYPI=true for normal publishing. A maintainer's
version tag starts the release workflow, which publishes only after its tests
and distribution checks pass. Enable this once during publishing setup:
Leave publishing enabled after a successful release. Set the variable to false
only when deliberately suspending PyPI delivery; tags created while it is
disabled skip the PyPI upload. Manual release rehearsals never publish.
Container registry delivery is a separate opt-in: PUBLISH_GHCR=true enables
edge and release uploads, including manual container workflow runs. It is
disabled for the initial public 0.5.0 launch; users can build the containers
from the public source. CI still builds the serve image and blocks fixable
HIGH/CRITICAL vulnerabilities before CI / required passes.
Before enabling GHCR, configure a clean package with the intended visibility and repository Actions access, then verify anonymous pulls for public images. Do not expose a legacy private package's old versions as part of that setup. See Docker deployment.
- Update the package version, lockfile, changelog, and public documentation on
main. Wait forCI / requiredto pass on the exact commit to be released. - Rehearse the release from
mainwithgh workflow run release.yml --repo scienceverse/bibr --ref main. Wait for the Ubuntu, macOS, Windows, and distribution checks to pass. A manual rehearsal cannot publish to PyPI, GHCR, or GitHub Releases. - After release approval, create and push an annotated
vX.Y.Ztag on the verified commit, withX.Y.Zmatchingproject.version. The workflow rejects mismatched tags and commits that are not reachable frommain. - Watch the tag-triggered Release workflow to completion. PyPI receives the verified distributions and GitHub Release assets are attached after each enabled delivery channel succeeds. If GHCR is enabled, the release container must also pass its digest scan before its version tags are promoted. A failed enabled channel blocks finalization; only deliberately disabled channels may be skipped.
- Verify the live PyPI description and install that exact version from PyPI in a fresh environment.
If publication partially succeeds, rerun only the failed jobs of that same run. Do not rerun a successful PyPI upload or move a published release tag. PyPI files are immutable; package or description corrections require a new version.
Submitting a pull request
- Branch from
main, keep PRs focused on a single concern, and use descriptive branch names withoutcodex/orclaude/prefixes - Add tests for new functionality
- CI must be green, including the strict docs build (
mkdocs build --strict) - Update user-facing docs when CLI options, defaults, input formats, output fields, or deployment behavior change
- A CLA is required before your first PR can be merged — see CONTRIBUTING.md for details