> ## 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.

# Requirements

> Query parsed compliance requirements from EU frameworks using the Law4Devs Python SDK.

## Overview

Requirements are machine-readable compliance obligations extracted from framework articles. Each requirement is tied to a specific article (and optionally a paragraph), carries a type classification, and lists the stakeholder roles it applies to.

***

## Methods

### `list()`

Returns a page of requirements. Without filters, this returns requirements across all frameworks.

```python theme={null}
# All requirements (all frameworks)
page = client.requirements.list()
print(f"Total requirements: {page.meta.total}")

# Filter to a single framework
page = client.requirements.list(framework_slug="gdpr")
for req in page.data:
    print(f"[{req.requirement_type}] Art. {req.article_number}: {req.requirement_text[:60]}...")
```

**Parameters**

| Parameter        | Type  | Default | Description            |
| ---------------- | ----- | ------- | ---------------------- |
| `framework_slug` | `str` | `None`  | Filter by framework    |
| `page`           | `int` | `1`     | Page number            |
| `per_page`       | `int` | `20`    | Items per page (1–100) |

**Returns** `Page[Requirement]`

***

### `iter()`

Iterate over all requirements, optionally filtered by framework.

```python theme={null}
for req in client.requirements.iter(framework_slug="cra"):
    print(req.requirement_text)
```

**Parameters** — same kwargs as `list()` (except `page`).

**Returns** `Iterator[Requirement]`

***

## Model

### `Requirement`

| Field                    | Type          | Description                                                                           |
| ------------------------ | ------------- | ------------------------------------------------------------------------------------- |
| `id`                     | `int`         | Internal numeric ID                                                                   |
| `framework_slug`         | `str`         | Parent framework slug                                                                 |
| `article_number`         | `int`         | Source article number                                                                 |
| `paragraph_ref`          | `str \| None` | Paragraph label, e.g. `"1"`, `"2a"`                                                   |
| `paragraph_content`      | `str \| None` | Full text of the source paragraph                                                     |
| `requirement_text`       | `str`         | Extracted obligation text                                                             |
| `requirement_type`       | `str`         | Classification: `"obligation"`, `"prohibition"`, `"permission"`, `"definition"`, etc. |
| `compliance_deadline`    | `str \| None` | ISO 8601 date if a deadline is specified                                              |
| `linked_article_numbers` | `list[int]`   | Related articles within the same framework                                            |
| `stakeholder_roles`      | `list[str]`   | Roles this applies to, e.g. `["controller", "processor"]`                             |
| `tags`                   | `list[str]`   | Tag slugs                                                                             |
| `created_at`             | `str`         | ISO 8601 creation timestamp                                                           |

***

## Examples

### Build a compliance checklist

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

client = Law4DevsClient()

print("GDPR Compliance Checklist")
print("=" * 60)

obligations = [
    req for req in client.requirements.iter(framework_slug="gdpr")
    if req.requirement_type == "obligation"
]

for i, req in enumerate(obligations, 1):
    roles = ", ".join(req.stakeholder_roles) or "all parties"
    print(f"\n[{i}] Art. {req.article_number} — {roles}")
    print(f"    {req.requirement_text}")
    if req.compliance_deadline:
        print(f"    Deadline: {req.compliance_deadline}")
```

### Filter requirements for a specific role

```python theme={null}
controller_reqs = [
    req for req in client.requirements.iter(framework_slug="gdpr")
    if "controller" in req.stakeholder_roles
]

print(f"GDPR has {len(controller_reqs)} requirements for data controllers")
```

### Find requirements with deadlines

```python theme={null}
with_deadlines = [
    req for req in client.requirements.iter()
    if req.compliance_deadline is not None
]

for req in sorted(with_deadlines, key=lambda r: r.compliance_deadline):
    print(f"{req.compliance_deadline}  [{req.framework_slug}] Art. {req.article_number}")
```

### Group requirements by type

```python theme={null}
from collections import defaultdict

by_type = defaultdict(list)

for req in client.requirements.iter(framework_slug="nis2"):
    by_type[req.requirement_type].append(req)

for req_type, reqs in sorted(by_type.items()):
    print(f"{req_type}: {len(reqs)} requirements")
```

### Export requirements to a CSV

```python theme={null}
import csv

with open("gdpr_requirements.csv", "w", newline="") as f:
    writer = csv.DictWriter(f, fieldnames=[
        "article_number", "paragraph_ref", "requirement_type",
        "stakeholder_roles", "requirement_text",
    ])
    writer.writeheader()

    for req in client.requirements.iter(framework_slug="gdpr"):
        writer.writerow({
            "article_number": req.article_number,
            "paragraph_ref": req.paragraph_ref or "",
            "requirement_type": req.requirement_type,
            "stakeholder_roles": "; ".join(req.stakeholder_roles),
            "requirement_text": req.requirement_text,
        })

print("Exported to gdpr_requirements.csv")
```

<Tip>
  The `requirement_type` field makes it easy to separate hard obligations from definitions and permissions. Filter on `"obligation"` or `"prohibition"` when building audit checklists.
</Tip>

<Note>
  `linked_article_numbers` contains article numbers within the same framework, not cross-framework references.
</Note>
