> ## Documentation Index
> Fetch the complete documentation index at: https://docs.law4devs.eu/llms.txt
> Use this file to discover all available pages before exploring further.

# Pagination

> Manual pagination and auto-pagination with iter() in the Law4Devs Python SDK.

## Overview

Every list endpoint returns a `Page[T]` object. You can either paginate manually using the `.links` and `.meta` fields, or let the SDK handle it automatically with `iter()`.

***

## The `Page[T]` Object

```python theme={null}
page = client.frameworks.list()

# The items on this page
page.data         # list[Framework]

# Metadata about the full result set
page.meta.total   # int — total items across all pages
page.meta.page    # int — current page number (1-indexed)
page.meta.per_page  # int — items per page
page.meta.pages   # int — total number of pages

# Navigation links (None if not applicable)
page.links.next   # str | None — URL of the next page
page.links.prev   # str | None — URL of the previous page
```

***

## Manual Pagination

Loop through pages yourself by checking `page.links.next`:

```python theme={null}
from law4devs import Law4DevsClient

client = Law4DevsClient()

page_num = 1
while True:
    page = client.frameworks.list(page=page_num, per_page=10)

    for fw in page.data:
        print(fw.name)

    if page.links.next is None:
        break
    page_num += 1

print(f"Done. Total frameworks: {page.meta.total}")
```

***

## Auto-Pagination with `iter()`

Every resource exposes an `iter()` method that fetches pages on demand and yields items one at a time. This is the recommended approach for processing complete result sets.

### Iterate all frameworks

```python theme={null}
for fw in client.frameworks.iter():
    print(fw.slug, fw.name)
```

### Iterate all articles in a framework

```python theme={null}
for article in client.articles.iter("gdpr"):
    print(f"Art. {article.article_number}: {article.title}")
```

### Iterate with a custom page size

Use `per_page` to control how many items are fetched per HTTP request. Larger values reduce the number of requests but use more memory per page.

```python theme={null}
# Fetch 100 articles per request instead of the default 20
for article in client.articles.iter("gdpr", per_page=100):
    print(article.article_number)
```

***

## Collecting Results into a List

```python theme={null}
# Collect all requirements for a framework into a list
all_requirements = list(client.requirements.iter(framework_slug="gdpr"))
print(f"Loaded {len(all_requirements)} requirements")
```

<Warning>
  For large frameworks, collecting everything into a list can use significant memory. Prefer streaming with a `for` loop when you don't need random access.
</Warning>

***

## The `per_page` Parameter

All `list()` and `iter()` methods accept a `per_page` parameter:

* Minimum: `1`
* Maximum: `100`
* Default: `20`

```python theme={null}
# Smallest possible pages (useful for sampling)
page = client.articles.list("gdpr", per_page=1)
print(f"GDPR has {page.meta.total} articles total")

# Largest pages (fewer HTTP requests)
for article in client.articles.iter("cra", per_page=100):
    process(article)
```

***

## Checking Total Count Without Fetching All Items

Request a single item to read `meta.total` without loading the full data set:

```python theme={null}
page = client.requirements.list(framework_slug="nis2", per_page=1)
print(f"NIS2 has {page.meta.total} requirements")
```

***

## Detailed Examples

### Process all frameworks with progress reporting

```python theme={null}
frameworks = list(client.frameworks.iter())
total = len(frameworks)

for i, fw in enumerate(frameworks, 1):
    print(f"[{i}/{total}] Processing {fw.slug}...")
    articles = list(client.articles.iter(fw.slug))
    print(f"  {len(articles)} articles")
```

### Collect all requirements across all frameworks

```python theme={null}
all_requirements = []

for fw in client.frameworks.iter():
    for req in client.requirements.iter(framework_slug=fw.slug):
        all_requirements.append(req)

print(f"Total requirements across all frameworks: {len(all_requirements)}")
```

### Paginate with an offset (skip first N items)

```python theme={null}
# Skip the first 40 items (pages 1–2 at per_page=20) and start from page 3
page = client.articles.list("gdpr", page=3, per_page=20)
for article in page.data:
    print(article.article_number)
```

### Stop iteration early

Because `iter()` yields lazily, you can stop at any point without fetching the remaining pages:

```python theme={null}
import itertools

# Only process the first 50 articles, regardless of total count
for article in itertools.islice(client.articles.iter("gdpr"), 50):
    print(article.title)
```

<Tip>
  `iter()` is lazy — it only fetches the next page when the current page's items are exhausted. If you break out of the loop early, no unnecessary HTTP requests are made.
</Tip>
