Metadata-Version: 2.4
Name: nullmail
Version: 0.1.0
Summary: Official typed Python client for the NullMail temporary email Pro API
Project-URL: Homepage, https://github.com/irtco/nullmail
Project-URL: Repository, https://github.com/irtco/nullmail
Project-URL: Documentation, https://github.com/irtco/nullmail/tree/main/nullmail-python#readme
Project-URL: Issues, https://github.com/irtco/nullmail/issues
Author: NullMail
License: MIT License
        
        Copyright (c) 2026 NullMail
        
        Permission is hereby granted, free of charge, to any person obtaining a copy
        of this software and associated documentation files (the "Software"), to deal
        in the Software without restriction, including without limitation the rights
        to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
        copies of the Software, and to permit persons to whom the Software is
        furnished to do so, subject to the following conditions:
        
        The above copyright notice and this permission notice shall be included in all
        copies or substantial portions of the Software.
        
        THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
        IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
        FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
        AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
        LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
        OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
        SOFTWARE.
License-File: LICENSE
Keywords: api-client,disposable-email,email-testing,nullmail,temporary-email
Classifier: Development Status :: 3 - Alpha
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 :: Only
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: Programming Language :: Python :: 3.14
Classifier: Topic :: Communications :: Email
Classifier: Topic :: Software Development :: Testing
Classifier: Typing :: Typed
Requires-Python: >=3.9
Requires-Dist: httpx<1,>=0.24
Provides-Extra: cli
Provides-Extra: dev
Requires-Dist: build<2,>=1.2; extra == 'dev'
Requires-Dist: mypy<2,>=1.8; extra == 'dev'
Requires-Dist: pytest-cov<7,>=4.1; extra == 'dev'
Requires-Dist: pytest<9,>=7.4; extra == 'dev'
Requires-Dist: ruff<1,>=0.4; extra == 'dev'
Requires-Dist: twine<7,>=5; extra == 'dev'
Description-Content-Type: text/markdown

# NullMail for Python

The official typed Python client for the NullMail Pro API. Create temporary inboxes, list
received messages, open full messages, and wait for verification codes or verification URLs
from synchronous or asynchronous applications.

NullMail is receive-only and intended for legitimate privacy-conscious development and testing.

## Requirements

- Python 3.9 or newer
- A NullMail Pro API key

## Installation

```bash
pip install nullmail
```

The lightweight CLI is implemented with Python's standard library and can be installed using:

```bash
pip install "nullmail[cli]"
```

## Authentication

Pass the API key directly:

```python
from nullmail import NullMail

client = NullMail(api_key="YOUR_NULLMAIL_API_KEY")
```

For applications and the CLI, prefer the `NULLMAIL_API_KEY` environment variable.

Linux and macOS:

```bash
export NULLMAIL_API_KEY="your_api_key"
```

Windows PowerShell:

```powershell
$env:NULLMAIL_API_KEY="your_api_key"
```

Then initialize without arguments:

```python
client = NullMail()
```

The library never places the key in URLs and redacts it from exceptions. Do not commit API keys
to source control.

## API origin

Version 0.1.0 uses the production NullMail API at `https://www.nullmail.xyz` by default.
Self-hosted deployments can set another HTTPS origin explicitly:

```python
client = NullMail(base_url="https://your-nullmail.example.com")
```

or:

```bash
export NULLMAIL_BASE_URL="https://your-nullmail.example.com"
```

HTTP is rejected for every host except `localhost`, `127.0.0.1`, and `::1`. TLS verification is
always enabled and redirects are not followed, preventing credentials from being forwarded to a
different host.

## Create an inbox

```python
from nullmail import NullMail

with NullMail() as client:
    inbox = client.create_inbox("build-test")
    print(inbox.email)
```

Allow the server to generate the username:

```python
inbox = client.create_inbox()
```

Inbox creation is not automatically retried because the endpoint does not currently accept an
idempotency key.

## List messages

```python
inbox = client.get_inbox("build-test@web-library.net")

for message in inbox.messages:
    print(message.subject)
    print(message.sender)
    print(message.preview)
    print(message.verification.code)
    print(message.verification.url)
```

Verification values may be `None` when they are not present in the provider's message preview.

## Read a full message

```python
message = client.get_message(
    message_id="MESSAGE_ID",
    email="build-test@web-library.net",
)

print(message.subject)
print(message.text)
print(message.html)
print(message.verification.code)
print(message.verification.url)
```

The email address is an optional lookup hint. Full HTML email content is untrusted; do not render
it without isolation and sanitization.

## Wait for a verification email

```python
verification = client.wait_for_verification(
    email="build-test@web-library.net",
    subject_contains="Verify",
    sender_contains="example.com",
    timeout=120,
    interval=3,
)

print(verification.code)
print(verification.url)
```

The helper processes each message at most once, opens the full message when its summary lacks
verification details, and raises `VerificationTimeoutError` when the deadline is reached.

## Async usage

```python
import asyncio

from nullmail import AsyncNullMail


async def main() -> None:
    async with AsyncNullMail() as client:
        inbox = await client.create_inbox("build-test")
        verification = await client.wait_for_verification(inbox.email, timeout=120)
        print(verification.code)


asyncio.run(main())
```

## Refresh an inbox

```python
inbox = client.refresh_inbox("build-test@web-library.net")
```

Refresh requests are safely retryable but remain subject to the server's plan cooldown.

## Error handling

```python
from nullmail import AuthenticationError, RateLimitError

try:
    inbox = client.create_inbox("build-test")
except AuthenticationError:
    print("The API key is invalid or revoked.")
except RateLimitError as error:
    print("Retry after:", error.retry_after)
```

The public hierarchy includes:

- `ConfigurationError`
- `AuthenticationError`
- `AuthorizationError`
- `ValidationError`
- `NotFoundError`
- `RateLimitError`
- `APIError`
- `ConnectionError`
- `TimeoutError`
- `VerificationTimeoutError`

API errors preserve safe `status_code`, `request_id`, `error_code`, and `details` attributes.

## Configuration

```python
client = NullMail(
    api_key="...",
    base_url="https://your-nullmail.example.com",
    timeout=15,
    max_retries=3,
)
```

Retries apply to temporary connection failures and HTTP `429`, `500`, `502`, `503`, and `504`
responses for safe operations. The client uses exponential backoff and respects `Retry-After`.

## CLI

The CLI reads the key only from `NULLMAIL_API_KEY`; it deliberately has no API-key argument.

```bash
nullmail create build-test
nullmail inbox build-test@web-library.net
nullmail message MESSAGE_ID --email build-test@web-library.net
nullmail wait build-test@web-library.net --subject Verify --timeout 120
```

Use `--base-url` or `NULLMAIL_BASE_URL` to target a self-hosted NullMail deployment.

## Security recommendations

- Store API keys in a secret manager or environment variable.
- Never log client request headers or complete received email bodies.
- Treat sender names, subjects, message bodies, attachments, and verification URLs as untrusted.
- Validate a verification URL's destination before opening it.
- Revoke API keys that may have been exposed.
- Use HTTPS in every deployed environment.

## Development

```bash
python -m venv .venv
.venv\Scripts\Activate.ps1  # Windows PowerShell
python -m pip install -e ".[dev]"
python -m pytest
python -m ruff check .
python -m ruff format --check .
python -m mypy nullmail
```

Tests use `httpx.MockTransport` and never call the live NullMail API.

Build and validate distributions:

```bash
python -m build
python -m twine check dist/*
```

## License

MIT. See [LICENSE](LICENSE).
