Metadata-Version: 2.4
Name: isdisposable
Version: 1.0.0
Summary: Detect disposable and temporary email addresses. 160k+ domains, zero dependencies.
Project-URL: Homepage, https://isdisposable.com
Project-URL: Documentation, https://isdisposable.com/docs
Project-URL: Repository, https://github.com/isdisposable/python
Project-URL: Issues, https://github.com/isdisposable/python/issues
Author-email: Junaid Shaukat <junaidshaukat546@gmail.com>
License-Expression: MIT
Keywords: burner-email,disposable-email,email-validation,email-verification,signup-protection,spam-prevention,temp-email
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.8
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 :: Communications :: Email
Classifier: Topic :: Security
Classifier: Typing :: Typed
Requires-Python: >=3.8
Description-Content-Type: text/markdown

<p align="center">
  <img src="https://isdisposable.com/logo.png" width="60" alt="isDisposable" />
</p>

<h1 align="center">isdisposable</h1>

<p align="center">
  <strong>Detect disposable emails in Python. One function call.</strong>
</p>

<p align="center">
  <a href="https://pypi.org/project/isdisposable/"><img src="https://img.shields.io/pypi/v/isdisposable?style=flat-square&color=6366f1" alt="PyPI version" /></a>
  <a href="https://pypi.org/project/isdisposable/"><img src="https://img.shields.io/pypi/pyversions/isdisposable?style=flat-square" alt="Python versions" /></a>
  <a href="https://github.com/isdisposable/python/blob/main/LICENSE"><img src="https://img.shields.io/pypi/l/isdisposable?style=flat-square" alt="License" /></a>
</p>

<p align="center">
  Open-source disposable email detection with <strong>160,000+</strong> domains.<br/>
  Offline-first. Zero dependencies. Fully typed.
</p>

<p align="center">
  <a href="https://isdisposable.com">Website</a> · <a href="https://isdisposable.com/docs">Docs</a> · <a href="https://isdisposable.com/docs/api-reference">API Reference</a>
</p>

---

## Install

```bash
pip install isdisposable
```

## Usage

```python
from isdisposable import is_disposable

is_disposable("test@mailinator.com")  # True
is_disposable("user@gmail.com")       # False
```

Synchronous. Offline. Zero config.

## Bulk Check

```python
from isdisposable import is_disposable_bulk

results = is_disposable_bulk([
    "a@tempmail.com",
    "b@gmail.com",
    "c@guerrillamail.com",
])
# [True, False, True]
```

## Domain Check

```python
from isdisposable import is_domain_disposable

is_domain_disposable("mailinator.com")  # True
is_domain_disposable("gmail.com")       # False
```

## API Mode — Real-time Detection

For DNS/MX validation, risk scoring, and domain age analysis:

```python
from isdisposable import create_client

client = create_client(api_key="isd_live_xxxxx")

result = client.check("test@suspicious-domain.com")
print(result.disposable)       # True
print(result.score)            # 95
print(result.reason)           # "blocklist_match"
print(result.mx_valid)         # True
print(result.domain_age_days)  # 3
```

The API client automatically falls back to offline detection on network errors.

### Error Handling

```python
from isdisposable import create_client
from isdisposable.client import AuthenticationError, RateLimitError

client = create_client(api_key="wrong_key")

try:
    result = client.check("test@example.com")
except AuthenticationError:
    print("Invalid API key")
except RateLimitError:
    print("Too many requests")
```

### Bulk API Check

```python
results = client.check_bulk([
    "a@tempmail.com",
    "b@gmail.com",
])
for r in results:
    print(f"{r.email}: {r.disposable} (score: {r.score})")
```

## Framework Integrations

<details>
<summary><strong>Django — Form Validation</strong></summary>

```python
from django import forms
from isdisposable import is_disposable

class SignupForm(forms.Form):
    email = forms.EmailField()

    def clean_email(self):
        email = self.cleaned_data["email"]
        if is_disposable(email):
            raise forms.ValidationError("Disposable emails are not allowed.")
        return email
```
</details>

<details>
<summary><strong>FastAPI — Dependency</strong></summary>

```python
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
from isdisposable import is_disposable

app = FastAPI()

class SignupRequest(BaseModel):
    email: str
    password: str

@app.post("/signup")
def signup(req: SignupRequest):
    if is_disposable(req.email):
        raise HTTPException(400, "Disposable emails are not allowed")
    return {"ok": True}
```
</details>

<details>
<summary><strong>Flask — Before Request</strong></summary>

```python
from flask import Flask, request, jsonify
from isdisposable import is_disposable

app = Flask(__name__)

@app.route("/signup", methods=["POST"])
def signup():
    email = request.json.get("email", "")
    if is_disposable(email):
        return jsonify(error="Disposable emails are not allowed"), 400
    return jsonify(ok=True)
```
</details>

<details>
<summary><strong>Pydantic — Field Validator</strong></summary>

```python
from pydantic import BaseModel, field_validator
from isdisposable import is_disposable

class User(BaseModel):
    email: str

    @field_validator("email")
    @classmethod
    def check_disposable(cls, v: str) -> str:
        if is_disposable(v):
            raise ValueError("Disposable emails are not allowed")
        return v
```
</details>

## API Reference

### `is_disposable(email: str) -> bool`
Returns `True` if the email is from a disposable provider.

### `is_disposable_bulk(emails: list[str]) -> list[bool]`
Bulk check. Returns list of booleans matching input order.

### `is_domain_disposable(domain: str) -> bool`
Check a domain directly.

### `extract_domain(email: str) -> str | None`
Extract the domain from an email address.

### `create_client(api_key, ...) -> IsDisposableClient`
Create an API client with `.check()`, `.check_bulk()`, and `.clear_cache()`.

## SDKs

| Language | Package | Status |
|----------|---------|--------|
| JavaScript/TypeScript | [`@isdisposable/js`](https://www.npmjs.com/package/@isdisposable/js) | Stable |
| Python | [`isdisposable`](https://pypi.org/project/isdisposable/) | Stable |
| Go | `isdisposable-go` | Coming soon |

## License

MIT

---

<p align="center">
  Built by <a href="https://github.com/junaiddshaukat">Junaid Shaukat</a><br/>
  Dashboard & API at <a href="https://isdisposable.com">isdisposable.com</a>
</p>
