CountAdapter
Base class for pluggable count extraction strategies in ApiBackend.
Overview
Responsible for answering one question: how many records are there in total? This is separate from pagination (which answers “how do I get the next page?” — see :class:~clearskies.backends.adapters.PaginationAdapter).
Different APIs communicate counts in completely different ways — some use response headers, some embed counts in the response body, and some don’t provide counts at all. Subclass CountAdapter and override extract_count to handle your API’s counting style.
clearskies ships with one concrete implementation:
- :class:
~clearskies.backends.adapters.HeaderCountAdapter— readsX-Total-Count,X-Total, andX-Total-Pagesresponse headers (the default forApiBackend)
Implementing a custom adapter
import clearskies
class BodyCountAdapter(clearskies.backends.adapters.CountAdapter):
def extract_count(self, response_data, response_headers, query=None):
if isinstance(response_data, dict):
total = response_data.get("meta", {}).get("total")
if total is not None:
return (int(total), None)
return (None, None)
Attach it to an ApiBackend:
backend = clearskies.backends.ApiBackend(
base_url="https://api.example.com",
count_adapter=BodyCountAdapter(),
)
Using a callable
For simple cases a plain callable may be supplied instead of a full subclass. The callable receives (response_headers, response_data) and should return a tuple of (total_count, total_pages) where either value can be None:
backend = clearskies.backends.ApiBackend(
base_url="https://api.example.com",
count_adapter=lambda headers, data: (
int(headers["X-My-Total"]) if headers and "X-My-Total" in headers else None,
None,
),
)