Metadata-Version: 2.4
Name: pyfeuxdeforet-fr
Version: 0.2.0
Summary: Async Python client for the feuxdeforet.fr unofficial API
Author-email: Julien <jul-fls@users.noreply.github.com>
License-Expression: Apache-2.0
Project-URL: Homepage, https://github.com/jul-fls/pyfeuxdeforet-fr
Project-URL: Issues, https://github.com/jul-fls/pyfeuxdeforet-fr/issues
Project-URL: Repository, https://github.com/jul-fls/pyfeuxdeforet-fr
Classifier: Development Status :: 3 - Alpha
Classifier: Framework :: AsyncIO
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Typing :: Typed
Requires-Python: >=3.12
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: aiohttp>=3.9
Dynamic: license-file

# pyfeuxdeforet-fr

[![CI](https://github.com/jul-fls/pyfeuxdeforet-fr/actions/workflows/ci.yml/badge.svg)](https://github.com/jul-fls/pyfeuxdeforet-fr/actions/workflows/ci.yml)
[![PyPI](https://img.shields.io/pypi/v/pyfeuxdeforet-fr.svg)](https://pypi.org/project/pyfeuxdeforet-fr/)

`pyfeuxdeforet-fr` is an unofficial async Python client for JSON data exposed by [feuxdeforet.fr](https://feuxdeforet.fr).

The package is intentionally small and close to the site payloads. It is meant to provide reusable transport and typed convenience models for future projects, including a possible Home Assistant / HACS integration, without baking Home Assistant entity decisions into the library.

## Features

- Async API client built for `aiohttp`.
- Fetch French regions and departments from `/api/regions`.
- Fetch national counters and vigilance/risk totals from `/api/stats`.
- Fetch homepage news summaries from `/api/home`.
- Fetch raw cartography GeoJSON from `/fdf/cartographie/geojson`.
- Bootstraps the cartography proxy from `/cartes/feux/`, including its dynamic nonce and cookies.
- Raw payload helpers are available for integrations that need fields not yet modeled.
- Typed package (`py.typed`) for downstream users.

## Installation

```bash
pip install pyfeuxdeforet-fr
```

## Quick start

```python
import asyncio

from aiohttp import ClientSession
from pyfeuxdeforet_fr import FeuxDeForetClient


async def main() -> None:
    async with ClientSession() as session:
        client = FeuxDeForetClient(session=session)

        regions = await client.get_regions()
        stats = await client.get_stats()
        home = await client.get_home()
        geojson = await client.get_geojson(
            last_update="2026-07-05T00:11:12+02:00",
        )

        print(f"Regions: {len(regions or [])}")
        print(f"Stats: {stats}")
        print(f"Latest article: {home.articles[0].title if home and home.articles else None}")
        print(f"GeoJSON type: {geojson.get('type') if geojson else None}")


asyncio.run(main())
```

## API overview

### `FeuxDeForetClient(session, base_url="https://feuxdeforet.fr")`

Create a client using an injected `aiohttp.ClientSession`.

The caller owns the session lifecycle. This keeps the library suitable for applications that already manage connection pooling, such as Home Assistant.

### `get_regions()` / `get_regions_payload()`

Return normalized `Region` objects, or the raw `/api/regions` payload.

Each `Region` contains `Department` entries from the source `depts` field.

### `get_stats()` / `get_stats_payload()`

Return normalized `Stats`, or the raw `/api/stats` payload.

Known fields include published fire counts over several periods and aggregated risk-zone counters.

### `get_home()` / `get_home_payload()`

Return normalized homepage article summaries, or the raw `/api/home` payload.

The raw payload is also kept on `HomeData.raw` because the homepage response may grow with sections that are not yet modeled.

### `get_geojson(scope="web", last_update=None, nonce=None, headers=None)`

Return the raw cartography GeoJSON payload.

By default, each call first loads `/cartes/feux/`, extracts
`window.fdfBridge.proxyNonce`, retains any response cookies, then reproduces the
frontend proxy request with:

```http
X-FDF-Nonce: <dynamic proxyNonce>
Referer: https://feuxdeforet.fr/cartes/feux/
```

`last_update` accepts either a `datetime` or an already formatted string. A
manual nonce and extra headers remain available for diagnostics. The legacy
`nonce="0"` value now enables automatic discovery instead of sending zero.

## Known limitations

- This is an unofficial client and is not affiliated with feuxdeforet.fr.
- The API is not publicly documented and may change without notice.
- The HTML bootstrap format is private frontend behavior and may change without notice.
- Most endpoints are intentionally exposed through raw helpers as well as typed models.

## Development

For contributors:

```bash
python -m pip install -r requirements_dev.txt
pytest -q --cov
mypy pyfeuxdeforet_fr
python -m build
```

## Demo script

Run the full feature demo with:

```bash
python examples/demo.py
```

It exercises raw payload helpers, normalized models, and the GeoJSON endpoint. The GeoJSON call accepts overrides while reverse engineering continues:

```bash
python examples/demo.py --last-update "2026-07-05T00:11:12+02:00"
```

## License

Apache-2.0
