Metadata-Version: 2.4
Name: nu-private-api
Version: 0.2.0
Summary: Read-only Python client for discovering and parsing public NU.nl articles.
Author: 11philip22
License-Expression: MIT
Project-URL: Repository, https://github.com/11philip22/nu-private-api
Keywords: nu.nl,news,api,client
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.10
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: httpx>=0.28
Dynamic: license-file

<div align="center">

# nu-private-api

Read-only Python client for discovering and parsing public NU.nl articles.

[![PyPI](https://img.shields.io/pypi/v/nu-private-api?style=flat-square&logo=pypi&logoColor=white)](https://pypi.org/project/nu-private-api/)
![Python](https://img.shields.io/badge/Python-%3E%3D3.10-3776ab?style=flat-square&logo=python&logoColor=white)
![License](https://img.shields.io/pypi/l/nu-private-api?style=flat-square)
[![Downloads](https://img.shields.io/pypi/dm/nu-private-api?style=flat-square)](https://pypi.org/project/nu-private-api/)

[Overview](#overview) | [Install](#install) | [Quick Start](#quick-start) | [API](#api) | [Development](#development)

</div>

## Overview

`nu-private-api` wraps the public NU.nl web GraphQL endpoint used by the site
itself. It is intentionally small: give it a section or article URL, get back
article URLs or a parsed article object.

Use it for scripts, experiments, and lightweight content extraction where a
full browser is unnecessary.

> [!WARNING]
> This is an unofficial client for NU.nl web endpoints. It may break when
> NU.nl changes its private response shape.

## Features

- Fetch de-duplicated article URLs from public NU.nl section/list pages.
- Fetch and parse public article pages.
- Return normalized article fields: URL, title, description, publish time,
  modified time, author, and body text.
- Use built-in `SectionUrl` values or pass raw NU.nl URLs.
- Bring your own configured `httpx.Client` when you need custom timeouts,
  proxies, headers, or lifecycle control.

## Install

```powershell
python -m pip install nu-private-api
```

## Quick Start

```python
from nu_private_api import NuClient, SectionUrl

client = NuClient()

urls = client.section_by_url(SectionUrl.BINNENLAND)
article = client.article_by_url(urls[0])

print(article.title)
print(article.author)
print(article.body)
```

Raw URLs work too:

```python
urls = client.section_by_url("https://www.nu.nl/binnenland")
article = client.article_by_url("https://www.nu.nl/123456/example.html")
```

Use your own `httpx.Client` if you want to control connection settings:

```python
import httpx

from nu_private_api import NuClient

with httpx.Client(timeout=10) as http:
    client = NuClient(client=http)
    article = client.article_by_url("https://www.nu.nl/123456/example.html")
```

## API

### `NuClient.section_by_url(url)`

Fetches a NU.nl section/list page and returns de-duplicated absolute article
URLs.

```python
from nu_private_api import NuClient, SectionUrl

client = NuClient()
urls = client.section_by_url(SectionUrl.ECONOMIE)
```

`url` can be a `SectionUrl` enum value or a string URL.

### `NuClient.article_by_url(url)`

Fetches and parses a public article URL.

```python
article = client.article_by_url(urls[0])
```

Returns an immutable `Article` dataclass:

```python
Article(
    url="...",
    title="...",
    description="...",
    published_at="...",
    modified_at="...",
    author="...",
    body="...",
)
```

## Notes

- Public article reads do not require cookies or login.
- Video pages and live blogs are not supported.
- The current parser follows the observed NU.nl article shape:
  base64 JSON-LD schema, `screenMetadata`, and article text blocks.
- API research notes live in [`docs/apis`](docs/apis/).
