bibliofabric: a foundation for modern scholarly API clients
Samuel Mok // s.mok@utwente.nl // 2025
bibliofabric is a foundational, asynchronous Python framework for building modern, resilient, and maintainable clients for scholarly APIs. It is the generic engine designed to create a future toolkit of clients for services like OpenAIRE, Crossref, OpenAlex, and more.
Key Features
- Built on
httpxandasynciofor high-performance, non-blocking I/O. - Automatic retries for transient network errors and 5xx/429 status codes with configurable exponential backoff.
- Supports various authentication schemes.
- The
ResponseUnwrappercan be adapted to all response structures. - Optional in-memory TTL caching for GET requests to reduce latency and API load.
- Handles
429errors by respectingRetry-Afterheaders. - Inject custom logic before a request is sent or after a response is received with a hook system.
Who is this for?
bibliofabric is a framework for developers building API clients. It is not an end-user library. You would use bibliofabric to create a library like AIREloom, which can then be used by researchers, librarians, data scientists, ....
How to Build a Client with bibliofabric (Conceptual Example)
Here’s a simplified example of how you would build a client for a hypothetical "SimpleAPI".
The developer only needs to define the API-specific parts; the underlying boilerplay & logic is handled by bibliofabric.
# simpleapi_client/client.py
from bibliofabric.client import BaseApiClient
from bibliofabric.config import BaseApiSettings
from bibliofabric.models import ResponseUnwrapper
from bibliofabric.resources import GettableMixin, BaseResourceClient
from pydantic import BaseModel
# 1. Define the API's data model
class SimpleWork(BaseModel):
id: str
title: str
# 2. Implement the ResponseUnwrapper for this specific API
class SimpleApiUnwrapper(ResponseUnwrapper[dict]):
def unwrap_results(self, response_json: dict) -> list[dict]:
return response_json.get("data", [])
def unwrap_single_item(self, response_json: dict) -> dict:
return response_json.get("item", {})
# ... implement other protocol methods ...
# 3. Define the Resource Client using BiblioFabric's mixins
class WorksClient(GettableMixin, BaseResourceClient):
_entity_path: str = "works"
_entity_model: type[SimpleWork] = SimpleWork
# 4. Create the main client class
class SimpleApiClient(BaseApiClient):
def __init__(self, settings: BaseApiSettings | None = None, auth_strategy=None):
# Instantiate the unwrapper and pass it to the base client
unwrapper = SimpleApiUnwrapper()
super().__init__(
base_url="https://api.simple.org/v1",
settings=settings,
auth_strategy=auth_strategy,
response_unwrapper=unwrapper
)
# Attach the specific resource client
self.works = WorksClient(api_client=self)
# 5. The end-user can now use your new client
async def main():
async with SimpleApiClient() as client:
work = await client.works.get("123")
print(work.title)
Core Architectural Concepts
bibliofabric is built on a few key, decoupled concepts:
- The heart of the framework is formed by the
BaseApiClient. A robust,httpx-based asynchronous client that manages the entire request/response lifecycle, including retries, caching, rate limiting, and a hook system. - A pluggable system for authentication using
AuthStrategy. Implementations for No-Auth, Static Bearer Token, and OAuth2 Client Credentials are provided out of the box, and adding new strategies (e.g., for Crossref's "polite pool") is straightforward. ResponseUnwrapper: The key to flexibility. This protocol allows specific clients to teach theBaseApiClienthow to navigate different API response "envelopes" (e.g., finding results inresponse['results']vs.response['message']['items']).- A set of pre-built mixins (
GettableMixin,SearchableMixin,CursorIterableMixin) that provide the boilerplate logic for common REST operations (.get(),.search(),.iterate()), making specific client implementations incredibly lean and declarative.
Contributing
Contributions are welcome! This project adheres to standard open-source practices. Please see our development guidelines for information on setting up your environment, coding conventions, and testing.
License
This project is licensed under the MIT License.
Metadata
Release files for bibliofabric 0.5.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| bibliofabric-0.5.2.tar.gz | 101.5 kB | Without provenance | Details for bibliofabric-0.5.2.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| bibliofabric-0.5.2-py3-none-any.whl | Python 3 | none | any | Details for bibliofabric-0.5.2-py3-none-any.whl |
Total release size: 136.5 kB
Release files / bibliofabric-0.5.2.tar.gz
| Download URL | bibliofabric-0.5.2.tar.gz |
|---|---|
| Size | 101.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
eafd8fb88a0b882359bfd43bef854fb7431090610a5a55dd3e2c5f1d561e3922
|
|
BLAKE2b-256 checksum How to use checksums |
a34cad8a9698d989ace7113944f2107e3ececec610c3f4e3a01ce83a6702df1e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.12.10 {"installer":{"name":"uv","version":"0.12.10","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / bibliofabric-0.5.2-py3-none-any.whl
| Download URL | bibliofabric-0.5.2-py3-none-any.whl |
|---|---|
| Size | 35.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
ff3e165cd550e6b4d500803d3ce84e8b2d6335a861eab40ca918a24d6d6d3f46
|
|
BLAKE2b-256 checksum How to use checksums |
26a3fe5a3280d13208735f26cd2f95bf24c077a3a6bf774fd3e54a534ef3143c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.12.10 {"installer":{"name":"uv","version":"0.12.10","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Security for bibliofabric 0.5.2
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.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.