Metadata-Version: 2.4
Name: omnizoek
Version: 0.1.0
Summary: Official Python SDK for the OmniZoek API — Dutch government data in one line of code
Project-URL: Homepage, https://omnizoek.nl
Project-URL: Documentation, https://omnizoek.nl/docs
Project-URL: Repository, https://github.com/JakoRens/searchworks-nl/tree/main/omni-sdk-py
License: MIT
Keywords: api,bag,dutch,iban,kvk,netherlands,postcode,rdw
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.10
Requires-Dist: httpx>=0.27.0
Requires-Dist: pydantic>=2.7.0
Provides-Extra: dev
Requires-Dist: mypy>=1.10.0; extra == 'dev'
Requires-Dist: pytest-asyncio>=0.23.0; extra == 'dev'
Requires-Dist: pytest-httpx>=0.30.0; extra == 'dev'
Requires-Dist: pytest>=8.0.0; extra == 'dev'
Requires-Dist: ruff>=0.4.0; extra == 'dev'
Description-Content-Type: text/markdown

# omnizoek · Python SDK

Official Python SDK for the [OmniZoek API](https://omnizoek.nl) — Dutch government data (address enrichment, IBAN/BIC, VAT, energy labels, emission zones, minimum wage, and more) in one line of code.

```python
from omnizoek import OmniClient

client = OmniClient(api_key="omni_live_...")

# Address enrichment (BAG + PDOK)
address = client.geo.enrich_address(postcode="1012LG", house_number="1")
print(address.street, address.city)  # Damrak Amsterdam

# IBAN → BIC
bic = client.finance.iban_to_bic(iban="NL91ABNA0417164300")
print(bic.bic, bic.bank_name)  # ABNANL2A ABN AMRO Bank N.V.

# Minimum wage
wage = client.hr.minimum_wage(age=21, date="2026-01-01")
print(f"€{wage.hourly_eur}/hour")  # €14.06/hour
```

## Installation

```bash
pip install omnizoek
```

Requires Python 3.10+.

## Quick start

```python
from omnizoek import OmniClient

client = OmniClient(api_key="omni_live_...")
```

Get an API key at [omnizoek.nl/signup](https://omnizoek.nl/signup). Use `omni_test_...` keys for development — they return fixture data and are never billed.

## Async support

Every method has an `async` counterpart via `AsyncOmniClient`:

```python
import asyncio
from omnizoek import AsyncOmniClient

async def main():
    async with AsyncOmniClient(api_key="omni_live_...") as client:
        address = await client.geo.enrich_address(postcode="1012LG", house_number="1")
        print(address.street)

asyncio.run(main())
```

## Endpoints

### Geo
```python
address = client.geo.enrich_address(postcode="1012LG", house_number="1")
# → AddressEnrichResponse
```

### Finance
```python
bic     = client.finance.iban_to_bic(iban="NL91ABNA0417164300")
# → IbanToBicResponse

vat     = client.finance.vat_verify(country_code="NL", vat_number="004495445B01")
# → VatVerifyResponse
```

### Compliance
```python
result  = client.compliance.validate_finance(type="bsn", number="123456782")
# → FinanceValidationResponse
```

### HR
```python
wage    = client.hr.minimum_wage(age=21, date="2026-01-01")
# → MinimumWageResponse

holiday = client.hr.holiday_surcharge(date="2026-04-27", industry="horeca")
# → HolidaySurchargeResponse
```

### Real Estate
```python
label   = client.real_estate.energy_label(postcode="1012LG", house_number="1")
# → EnergyLabelResponse
```

### Logistics
```python
zone    = client.logistics.emission_zone(kenteken="V-123-AB")
# → EmissionZoneResponse

transit = client.logistics.transit_disruptions(station_code="ASD")
# → TransitDisruptionsResponse
```

### Energy
```python
grid    = client.energy.grid_trigger(country_code="NL")
# → GridTriggerResponse
```

## Error handling

```python
from omnizoek import OmniClient
from omnizoek.exceptions import OmniAuthError, OmniNotFoundError, OmniRateLimitError, OmniError

client = OmniClient(api_key="omni_live_...")

try:
    address = client.geo.enrich_address(postcode="9999XX", house_number="1")
except OmniNotFoundError:
    print("Address not found")
except OmniRateLimitError as e:
    print(f"Rate limited, retry after {e.retry_after}s")
except OmniAuthError:
    print("Invalid API key")
except OmniError as e:
    print(f"API error: {e}")
```

| Exception | HTTP status | When |
|---|---|---|
| `OmniAuthError` | 401 | Invalid or missing API key |
| `OmniNotFoundError` | 404 | Resource not found |
| `OmniRateLimitError` | 429 | Rate limit exceeded |
| `OmniServerError` | 5xx | Upstream API unavailable |
| `OmniError` | Any | Base class for all SDK errors |

## CLI

```bash
omnizoek address 1012LG 1
omnizoek iban NL91ABNA0417164300
omnizoek wage 21 2026-01-01
omnizoek vat NL 004495445B01
```

Set your API key via environment variable:
```bash
export OMNIZOEK_API_KEY=omni_live_...
```

## Client options

```python
OmniClient(
    api_key="omni_live_...",   # or set OMNIZOEK_API_KEY env var
    base_url="https://api.omnizoek.nl",  # default
    timeout=10.0,              # seconds, default 10
    max_retries=3,             # retries on 429/5xx, default 3
)
```
