0%

Talking to an API · practice

Validate the Items Page

Successful JSON decoding proves syntax, not meaning. Add validate_items_page(document) and reject data outside the reviewed page contract with .

The top-level has exactly these keys:

items, page, page_size, total, has_next, next_page

items is a . Every item is a with exactly id, name, category, and value. IDs and values are integers; bool must not pass as an integer. Names and categories are non-empty text. Page is an integer from 1 through 10, page size is an integer from 1 through 3, and total is a non-negative integer.

The pagination fields must describe one possible of the dataset. The slice starts at (page - 1) * page_size. A successful non-empty dataset page starts before total, and the item count equals the smaller of page_size and the number of items remaining. has_next is exactly whether more items remain after this page. When it is true, next_page is page + 1; otherwise next_page is None. For an empty dataset, page 1 contains no items and has no next page.

Do not rebuild or sort the document. Return the same validated object so unseen values, order, duplicates, and integer survive.

Then implement the one-page composition:

def fetch_items_page(page, page_size, *, timeout=DEFAULT_TIMEOUT, session=None):
    document = request_json(
        "/items",
        params={"page": page, "page_size": page_size},
        timeout=timeout,
        session=session,
    )
    return validate_items_page(document)

The API itself accepts page values 1 through 10 and page sizes 1 through 3; an out-of- slice of a non-empty dataset is a 400. The will reject locally invalid page and page-size values before HTTP, while the schema validator checks the actual response shape.

Feed your validator some deliberately wrong documents before you move on. Put true where an integer belongs, add a key that should not be there, remove one that should, and claim has_next is true while next_page is None. Each of those should raise, and the message should say which rule was broken.

Why use type(value) is int instead of isinstance(value, int) here?

Task

Implement validate_items_page with the exact top-level and item keys, -safe integer and boolean checks, non-empty text, bounded page and page size, non-negative total, an item count consistent with the requested , and exact has_next/next_page fields. Return the same . Implement fetch_items_page as one /items request with exact page , forwarded timeout/session, then validation.