Metadata-Version: 2.3
Name: python-yappy
Version: 0.1.2
Summary: API Bindings for Yapper!
Author: H1387Lmao
Requires-Dist: aiohttp>=3.14.5
Requires-Dist: load-dotenv>=0.1.0
Requires-Dist: rich>=13.0
Requires-Dist: uv-build>=0.13.1
Requires-Python: >=3.14
Description-Content-Type: text/markdown

# YapPy

**A Python API binding for Yapper.**

YapPy brings a Python-friendly interface to [Yapper](https://yapper.website), a chat platform similar to Discord. It provides familiar models, event handlers, and command decorators so you can build Yapper bots with straightforward asynchronous Python.

> **Project status:** Early development. The current implementation includes `Context`, `Message`, `Channel`, and `User` models, along with bot event and command handling. The API may change as development continues.

## Features

- **Python-first API** — build bot logic using async functions and decorators.
- **Event handlers** — respond to Yapper events such as incoming messages.
- **Commands** — register named commands with descriptions.
- **Context-based interactions** — reply to messages through a context object.
- **Core models** — work with `Context`, `Message`, `Channel`, and `User` objects.
- **Argument validation** — type-hinted command parameters are converted for you, and mistakes get a helpful reply.
- **Rich logging** — coloured logs and readable tracebacks; `verbose=True` adds debug output.

## Installation


```bash
pip install python-yappy
```

## Quick start

This example uses the dotenv module from `pip install load_dotenv`
Create a file named `main.py`:

```python
from yappy import App
import os
from dotenv import load_dotenv
load_dotenv()
bot = App(verbose=True)
@bot.event(
	"message"
)
async def on_message(ctx):
	if ctx.is_bot:
		return
	await bot.process_command(ctx)
@bot.command(
	name="ping",
    description="replies with 'Pong!'"
)
async def ping(ctx):
	await ctx.reply("Pong!")	

@bot.command(
	name="react",
	description="React your message with a certain emoji!"
)
async def react(ctx, emoji: str):
	await ctx.message.react(emoji)
@bot.event(
	"ready"
)
async def on_ready():
	print("Logged as", bot.user.name)

bot.run(os.getenv("TOKEN"))
```

Create a `.env` file beside `bot.py`:

```dotenv
TOKEN=your_yapper_bot_token
```

Then run the bot:

```bash
python bot.py
```

This example registers a `message` event that replies with `Hi!` to messages not sent by bots, and a `ping` command that replies with `Pong!`.

**Keep your token private.** Do not commit your `.env` file or publish your bot token.

## Core concepts

### `App`

`App` is the main entry point for creating and running a YapPy bot.

```python
from yappy import App

bot = App(verbose=True)
bot.run("YOUR_TOKEN")
```

Set `verbose=True` to enable verbose output while developing. Keep credentials in environment variables rather than hard-coding them in source files.

### Events

Register an event handler with `@bot.event(...)`. Event handlers are asynchronous functions.

```python
@bot.event("message")
async def on_message(ctx):
    if ctx.is_bot:
        return

    await bot.process_command(ctx)
```

The event name and handler arguments should match the event interface supported by the installed YapPy version.

### Commands

Register a command using `@bot.command(...)`:

```python
@bot.command(
    name="ping",
    description="replies with 'Pong!'",
)
async def ping(ctx):
    await ctx.reply("Pong!")
```

The `name` identifies the command, and `description` describes its purpose. Command registration and invocation behavior depend on the current implementation.

### Command arguments

Arguments from the message are matched to your function's parameters. Add type hints and YapPy converts them for you:

```python
@bot.command(name="add", description="Adds two numbers")
async def add(ctx, a: int, b: int = 0):
    await ctx.reply(f"{a} + {b} = {a + b}")
```

| Annotation | Accepts |
| --- | --- |
| `str` | the text exactly as typed (use `"quotes"` for spaces) |
| `int`, `float` | numbers |
| `bool` | `true`/`false`, `yes`/`no`, `on`/`off`, `1`/`0` |
| `User`, `Channel`, `Role` | a mention such as `<@123>` |
| *(none)* | guessed: whole numbers become `int`, decimals `float`, mentions are resolved, anything else is `str` |

Parameters with a default are optional, and `*args` collects any remaining arguments.

### Command errors

If someone uses a command the wrong way, the bot tells them instead of failing silently:

```text
!add
Missing required argument 'a'.
Usage: `!add <a> [b]`
```

Too many arguments and values of the wrong type are handled the same way. Unknown commands are ignored, and an exception raised inside a command is logged rather than sent to chat.

To handle these yourself, register a `command_error` handler. It replaces the default replies:

```python
from yappy import UnknownCommand

@bot.event("command_error")
async def on_command_error(ctx, error):
    if isinstance(error, UnknownCommand):
        return
    await ctx.reply(str(error))
```

`error` is one of `UnknownCommand`, `MissingArgument`, `TooManyArguments`, `BadArgument` or `CommandInvokeError` (all subclasses of `yappy.CommandError`). For `CommandInvokeError`, the exception your command raised is `error.original`, and `error.command` is the command involved.

### Logging

YapPy logs through Python's `logging` module under the name `yappy` and prints it with [Rich](https://github.com/Textualize/rich). Exceptions appear as readable tracebacks. `App(verbose=True)` also shows debug output: events, HTTP requests and command invocations.

To configure logging yourself, create the app with `configure_logging=False`:

```python
import logging
from yappy import App, setup_logging

bot = App(configure_logging=False)
setup_logging(level=logging.WARNING, show_locals=True)  # or attach your own handlers to logging.getLogger("yappy")
```

### Context and models

YapPy currently provides these core models:

| Model | Purpose |
| --- | --- |
| `Context` | Context for handling an interaction or message event. |
| `Message` | Represents a message. |
| `Channel` | Represents a channel. |
| `User` | Represents a user. |
| `Guild` | Represents a guild / server |
| `Role` | Represents a role |

The example uses the context object (`ctx`) to check `ctx.is_bot` and send a reply with `ctx.reply(...)`. Consult the source code for the currently available attributes and methods of each model.

## Project status

YapPy is under active development. Current implemented areas include:

- `Context`, `Message`, `Channel`, and `User` models
- Bot event registration and handling
- Command registration
- Message replies through the context API

Other features may be planned, incomplete, or unsupported. Check the source code and release notes for the actual capabilities of the version you are using.

## Contributing

Contributions, bug reports, and suggestions are welcome. Before opening a pull request, describe the change clearly and include a minimal reproduction or test where appropriate.

## License

This project is licensed under the MIT License.
