Metadata-Version: 2.4
Name: acuris-geo
Version: 0.1.0
Summary: Python SDK for the Acuris Address Validation, Geocoding, UK PAF Postcode Lookup, and Email Verification API (api.acuris-geo.com).
Author-email: Acuris GmbH <engineering@acuris-geo.com>
License: MIT
Project-URL: Homepage, https://api.acuris-geo.com
Project-URL: Documentation, https://api.acuris-geo.com/docs
Project-URL: Source, https://github.com/Acuris-GmbH/acuris-python-sdk
Project-URL: Issues, https://github.com/Acuris-GmbH/acuris-python-sdk/issues
Keywords: acuris,address-validation,geocoding,reverse-geocoding,postcode-lookup,uk-postcode,royal-mail-paf,email-validation,email-verification,sdk
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: requests>=2.28
Provides-Extra: test
Requires-Dist: pytest>=7; extra == "test"
Requires-Dist: responses>=0.23; extra == "test"
Dynamic: license-file

# acuris-geo

Python SDK for the **Acuris Address Validation, Geocoding, UK PAF Postcode Lookup, and Email Verification** API ([api.acuris-geo.com](https://api.acuris-geo.com)).

```bash
pip install acuris-geo
```

Requires Python ≥ 3.9. One runtime dep: `requests`.

## Quick start

```python
from acuris_geo import AcurisClient

# api_key falls back to env ACURIS_API_KEY if omitted.
cli = AcurisClient(api_key="...")

# Address validation (fielded)
r = cli.validate({
    "country": "deu",
    "street": "Friedrichstraße",
    "house_number": "43",
    "city": "Berlin",
    "postcode": "10117",
})
print(r["match_type"], r["lat"], r["lng"])

# Address validation (single-line string)
cli.validate("100 Pennsylvania Ave NW, Washington DC 20500", country="usa")

# Forward geocoding
cli.geocode("usa", street="Pennsylvania Ave NW", hno="1600",
            city="Washington", state="DC")

# Reverse geocoding
cli.reverse(51.5014, -0.1419, country="gbr")

# Autocomplete
cli.suggest("Friedrichstr", country="deu", limit=5)

# UK Royal Mail PAF postcode lookup
cli.postcode_lookup("SW1A 2AA")
# → {"count": 1, "addresses": [{"street": "DOWNING STREET", ...}]}

# Email verification (separate credit pool from address validation)
cli.email_validate("user@gmial.com")
# → {"deliverable": "risky", "did_you_mean": "user@gmail.com", ...}

# Batch email verification — up to 1,000 emails per call, atomic billing
cli.email_validate_batch(["a@gmail.com", "b@yahoo.com", "c@mailinator.com"])
# → {"count": 3, "results": [...], "email_quota_remaining": 247}
```

## Errors

Every error subclasses `AcurisError`:

```python
from acuris_geo import (
    AcurisAuthError,        # 401 — invalid / missing API key
    AcurisQuotaError,       # 402 / 403 — pack expired or quota reached
    AcurisValidationError,  # 400 / 422 — bad request shape or input
    AcurisNotFoundError,    # 404 — postcode / address not in reference data
    AcurisRateLimitError,   # 429 — anonymous tier or per-key cap
    AcurisServerError,      # 5xx — transient; SDK retries automatically
    AcurisTimeoutError,     # local timeout
    AcurisNetworkError,     # connection / DNS / TLS failure
)
```

Each exception carries `.status`, `.endpoint`, and `.body` (the parsed JSON
response body) so you can surface server-side detail without re-parsing.

```python
try:
    cli.email_validate_batch(huge_list)
except AcurisQuotaError as e:
    remaining = (e.body or {}).get("email_quota_remaining", 0)
    print(f"need {len(huge_list)} credits, have {remaining}")
```

## Pricing pools

Each plan has **three separate credit pools** (see [acuris-geo.com/acuris-pricing](https://acuris-geo.com/acuris-pricing/)):

| Pool | Decrements on |
|---|---|
| `validation_credits` / `quota_used` | `/validate`, `/postcode-lookup` |
| `geocode_credits` | `/geocode`, `/reverse` |
| `email_credits` / `email_quota_*` | `/email-validate`, `/email-validate/batch` |

A Dev trial gets **1,000 of each**; the **NA Growth** plan ($59/mo) gets
**25,000 address validations OR 10,000 geocodes PLUS 25,000 email
verifications**. Email verification is included free on every paid plan —
no separate SKU, no double billing.

## Retries + timeouts

`AcurisClient(max_retries=3, timeout_s=5.0)` (the defaults) retries on
5xx and 429 with exponential backoff (0.2s → 0.4s → 0.8s → 1.6s capped at
2s). Pass `max_retries=0` to disable, or `timeout_s=30.0` for batch calls.

## Connection pooling

The client uses a single `requests.Session` so HTTPS connections are
reused across calls. Pass `session=` if you need to share a session with
other HTTP traffic (e.g. behind a proxy or with custom adapters).

## License

MIT
