Shared library for biomedical literature tools — LLM abstraction, quality assessment, transparency analysis, and database utilities
Project description
bmlib
Shared Python library for biomedical literature tools — LLM abstraction, quality assessment, transparency analysis, full-text retrieval, publication ingestion, and database utilities.
Version: 0.4.0 | License: AGPL-3.0-or-later | Python: >=3.11
Installation
# Core (only jinja2 dependency)
pip install bmlib
# Editable install with all extras
uv pip install -e ".[all,dev]"
Optional dependency groups
| Group | Install command | Provides |
|---|---|---|
anthropic |
pip install bmlib[anthropic] |
Anthropic Claude LLM provider |
ollama |
pip install bmlib[ollama] |
Ollama local LLM provider |
openai |
pip install bmlib[openai] |
OpenAI, DeepSeek, Mistral, Gemini, and OpenAI-compatible providers |
postgresql |
pip install bmlib[postgresql] |
PostgreSQL database backend |
transparency |
pip install bmlib[transparency] |
Transparency analysis (httpx) |
publications |
pip install bmlib[publications] |
Publication ingestion and sync (httpx) |
pdf |
pip install bmlib[pdf] |
PDF → text conversion (pymupdf) |
dev |
pip install bmlib[dev] |
pytest, pytest-cov, ruff |
all |
pip install bmlib[all] |
Every runtime extra above (not dev) |
Modules
| Module | Description |
|---|---|
| bmlib.db | Thin database abstraction (SQLite + PostgreSQL) with pure functions over DB-API connections |
| bmlib.llm | Unified LLM client with pluggable providers (Anthropic, OpenAI, Ollama, DeepSeek, Mistral, Gemini) — chat, tool calling, embeddings, JSON repair, and text chunking |
| bmlib.templates | Jinja2-based prompt template engine with user-override directory fallback |
| bmlib.agents | Base agent class for LLM-driven tasks with template rendering and JSON parsing |
| bmlib.quality | 3-tier quality assessment pipeline for biomedical publications (metadata → LLM classifier → deep assessment), plus Cochrane risk-of-bias models and rule-based extractors |
| bmlib.transparency | Multi-API transparency and bias analysis (CrossRef, Europe PMC, OpenAlex, ClinicalTrials.gov) |
| bmlib.publications | Publication ingestion from PubMed, bioRxiv, medRxiv, and OpenAlex with deduplication and sync |
| bmlib.fulltext | Full-text retrieval (Europe PMC → Unpaywall → DOI), JATS XML parsing, PDF → text conversion, and disk-based caching |
Quick Start
Database
from bmlib.db import connect_sqlite, execute, fetch_all, transaction
conn = connect_sqlite("~/.myapp/data.db")
with transaction(conn):
execute(conn, "INSERT INTO papers (doi, title) VALUES (?, ?)", ("10.1101/x", "A paper"))
rows = fetch_all(conn, "SELECT * FROM papers")
LLM
from bmlib.llm import LLMClient, LLMMessage
client = LLMClient(default_provider="ollama")
response = client.chat(
messages=[LLMMessage(role="user", content="Summarise this paper.")],
model="ollama:medgemma4B_it_q8",
)
print(response.content)
Model strings use the format "provider:model_name":
"anthropic:claude-sonnet-4-20250514"
"openai:gpt-4o"
"ollama:medgemma4B_it_q8"
"deepseek:deepseek-chat"
"mistral:mistral-large-latest"
"gemini:gemini-2.0-flash"
Tool Calling
from bmlib.llm import LLMClient, LLMMessage, LLMToolDefinition
search = LLMToolDefinition(
name="search_pubmed",
description="Search PubMed for articles matching a query.",
parameters={
"type": "object",
"properties": {"query": {"type": "string"}},
"required": ["query"],
},
)
client = LLMClient()
response = client.chat(
messages=[LLMMessage(role="user", content="Find recent trials on statins.")],
model="anthropic:claude-sonnet-4-20250514",
tools=[search],
)
for call in response.tool_calls or []:
print(call.name, call.arguments) # arguments is already a parsed dict
To continue the conversation, append the assistant message (carrying
tool_calls) and one role="tool" message per call, each with the matching
tool_call_id, then send the whole list again.
Long Documents
from bmlib.llm import chunk_text, process_with_map_reduce
for chunk in chunk_text(paper_text, chunk_size=8000, overlap=200):
print(chunk.chunk_index, chunk.size)
summary = process_with_map_reduce(
paper_text,
map_fn=lambda part: summarise(part),
reduce_fn=lambda parts: summarise("\n".join(parts)),
)
Publication Sync
from datetime import date
from bmlib.db import connect_sqlite
from bmlib.publications import sync
conn = connect_sqlite("publications.db")
report = sync(
conn,
sources=["pubmed", "biorxiv"],
date_from=date(2025, 1, 1),
date_to=date(2025, 1, 7),
email="researcher@example.com",
)
print(f"Added: {report.records_added}, Merged: {report.records_merged}")
Full-Text Retrieval
from bmlib.fulltext import FullTextService
service = FullTextService(email="researcher@example.com")
# Passing identifier= enables the built-in disk cache (platform default dir).
result = service.fetch_fulltext(
pmc_id="PMC7614751", doi="10.1234/example", identifier="PMC7614751"
)
if result.html:
print(result.html[:200])
Quality Assessment
from bmlib.llm import LLMClient
from bmlib.quality import QualityManager
llm = LLMClient()
manager = QualityManager(
llm=llm,
classifier_model="anthropic:claude-3-haiku-20240307",
assessor_model="anthropic:claude-sonnet-4-20250514",
)
assessment = manager.assess(
title="A Randomized Controlled Trial of ...",
abstract="We conducted a double-blind RCT ...",
publication_types=["Randomized Controlled Trial"],
)
print(assessment.study_design, assessment.quality_tier)
Transparency Analysis
from bmlib.transparency import TransparencyAnalyzer
analyzer = TransparencyAnalyzer(email="researcher@example.com")
result = analyzer.analyze("doc-001", doi="10.1038/s41586-024-00001-0")
print(result.transparency_score, result.risk_level)
Development
# Install with dev dependencies
uv pip install -e ".[all,dev]"
# Run tests
uv run pytest tests/ -v
# Lint and format
uv run ruff check .
uv run ruff format --check .
Documentation
Full API documentation is available in docs/manual/.
License
AGPL-3.0-or-later
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file bmlib-0.4.0.tar.gz.
File metadata
- Download URL: bmlib-0.4.0.tar.gz
- Upload date:
- Size: 180.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
794b74ec33388f073b37186959db8cba3b18d05186d24d65eaeffe29d0f967b9
|
|
| MD5 |
8ecd3754113160a85508373bbaa0bf23
|
|
| BLAKE2b-256 |
fcc25c4ecd41a35f3df3f1c0f91aaf816b96acaaa0e3bb93667e9008c664c7de
|
Provenance
The following attestation bundles were made for bmlib-0.4.0.tar.gz:
Publisher:
release.yml on hherb/bmlib
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
bmlib-0.4.0.tar.gz -
Subject digest:
794b74ec33388f073b37186959db8cba3b18d05186d24d65eaeffe29d0f967b9 - Sigstore transparency entry: 2198047587
- Sigstore integration time:
-
Permalink:
hherb/bmlib@0de98bc0d9678d00f2301ce670be6011489ba805 -
Branch / Tag:
refs/tags/v0.4.0 - Owner: https://github.com/hherb
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@0de98bc0d9678d00f2301ce670be6011489ba805 -
Trigger Event:
release
-
Statement type:
File details
Details for the file bmlib-0.4.0-py3-none-any.whl.
File metadata
- Download URL: bmlib-0.4.0-py3-none-any.whl
- Upload date:
- Size: 161.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
95e89ee6126151c4c650dd1115d26f3c0b68c2fd3d008207a06b91427ba525e4
|
|
| MD5 |
88405a02eb0210b48d52dbacbd559d9f
|
|
| BLAKE2b-256 |
9da976cc6a79c7271a2ca1a704a59d9a47b22f740760448951e269ca754893b2
|
Provenance
The following attestation bundles were made for bmlib-0.4.0-py3-none-any.whl:
Publisher:
release.yml on hherb/bmlib
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
bmlib-0.4.0-py3-none-any.whl -
Subject digest:
95e89ee6126151c4c650dd1115d26f3c0b68c2fd3d008207a06b91427ba525e4 - Sigstore transparency entry: 2198047739
- Sigstore integration time:
-
Permalink:
hherb/bmlib@0de98bc0d9678d00f2301ce670be6011489ba805 -
Branch / Tag:
refs/tags/v0.4.0 - Owner: https://github.com/hherb
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@0de98bc0d9678d00f2301ce670be6011489ba805 -
Trigger Event:
release
-
Statement type: