Metadata-Version: 2.4
Name: acuris-geo
Version: 0.2.0
Summary: Python SDK for the Acuris Address Validation, Autocomplete, Geocoding, and UK PAF Postcode Lookup 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,autocomplete,address-autocomplete,typeahead,postcode-lookup,uk-postcode,royal-mail-paf,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, Autocomplete, Geocoding, and UK PAF Postcode Lookup** 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")

# Address autocomplete (type-ahead)
cli.autocomplete("Friedrichstr", country="deu", limit=5)   # alias: cli.suggest(...)

# Autocomplete (UK is routed to the Royal Mail PAF service automatically;
# the query may be, or start with, a postcode)
cli.autocomplete("SW1A 2", country="gbr")

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

# Validate up to 200 addresses per request
cli.validate_batch(["Eckenbertstraße 31, 67549 Worms"], country="deu")

# Free evaluation key (no key needed). Set accept_terms=True ONLY after the
# person has agreed to the Terms of Service and the UK PAF Evaluation Terms:
#   https://api.acuris-geo.com/legal/terms
#   https://api.acuris-geo.com/legal/uk-evaluation-terms
from acuris_geo import request_dev_key
request_dev_key("you@example.com", accept_terms=True)
```

## 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.validate_batch(rows)
except AcurisQuotaError as e:
    print("quota reached:", e.body)
```

## Pricing and quota

Plans, quota and what each call costs are on
[acuris-geo.com/acuris-pricing](https://acuris-geo.com/acuris-pricing/).
`/check-key?key=...` and `/account/balances` report your current balance.

## 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
