Metadata-Version: 2.4
Name: datacycle
Version: 0.1.0
Summary: Python client for the dataCycle API v4
Author: dataCycle Client Developers
License-Expression: MIT
Keywords: datacycle,api,client
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: requests>=2.28
Requires-Dist: pydantic>=2.0
Provides-Extra: dev
Requires-Dist: pytest>=7.0; extra == "dev"
Requires-Dist: pytest-cov; extra == "dev"
Requires-Dist: ruff; extra == "dev"
Dynamic: license-file

# dataCycle Python Client

Pydantic-basierter Python-Client für die [dataCycle](https://datacycle.info/) API v4. Typsicher, mit vollständiger Abdeckung aller API-Bereiche: Klassifizierungen, Inhalte, GeoJSON/MVT, Webhooks, Externe Links und mehr.

## Quickstart

```bash
pip install -e .
# aus der Forgejo-Registry: pip install --index-url https://git.him-tools.de/api/packages/HIM-public/pypi/simple datacycle
```

```python
from datacycle import DataCycleClient

client = DataCycleClient("https://contenthub.kitzbueheler-alpen.com", token="abc123")

# Klassifizierungsbäume abrufen
schemes = client.classifications.get_schemes()
print(f"{schemes.meta.total} Bäume gefunden")

# Klassifizierungen durchsuchen
concepts = client.classifications.get_concepts(schemes.graph[0]["@id"],
    filter={"search": "Musik"})

# Inhalte aus einem Endpunkt (ID aus dem dataCycle Admin-UI)
for item in client.contents.iter("deine-endpoint-uuid", filter={"q": "Wandern"}):
    print(item["name"])

# Facettensuche
facets = client.classifications.get_facets("endpoint-uuid", "scheme-uuid")

# GeoJSON
fc = client.geodata.geojson_endpoint("endpoint-uuid")

# Context-Manager (schließt die Session automatisch)
with DataCycleClient("https://...", token="abc") as client:
    ...
```

## Architektur

Der Client ist in Sub-Clients organisiert, die über die Hauptklasse zugänglich sind:

| Sub-Client | Zugriff | Bereich |
|---|---|---|
| Classifications | `client.classifications` | Konzept-Schemata, Konzepte, Facetten, Externe Systeme |
| Contents | `client.contents` | Inhalte, Höhenprofile, Zeitserien, Autovervollständigung |
| Webhooks | `client.webhooks` | Inhalte erstellen/aktualisieren/löschen (JSON-LD) |
| External Links | `client.external_links` | Inhalte extern teilen |
| Endpoints | `client.endpoints` | Neue Datenendpunkte anlegen |
| Geodata | `client.geodata` | GeoJSON FeatureCollection, Mapbox Vector Tiles |

Jeder Sub-Client teilt dieselbe `requests.Session` (Connection-Pooling, Bearer-Auth).

## Kernfeatures

- **Paging-Iterator** – `iter()` lädt automatisch alle Seiten nach
- **Dict-basierte Filter** – alle Filtertypen der API-DSL unterstützt (`q`, `classifications`, `attribute`, `geo`, `schedule`, `linked`, `union`, …)
- **`include`/`fields`** – verknüpfte Inhalte auflösen, Attribute einschränken (String oder Liste)
- **Sprach-Default** – beim Client-Konstruktor setzbar, pro Aufruf überschreibbar
- **Fehlerbehandlung** – Exception-Hierarchie (`AuthError`, `NotFoundError`, `ValidationError`, …)
- **Context-Manager** – `with DataCycleClient(...) as client:` schließt die Session sauber
- **Response-Modelle** – Pydantic-validierte `ApiListResponse` mit typisierten `meta`/`links`

## Tests

```bash
# Smoke-Tests (keine Netzwerk-Aufrufe)
pytest tests/test_smoke.py -v

# Live-Tests gegen die API (nur lesend!)
pytest tests/test_live.py -v

# Endpunkt-abhängige Tests aktivieren:
$env:DATACYCLE_ENDPOINT_ID = "deine-endpoint-uuid"
pytest tests/test_live.py -v
```

## Build & Publishing (Forgejo)

```bat
build_wheel.bat                        :: baut dist\datacycle-<version>.whl
upload_wheel_to_forgejo_pypi.bat       :: lädt das Wheel in die Forgejo-Registry hoch
```

Vor dem Upload das Token in der lokalen `.pypirc` eintragen (gitignored, nie einchecken).

## Projektstruktur

```
datacycle_client/
├── pyproject.toml
├── requirements.txt
├── src/datacycle/          # Package (setuptools)
│   ├── client.py           # DataCycleClient
│   ├── exceptions.py       # Exception-Hierarchie
│   ├── models/             # Pydantic-Modelle
│   └── api/                # Sub-Clients
├── tests/                  # pytest
├── api_docs/               # Gespiegelte API-Dokumentation (Stand 2026-08-03)
└── client_docs/            # Client-Dokumentation mit Beispielen
```

## Future Points

- **Typsicherer Filter-Builder** – IDE-Autovervollständigung für Filter-DSL statt Dicts
- **Download-Endpunkt** – GPX/JSON/XML-Download (`/api/v4/endpoints/{id}/download`)
- **Schema-gesteuerte Content-Typisierung** – optionale Pydantic-Modelle für `@graph`-Einträge (z.B. `dcls:POI`, `dcls:Tour`)
- **Async-Support** – `httpx`-basierter Async-Client
- **PyPI-Publishing** – Package zusätzlich auf PyPI veröffentlichen (bisher nur Forgejo-Registry)

## Voraussetzungen

- Python ≥ 3.10
- `requests` ≥ 2.28
- `pydantic` ≥ 2.0
