Metadata-Version: 2.4
Name: sufyaanmx
Version: 0.1.0
Summary: DNS-based Email Service Provider (ESP) detection library
Author: Sufyaan T
License: MIT
Project-URL: Homepage, https://github.com/sufyaan-t/sufyaanmx
Project-URL: Bug Tracker, https://github.com/sufyaan-t/sufyaanmx/issues
Keywords: email,esp,dns,mx,spf,detection
Classifier: Development Status :: 3 - Alpha
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: Topic :: Communications :: Email
Classifier: Topic :: Internet :: Name Service (DNS)
Classifier: Typing :: Typed
Requires-Python: >=3.9
Description-Content-Type: text/markdown
Requires-Dist: dnspython>=2.4.0
Provides-Extra: dev
Requires-Dist: pytest>=7.0; extra == "dev"
Requires-Dist: pytest-cov; extra == "dev"
Requires-Dist: mypy; extra == "dev"
Requires-Dist: ruff; extra == "dev"

# sufyaanmx

**DNS-based Email Service Provider (ESP) detection library.**

Given a domain, `sufyaanmx` returns every detected ESP, a per-provider
confidence score, and the raw DNS signals that drove each decision.

---

## Features

- Detects **14+ ESP providers** out of the box (Google Workspace, Microsoft 365, SendGrid, Mailgun, Amazon SES, Postmark, Zoho, Mimecast, Proofpoint, HubSpot, Klaviyo, Brevo, Mailchimp/Mandrill, Fastmail)
- **Recursive SPF include resolution** (depth-limited, loop-safe)
- **Structured, typed output** via dataclasses — no raw dicts
- **Multiple providers** can be returned per domain
- **Additive confidence scoring**: MX hit (+0.6) + SPF hit (+0.4), capped at 1.0
- Fault-tolerant: DNS failures and invalid domains degrade gracefully
- Easily **extensible** fingerprint registry
- Single external dependency: [`dnspython`](https://www.dnspython.org/)

---

## Installation

```bash
pip install sufyaanmx
```

Or install from source:

```bash
git clone https://github.com/sufyaan-t/sufyaanmx.git
cd sufyaanmx
pip install -e .
```

---

## Quick Start

```python
from sufyaanmx import detect, bulk_detect

# Single domain
result = detect("example.com")

print(result.domain)       # "example.com"
print(result.providers)    # ["Google Workspace"]  ← sorted by confidence
print(result.confidence)   # 1.0
print(result.signals)      # {"mx_records": [...], "spf_record": "...", ...}

# Bulk
results = bulk_detect(["github.com", "stripe.com", "mailchimp.com"])
for r in results:
    print(r.domain, r.providers, r.confidence)
```

---

## Output Model

```python
@dataclass
class DetectionResult:
    domain: str
    providers: List[str]        # sorted by confidence descending
    confidence: float           # 0.0 – 1.0
    signals: Dict[str, Any]     # mx_records, spf_record, matched_fingerprints, ...
```

### `signals` keys

| Key | Type | Description |
|---|---|---|
| `mx_records` | `List[str]` | Raw MX hostnames resolved for the domain |
| `spf_record` | `str \| None` | Raw SPF TXT record, if found |
| `spf_includes` | `List[str]` | All recursively expanded SPF include domains |
| `matched_fingerprints` | `List[dict]` | Per-provider match details (score, mx_matches, spf_matches) |
| `provider_scores` | `Dict[str, float]` | Raw scores keyed by provider name |

---

## Scoring Logic

| Signal | Weight |
|---|---|
| MX hostname matches a fingerprint pattern | +0.6 |
| SPF include/record matches a fingerprint pattern | +0.4 |

Scores are **additive** within a provider and **capped at 1.0**.
Multiple providers can be returned.

---

## Extending Fingerprints

Add entries to `sufyaanmx/fingerprints.py`:

```python
FINGERPRINTS["My Custom ESP"] = {
    "mx": ["mail.myesp.com"],
    "spf": ["spf.myesp.com"],
}
```

---

## Project Structure

```
sufyaanmx/
├── __init__.py       # Public API surface
├── core.py           # Detection orchestration
├── dns.py            # DNS resolution layer (dnspython)
├── fingerprints.py   # ESP fingerprint registry
├── models.py         # DetectionResult, ProviderMatch dataclasses
├── spf.py            # SPF parsing & recursive include resolution
├── utils.py          # Domain validation, clamping helpers
└── exceptions.py     # Custom exception hierarchy
```

---

## Author

**Sufyaan T**

---

## License

MIT
