Metadata-Version: 2.5
Name: aiothreema
Version: 0.1.0
Summary: Async Python client for the Threema Gateway HTTP API
Project-URL: Homepage, https://github.com/LukasQ/aiothreema
Project-URL: Issues, https://github.com/LukasQ/aiothreema/issues
Author-email: Lukas Merz <merz.lukas@gmail.com>
License-Expression: MIT
License-File: LICENSE
Keywords: aiohttp,asyncio,gateway,messaging,threema
Classifier: Development Status :: 3 - Alpha
Classifier: Framework :: AsyncIO
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
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 :: Chat
Requires-Python: >=3.11
Requires-Dist: aiohttp>=3.9.0
Requires-Dist: pynacl>=1.5.0
Provides-Extra: test
Requires-Dist: pytest-asyncio>=0.24.0; extra == 'test'
Requires-Dist: pytest-cov>=5.0.0; extra == 'test'
Requires-Dist: pytest>=8.0.0; extra == 'test'
Description-Content-Type: text/markdown

# aiothreema

Async Python client for the [Threema Gateway](https://gateway.threema.ch/) HTTP API — send simple or end-to-end encrypted text messages from `asyncio` code.

This library implements the Gateway's HTTP wire protocol and NaCl-based end-to-end encryption directly (the official `threema.gateway` SDK is unmaintained), built on `aiohttp` and `PyNaCl`.

## Install

```bash
pip install aiothreema
```

## Usage

```python
import asyncio

from aiothreema import ThreemaGatewayClient


async def main() -> None:
    async with ThreemaGatewayClient("*GATEWAY", "api-secret") as client:
        await client.validate_credentials()
        message_id = await client.send_text_message("ABCD1234", "Hello!")
        print(message_id)


asyncio.run(main())
```

### End-to-end encryption

Pass a private key to send E2E-encrypted messages. The recipient's public key is looked up automatically via the Gateway's `/pubkeys/{id}` endpoint.

```python
async with ThreemaGatewayClient(
    "*GATEWAY", "api-secret", private_key="<64-char hex>"
) as client:
    await client.send_text_message("ABCD1234", "Hello, encrypted!")
```

### Generating a key pair

```python
from aiothreema import generate_key_pair, derive_public_key

private_key, public_key = generate_key_pair()
# Register public_key with your Gateway account at gateway.threema.ch,
# then store private_key securely — it cannot be recovered.

assert derive_public_key(private_key) == public_key
```

### Using an existing `aiohttp.ClientSession`

When embedding this client in a larger application (e.g. a long-lived service that already manages its own session pool), pass a session explicitly instead of using the context-manager form — the client will not close a session it doesn't own:

```python
client = ThreemaGatewayClient("*GATEWAY", "api-secret", session=my_session)
await client.send_text_message("ABCD1234", "Hello!")
```

## Errors

All errors inherit from `ThreemaGatewayError`:

- `ThreemaAuthError` — the Gateway ID or API secret was rejected.
- `ThreemaConnectionError` — a network/transport failure talking to the Gateway.
- `ThreemaSendError` — sending a message, or resolving a recipient's public key, failed.

## Development

```bash
pip install -e ".[test]"
pytest --cov=aiothreema
```

## License

MIT
