Metadata-Version: 2.5
Name: phound
Version: 0.3.0
Summary: Phound SDK
Project-URL: Homepage, https://bot-sdk.phound.app
Project-URL: Documentation, https://bot-sdk.phound.app
Project-URL: Changelog, https://bot-sdk.phound.app/changelog/
Author-email: Denys Varenyk <dvarenyk@carrierx.com>, Anatoliy Kachan <akachan@freeconferencecall.com>
License: MIT
License-File: LICENSE
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Requires-Python: >=3.10
Requires-Dist: pillow>=10.3.0
Requires-Dist: python-dotenv==1.0.1
Requires-Dist: requests>=2.34.2
Description-Content-Type: text/markdown

# Phound SDK

[![PyPI](https://img.shields.io/pypi/v/phound.svg)](https://pypi.org/project/phound/)
[![Python](https://img.shields.io/pypi/pyversions/phound.svg)](https://pypi.org/project/phound/)
[![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](https://opensource.org/licenses/MIT)
[![Docs](https://img.shields.io/badge/docs-bot--sdk.phound.app-1f6feb.svg)](https://bot-sdk.phound.app)

Python SDK for building chatbots and voice/call automation on the
[Phound](https://phound.app) messaging platform.

You write handler classes; the SDK runs one instance of yours per chat and per
call, and calls your methods as events arrive. There is no server to deploy, no
webhook endpoint to expose and no event loop to write — `start_listen_events()`
blocks, and everything else happens in your callbacks.

## What you can build

- **Chatbots** in private and group chats — text, attachments, quotes,
  `@mentions`, typing indicators, HTML/markdown formatting, chat history.
- **SMS to and from plain phone numbers**, including people with no Phound
  account: resolve a number to the persona the platform addresses it by, then
  text them.
- **Voice bots**: answer, reject or place calls; play audio with
  pause/resume/seek; record the call in chunks as it happens.
- **Realtime voice agents**: stream call audio over a websocket to an AI
  service and speak the answer back, with DTMF in both directions.
- **Voice messages**, delivered to your handler with the platform's
  transcription.

## Install

```bash
uv add phound      # or: pip install phound
```

Python 3.10 or newer. 3.10 is tested but deprecated — it emits a
`DeprecationWarning` on `import phound`, and a future minor release will
require 3.11+.

## Quickstart

Put a token in a `.env` file in your project directory:

```
TOKEN=<token>
```

Get a token from the **Support Bot** in the Phound app — message it
`/generate_token` and it replies with yours. Phound allows one active token per
account; `/show_generated_token` shows it again and `/revoke_token` revokes it.

That is the whole configuration the SDK requires. To answer SMS and phone calls,
your bot also needs a premium number assigned to it in the Phound app.

```python
import time

from phound import Phound
from phound.handlers import BaseChatHandler


class ChatHandler(BaseChatHandler):
    def on_message(self, message):
        self.show_typing()
        time.sleep(1)
        self.send_message(f"You said: {message.text}")


if __name__ == "__main__":
    with Phound() as phound:
        phound.register_chat_handler(ChatHandler)
        phound.start_listen_events()
```

Run it, message the bot from the Phound app, and it answers.

## Three things worth knowing before you start

**Handlers are constructed by the SDK, not by you.** To give one a config
object, an API client or a knowledge base, declare it keyword-only and register
the handler pre-bound: `functools.partial(ChatHandler, kb=kb)`. Whatever you
bind is shared by every instance, so it must be thread-safe; per-conversation
state belongs on the handler itself.
→ [Passing dependencies to handlers](https://bot-sdk.phound.app/usage/#passing-dependencies-to-handlers)

**Blocking calls belong to the handler's own thread.** `send_message()`,
`get_history()` and `lookup_phone_number()` wait for the platform's reply on the
channel your handler is reading, so from a timer or webhook thread they raise
`ChatError` rather than racing it. Use `send_message_nowait()` from anywhere
else — it waits for nothing and is safe from any thread.
→ [Usage](https://bot-sdk.phound.app/usage/)

**A caller on a plain phone has no account to address — only a number.** In a
1:1 call with them, the call's own chat *is* the SMS chat with that caller, so
`self.chat.send_message_nowait(text)` reaches their handset with no lookup at
all. Anywhere else, resolve the number once with `lookup_phone_number()` and
send by `persona_uid` afterwards.
→ [Reaching someone by phone number](https://bot-sdk.phound.app/usage/#reaching-someone-by-phone-number)

## Documentation

Full documentation lives at **[bot-sdk.phound.app](https://bot-sdk.phound.app)**.

| | |
|---|---|
| [Configuration](https://bot-sdk.phound.app/configuration/) | The `TOKEN`, logging, and what is logged at which level |
| [Usage](https://bot-sdk.phound.app/usage/) | A complete chatbot, handler dependencies, reaching someone by phone number |
| [Examples](https://bot-sdk.phound.app/examples/) | Runnable scripts — AI chatbot, answering machine, realtime audio, voice agent, texting a PSTN caller mid-call |
| [API Reference](https://bot-sdk.phound.app/reference/) | `Phound`, both handler base classes, every event object and exception |
| [Text helpers](https://bot-sdk.phound.app/text-helpers/) | `bold`, `italic`, `underline`, `mention` |
| [Changelog](https://bot-sdk.phound.app/changelog/) | What changed in each release, and how to migrate |

## Versioning

The SDK is `0.x`, where a **minor release may contain breaking changes** —
[SemVer places major version zero outside the compatibility
guarantee](https://semver.org/spec/v2.0.0.html#spec-item-4). In exchange, every
breaking change is listed in the changelog with what to do instead, and anything
scheduled for removal is deprecated — and warns at runtime — for at least one
minor release first. Pinning `0.2.*`, upgrading, and reading your own warnings
is enough to migrate without surprises.

## Support

`phound` is developed in a private repository; this SDK and its documentation
are public, but the source is not open for outside contributions.

Tokens come from the Support Bot in the Phound app (`/generate_token`). For
anything else — a bug, a feature request — email
[support@phound.app](mailto:support@phound.app), and for a bug include what you
are building, your SDK version, what you expected versus what happened, and a
minimal snippet that reproduces it.

```bash
python -c "from importlib.metadata import version; print(version('phound'))"
```

## License

MIT — see [LICENSE](LICENSE).
