Python · API · Beginner

Pagination

5 tasks

Iterate through multi-page API responses to collect all results.

How pagination works

#
APIs rarely return thousands of records in a single response — that would be slow and wasteful. Instead, they split results into pages. The /api/products/ endpoint returns up to 20 items per page by default, but the catalog has 372 products in total. Every paginated response includes four top-level fields: ```python data = response.json() data['count'] # 372 — total items across ALL pages data['next'] # URL of the next page, or null if this is the last page data['previous'] # URL of the previous page, or null if this is the first data['results'] # list of items on this page ``` To navigate pages, you have two options: Option 1 — follow the next URL. The server builds the URL for you, so you never have to calculate page numbers: ```python url = f'{BASE_URL}/api/products/' while url: data = requests.get(url).json() for product in data['results']: print(product['name']) url = data['next'] # None when there are no more pages ``` Option 2 — calculate total pages and iterate with a counter: ```python PAGE_SIZE = 20 first = requests.get(f'{BASE_URL}/api/products/', params={'page_size': PAGE_SIZE}).json() total_pages = -(-first['count'] // PAGE_SIZE) # ceiling division for page in range(1, total_pages + 1): data = requests.get( f'{BASE_URL}/api/products/', params={'page': page, 'page_size': PAGE_SIZE}, ).json() # process data['results'] ``` Following next is simpler and more robust — it works even if the total count changes while you are paginating. The counter approach is useful when you need to know how many pages there are upfront, for example to show a progress indicator.

Pagination patterns

#
Collect all product names across the entire catalog: ```python import requests BASE_URL = 'https://apilearn.tukas.dev' all_names = [] url = f'{BASE_URL}/api/products/' while url: data = requests.get(url).json() for product in data['results']: all_names.append(product['name']) url = data['next'] print(f'Collected {len(all_names)} products') ``` Pagination works with filters — the next URL preserves all your parameters: ```python url = f'{BASE_URL}/api/products/' params = {'category': 'kitchen', 'ordering': 'price'} all_products = [] while url: data = requests.get(url, params=params).json() all_products.extend(data['results']) url = data['next'] params = {} # params are already encoded in the next URL print(f'Kitchen products: {len(all_products)}') ``` Note: once you start following next, clear params — the next URL already contains them. If you pass params again, some values may be duplicated in the URL. Find the most expensive product across all pages: ```python # More efficient: sort descending and take the first result data = requests.get( f'{BASE_URL}/api/products/', params={'ordering': '-price', 'page_size': 1}, ).json() most_expensive = data['results'][0] print(most_expensive['name'], most_expensive['price']) ``` When you need a single extreme value (max, min), let the server do the work with ordering and page_size=1. Fetching all pages just to find a maximum is wasteful. Fetching all pages just to find a maximum is wasteful.

Pagination reference

#
Paginated response fields: ``` count int Total items across all pages next str | null URL of the next page; null on the last page previous str | null URL of the previous page; null on the first page results list Items on the current page ``` Pagination parameters: ``` page int Page number (default: 1) page_size int Items per page (default: 20) ``` Total pages formula: ```python import math total_pages = math.ceil(count / page_size) # or without math: total_pages = -(-count // page_size) # ceiling division trick ``` Loop patterns: ```python # Follow next (recommended) url = f'{BASE_URL}/api/products/' while url: data = requests.get(url).json() # process data['results'] url = data['next'] # Page counter for page in range(1, total_pages + 1): data = requests.get(url, params={'page': page}).json() # process data['results'] ```
01

Fetch a specific page

#

Fetch page 3 of the product list with page_size=10. Print the name of each product on that page.

import requests

BASE_URL = 'https://apilearn.tukas.dev'

# Fetch page 3 and print product names
Solution
import requests

BASE_URL = 'https://apilearn.tukas.dev'

params = {'page': 3, 'page_size': 10}
response = requests.get(f'{BASE_URL}/api/products/', params=params)
for product in response.json()['results']:
    print(product['name'])
02

Calculate total pages

#

Fetch the product list with page_size=20. Calculate and print the total number of pages needed to see all products.

import requests

BASE_URL = 'https://apilearn.tukas.dev'

# Calculate total pages for page_size=20
Solution
import requests
import math

BASE_URL = 'https://apilearn.tukas.dev'

PAGE_SIZE = 20
data = requests.get(f'{BASE_URL}/api/products/', params={'page_size': PAGE_SIZE}).json()
total_pages = math.ceil(data['count'] / PAGE_SIZE)
print(f'{data["count"]} products across {total_pages} pages')
03

Collect all products from a category

#

Collect all products in the "kitchen" category into a list by following the next URL. Print the total number of products collected.

import requests

BASE_URL = 'https://apilearn.tukas.dev'

all_products = []
url = f'{BASE_URL}/api/products/'
params = {'category': 'kitchen'}

# Paginate through all kitchen products
Solution
import requests

BASE_URL = 'https://apilearn.tukas.dev'

all_products = []
url = f'{BASE_URL}/api/products/'
params = {'category': 'kitchen'}

while url:
    data = requests.get(url, params=params).json()
    all_products.extend(data['results'])
    url = data['next']
    params = {}

print(len(all_products))
04

Collect all product names

#

Collect the names of all products in the entire catalog (all pages) into a list. Print the total count and the name of the last product in the list.

import requests

BASE_URL = 'https://apilearn.tukas.dev'

# Collect all product names across all pages
Solution
import requests

BASE_URL = 'https://apilearn.tukas.dev'

all_names = []
url = f'{BASE_URL}/api/products/'

while url:
    data = requests.get(url).json()
    for product in data['results']:
        all_names.append(product['name'])
    url = data['next']

print(len(all_names))
print(all_names[-1])
05

Find the most expensive product

#

Find the most expensive product in the catalog without fetching all pages. Print its name and price.

import requests

BASE_URL = 'https://apilearn.tukas.dev'

# Find the most expensive product efficiently
Solution
import requests

BASE_URL = 'https://apilearn.tukas.dev'

params = {'ordering': '-price', 'page_size': 1}
data = requests.get(f'{BASE_URL}/api/products/', params=params).json()
product = data['results'][0]
print(product['name'])
print(product['price'])