Metadata-Version: 2.4
Name: truelist-django
Version: 0.1.0
Summary: Django integration for Truelist email validation
Project-URL: Homepage, https://truelist.io
Project-URL: Documentation, https://github.com/Truelist-io-Email-Validation/truelist-django#readme
Project-URL: Repository, https://github.com/Truelist-io-Email-Validation/truelist-django
Project-URL: Changelog, https://github.com/Truelist-io-Email-Validation/truelist-django/blob/main/CHANGELOG.md
Project-URL: Issues, https://github.com/Truelist-io-Email-Validation/truelist-django/issues
Author-email: Truelist <support@truelist.io>
License: MIT
License-File: LICENSE
Keywords: django,drf,email,truelist,validation,verification
Classifier: Development Status :: 4 - Beta
Classifier: Framework :: Django
Classifier: Framework :: Django :: 4.2
Classifier: Framework :: Django :: 5.0
Classifier: Framework :: Django :: 5.1
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: Topic :: Communications :: Email
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Typing :: Typed
Requires-Python: >=3.9
Requires-Dist: django>=4.2
Requires-Dist: truelist>=0.1.0
Provides-Extra: dev
Requires-Dist: django-stubs>=4.2; extra == 'dev'
Requires-Dist: djangorestframework-stubs>=3.14; extra == 'dev'
Requires-Dist: djangorestframework>=3.14; extra == 'dev'
Requires-Dist: mypy>=1.0; extra == 'dev'
Requires-Dist: pytest-django>=4.5; extra == 'dev'
Requires-Dist: pytest>=7.0; extra == 'dev'
Requires-Dist: ruff>=0.4; extra == 'dev'
Provides-Extra: drf
Requires-Dist: djangorestframework>=3.14; extra == 'drf'
Description-Content-Type: text/markdown

# truelist-django

[![Free tier](https://img.shields.io/badge/free_plan-100_validations-4A7C59?style=flat-square)](https://truelist.io/pricing)
Django integration for the [Truelist](https://truelist.io) email validation API. Provides a Django model field validator, a DRF serializer field, and caching via Django's cache framework.

Built on top of the [truelist](https://github.com/Truelist-io-Email-Validation/truelist-python) Python SDK.

> **Start free** — 100 validations + 10 enhanced credits, no credit card required.
> [Get your API key →](https://app.truelist.io/signup?utm_source=github&utm_medium=readme&utm_campaign=free-plan&utm_content=truelist-django)

## Installation

```bash
pip install truelist-django
```

With DRF support:

```bash
pip install "truelist-django[drf]"
```

## Quick Start

Add your API key to Django settings:

```python
# settings.py
TRUELIST_API_KEY = "your-api-key"
```

### Django Validator

Use `TruelistEmailValidator` on any model field:

```python
from django.db import models
from truelist_django.validators import TruelistEmailValidator

class User(models.Model):
    email = models.EmailField(
        validators=[TruelistEmailValidator()]
    )
```

With options:

```python
class User(models.Model):
    email = models.EmailField(
        validators=[TruelistEmailValidator(
            allow_risky=True,      # Accept accept-all domains (default: True)
            fail_silently=True,    # Don't block on API errors (default: True)
        )]
    )
```

The validator is `@deconstructible`, so it works in Django migrations.

### DRF Serializer Field

Use `TruelistEmailField` in any DRF serializer:

```python
from rest_framework import serializers
from truelist_django.fields import TruelistEmailField

class SignupSerializer(serializers.Serializer):
    email = TruelistEmailField()
```

With options:

```python
class SignupSerializer(serializers.Serializer):
    email = TruelistEmailField(
        allow_risky=False,
        fail_silently=True,
    )
```

## Settings Reference

All settings are optional except `TRUELIST_API_KEY`.

| Setting | Default | Description |
|---------|---------|-------------|
| `TRUELIST_API_KEY` | `""` | Your Truelist API key (required) |
| `TRUELIST_BASE_URL` | `"https://api.truelist.io"` | API base URL |
| `TRUELIST_TIMEOUT` | `10` | Request timeout in seconds |
| `TRUELIST_ALLOW_RISKY` | `True` | Accept emails with "risky" state by default |
| `TRUELIST_CACHE_ENABLED` | `False` | Enable caching of validation results |
| `TRUELIST_CACHE_TTL` | `3600` | Cache duration in seconds |
| `TRUELIST_CACHE_ALIAS` | `"default"` | Which Django cache backend to use |

## Caching

Enable caching to reduce API calls for repeated validations:

```python
# settings.py
TRUELIST_CACHE_ENABLED = True
TRUELIST_CACHE_TTL = 3600  # 1 hour
TRUELIST_CACHE_ALIAS = "default"
```

When caching is enabled, validation results are stored in Django's cache framework. Results with `unknown` state are never cached, so they are always re-validated.

You can also use the cached client directly:

```python
from truelist_django.cache import CachedTruelistClient

client = CachedTruelistClient()
result = client.validate("user@example.com")
print(result.state)  # "ok", "email_invalid", "risky", or "unknown"
```

## Validation States

The Truelist API returns one of four states:

| State | Description | Default Behavior |
|-------|-------------|-----------------|
| `ok` | Email is deliverable | Passes validation |
| `email_invalid` | Email is not deliverable | Fails validation |
| `risky` | Email may be deliverable (accept-all domain) | Passes when `allow_risky=True` (default) |
| `unknown` | Could not determine deliverability | Passes when `fail_silently=True` (default) |

Authentication errors (401) always raise, regardless of `fail_silently`.

## Error Handling

By default (`fail_silently=True`), API errors and network issues are logged and the email passes validation. This prevents your forms from breaking when the Truelist API is unavailable.

Set `fail_silently=False` to reject emails when the API cannot be reached.

Authentication errors (invalid API key) always raise immediately, regardless of `fail_silently`.

## Testing

```bash
pip install -e ".[dev]"
python -m pytest tests/ -v
```

## Compatibility

- Python 3.9+
- Django 4.2, 5.0, 5.1
- DRF 3.14+ (optional)


## Getting Started

Sign up for a [free Truelist account](https://app.truelist.io/signup?utm_source=github&utm_medium=readme&utm_campaign=free-plan&utm_content=truelist-django) to get your API key. The free plan includes 100 validations and 10 enhanced credits — no credit card required.
## License

MIT
