Skip to main content

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 httpx and asyncio for 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 ResponseUnwrapper can be adapted to all response structures.
  • Optional in-memory TTL caching for GET requests to reduce latency and API load.
  • Handles 429 errors by respecting Retry-After headers.
  • 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 the BaseApiClient how to navigate different API response "envelopes" (e.g., finding results in response['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.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

bibliofabric-0.5.0.tar.gz (98.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

bibliofabric-0.5.0-py3-none-any.whl (33.3 kB view details)

Uploaded Python 3

File details

Details for the file bibliofabric-0.5.0.tar.gz.

File metadata

  • Download URL: bibliofabric-0.5.0.tar.gz
  • Upload date:
  • Size: 98.7 kB
  • Tags: Source
  • Uploaded using 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}

File hashes

Hashes for bibliofabric-0.5.0.tar.gz
Algorithm Hash digest
SHA256 3183a0c816ff2681fed22b2cf7742fd7956afdb956d603401ad61a8c90c467c2
MD5 aa20e0f0056efd4358321d1d27513d94
BLAKE2b-256 3373fe4671fd03070cec648a9f3c07027bccb42cfb2471774e0fef9569f0875d

See more details on using hashes here.

File details

Details for the file bibliofabric-0.5.0-py3-none-any.whl.

File metadata

  • Download URL: bibliofabric-0.5.0-py3-none-any.whl
  • Upload date:
  • Size: 33.3 kB
  • Tags: Python 3
  • Uploaded using 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}

File hashes

Hashes for bibliofabric-0.5.0-py3-none-any.whl
Algorithm Hash digest
SHA256 744a105af3aa3ee8f8186169011e1445b594f41c6884e08e8a03a7f83ef3af23
MD5 eb6b1ce2074e767d9a186b9f2eb798d5
BLAKE2b-256 0ffe1b75175b4e305ddc04e0fff0ed42b7fbad33c60ae6ce9e049e4bca0ec1d2

See more details on using hashes here.

Release history Release notifications | RSS feed

0.5.2

2 files

0.5.1

2 files

This release

0.5.0 This release

2 files

0.4.3

2 files

0.4.2

2 files

0.4.1

2 files

0.4.0

2 files

0.3.1

2 files

0.3.0

2 files

0.2.1

2 files

0.2.0

2 files

0.1.0

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page