# DexFather

**Python SDK for the Dexster Bot API**

Build bots for the [Dexster](https://dexster.io) social trading platform with an async-first, fully typed Python SDK.

## Install

```bash
pip install dexfather
```

## Quick Start

```python
import os
from dexfather import DexFatherBot

bot = DexFatherBot(os.environ["DEXSTER_BOT_TOKEN"])

@bot.command("start")
async def on_start(update, bot):
    await bot.send_message(
        update.message.chat.id,
        "Hello! I'm alive.",
    )

@bot.on_message()
async def on_echo(update, bot):
    await bot.send_message(
        update.message.chat.id,
        f"You said: {update.message.text}",
    )

bot.run_polling()
```

## Features

- **Async/await** -- built on `httpx` for non-blocking I/O
- **Rich object models** -- Pydantic v2 models for every API type (messages, users, chats, polls, etc.)
- **Exception hierarchy** -- `BadRequest`, `Unauthorized`, `Forbidden`, `NotFound`, `RateLimited` for precise error handling
- **Automatic retries** -- exponential backoff with jitter via `tenacity`
- **Middleware pipeline** -- plug in logging, timing, rate limiting, or custom pre/post processing
- **Keyboard builders** -- `InlineKeyboardBuilder` with fluent chaining and `adjust()` layout
- **Conversation state machine** -- `ConversationHandler` for multi-step flows with optional server-side persistence
- **Inline queries** -- handle `@botusername` inline queries with 20+ result types (article, photo, gif, video, audio, document, location, venue, contact + 8 cached variants)
- **File uploads** -- upload files via `uploadFile` API, get `dxf_` file_ids, send by file_id with `get_file()`
- **Composable filters** -- `TEXT & ~COMMAND`, `PHOTO | VIDEO`, `ChatType.PRIVATE`, `Regex(r"pattern")` with boolean algebra
- **Reactions** -- handle incoming `message_reaction` updates with `MessageReactionUpdated` type
- **Live location** -- send, update, and stop live locations with `send_location()`, `edit_message_live_location()`, `stop_message_live_location()`
- **Test utilities** -- `MockBot` and `TestClient` for unit testing without a live server
- **Full type hints** -- `py.typed` marker for mypy/pyright support
- **Multiple transports** -- polling, WebSocket, and webhook (with Starlette/Uvicorn)

## Token Format

Bot tokens use the `dxt_<base64url>` format. You receive one when creating a bot through @DexFather on Dexster.

## Documentation

- [Getting Started](docs/getting-started.md) -- 5-minute tutorial from zero to working bot
- [Examples](examples/) -- Echo bot, keyboard bot, conversation bot, inline bot, admin bot, polls, webhooks
- [API Reference](docs/api/) -- Generated pdoc HTML covering all public classes and methods

### Guides

- [Keyboards & Buttons](docs/guides/keyboards.md) -- Inline keyboards, reply keyboards, button styling
- [Inline Mode](docs/guides/inline-mode.md) -- Handle @botusername inline queries
- [Callbacks](docs/guides/callbacks.md) -- Callback query handling and patterns
- [Chat Management](docs/guides/chat-management.md) -- Banning, promoting, permissions
- [Conversations](docs/guides/conversations.md) -- Multi-step conversation state machine
- [Middleware](docs/guides/middleware.md) -- Custom pre/post processing pipeline
- [File Uploads](docs/guides/file-uploads.md) -- Upload files, file_id system, send by file_id
- [Reactions & Updates](docs/guides/reactions.md) -- Reactions API and new update types
- [Composable Filters](docs/guides/filters.md) -- Boolean filter composition for message handlers
- [Live Location](docs/guides/live-location.md) -- Real-time location sharing
- [Testing](docs/guides/testing.md) -- Unit test your bot with MockBot and TestClient
- [Migration from Telegram](docs/migration/from-telegram.md) -- Side-by-side porting guide with 75+ method mappings

## Examples

| Example | Description |
|---------|-------------|
| [echo_bot.py](examples/echo_bot.py) | Minimal echo bot |
| [keyboard_bot.py](examples/keyboard_bot.py) | Inline and reply keyboards |
| [conversation_bot.py](examples/conversation_bot.py) | Multi-step conversation state machine |
| [inline_bot.py](examples/inline_bot.py) | Inline query handler |
| [poll_bot.py](examples/poll_bot.py) | Creating and managing polls |
| [admin_bot.py](examples/admin_bot.py) | Chat administration commands |
| [menu_bot.py](examples/menu_bot.py) | Bot menu and commands |
| [webhook_bot.py](examples/webhook_bot.py) | Webhook mode with Starlette |
| [file_upload_bot.py](examples/file_upload_bot.py) | File upload and file_id usage |
| [reaction_bot.py](examples/reaction_bot.py) | Reactions and reaction updates |
| [filter_bot.py](examples/filter_bot.py) | Composable filter expressions |
| [live_location_bot.py](examples/live_location_bot.py) | Live location tracking |
| [demo_bot.py](examples/demo_bot.py) | Full-featured demo covering all SDK capabilities |

## Requirements

- Python 3.9+
- Dependencies: `httpx`, `pydantic`, `tenacity`, `structlog`
- Optional: `uvicorn` + `starlette` for webhook mode (`pip install dexfather[webhook]`)

## License

MIT
