Metadata-Version: 2.4
Name: eurovalidate
Version: 0.1.0
Summary: Python SDK for the EuroValidate API — validate EU VAT, IBAN, EORI, and company data
Project-URL: Homepage, https://eurovalidate.com
Project-URL: Documentation, https://docs.eurovalidate.com/sdks/python
Project-URL: Repository, https://github.com/eurovalidate/eurovalidate-python
Project-URL: Changelog, https://docs.eurovalidate.com/changelog
Author-email: EuroValidate <support@eurovalidate.com>
License-Expression: MIT
Keywords: api,eori,eu,europe,iban,tax,validation,vat
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.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
Classifier: Typing :: Typed
Requires-Python: >=3.9
Requires-Dist: httpx>=0.28
Description-Content-Type: text/markdown

# EuroValidate Python SDK

Official Python SDK for the [EuroValidate API](https://eurovalidate.com) -- validate EU VAT numbers, IBANs, EORI numbers, and look up company data in one unified API.

## Installation

```bash
pip install eurovalidate
```

Requires Python 3.9+.

## Quick start

```python
from eurovalidate import EuroValidate

client = EuroValidate("ev_live_your_key_here")

# Validate a VAT number
result = client.validate_vat("NL820646660B01")
print(result.valid)          # True
print(result.company_name)   # "COOLBLUE B.V."
print(result.company_address)
print(result.meta.confidence) # "HIGH"
```

Get your free API key at [eurovalidate.com](https://eurovalidate.com).

## Usage

### VAT validation

```python
result = client.validate_vat("DE123456789")
print(result.valid, result.company_name, result.country_code)
```

### IBAN validation

```python
result = client.validate_iban("DE89370400440532013000")
print(result.valid, result.bank_name, result.bic)
```

### EORI validation

```python
result = client.validate_eori("DE328169180000040")
print(result.valid, result.company_name)
```

### Company lookup (by LEI)

```python
result = client.lookup_company_by_lei("724500Y6DUVHQD6OXN27")
print(result.company_name, result.registered_address)
```

### VAT rates

```python
rates = client.get_vat_rates("DE")
print(rates.standard_rate)  # 19.0
for rate in rates.rates:
    print(f"{rate.type}: {rate.rate}%")

# All EU countries
all_rates = client.get_all_vat_rates()
```

### Unified validation (multiple checks, one call)

```python
result = client.validate(
    vat="NL820646660B01",
    iban="DE89370400440532013000",
    eori="DE328169180000040",
)
print(result.vat.valid, result.iban.valid, result.eori.valid)
```

### Account info

```python
account = client.get_account()
print(f"Plan: {account.plan}, Used: {account.calls_used}/{account.calls_limit}")
```

## Async client

Every method is also available as an async version:

```python
from eurovalidate import AsyncEuroValidate

async with AsyncEuroValidate("ev_live_your_key_here") as client:
    result = await client.validate_vat("NL820646660B01")
    print(result.valid, result.company_name)
```

## Error handling

The SDK raises typed exceptions for API errors:

```python
from eurovalidate import EuroValidate, AuthError, RateLimitError, ValidationError

client = EuroValidate("ev_live_your_key_here")

try:
    result = client.validate_vat("INVALID")
except AuthError:
    print("Invalid API key")
except RateLimitError as e:
    print(f"Rate limited. Retry after {e.retry_after}s")
    print(f"Limit: {e.rate_limit.limit}, Remaining: {e.rate_limit.remaining}")
except ValidationError as e:
    print(f"Bad input: {e.detail}")
```

Rate-limited requests (HTTP 429) are automatically retried up to 3 times using the `Retry-After` header.

### Exception hierarchy

- `EuroValidateError` -- base class for all API errors
  - `AuthError` -- 401 Unauthorized
  - `RateLimitError` -- 429 Too Many Requests
  - `ValidationError` -- 400 / 422 invalid input
  - `NotFoundError` -- 404 Not Found
  - `ServerError` -- 5xx server errors

All exceptions include `status_code`, `detail`, `request_id`, and `rate_limit` attributes.

## Response metadata

Every result includes a `meta` field with data freshness information:

```python
result = client.validate_vat("NL820646660B01")
print(result.meta.confidence)      # "HIGH", "MEDIUM", "LOW", or "UNKNOWN"
print(result.meta.source)          # "vies_live", "cache", etc.
print(result.meta.cached)          # True/False
print(result.meta.response_time_ms)
print(result.meta.last_verified)   # ISO 8601 timestamp
```

## Configuration

```python
client = EuroValidate(
    "ev_live_your_key_here",
    base_url="https://api.eurovalidate.com",  # default
    timeout=30.0,                              # seconds, default
)
```

## License

MIT
