banterbotapi
Python SDK for building bots on Banter.
pip install banterbotapi
Install name is banterbotapi, import name is banterapi (same pattern as Pillow/PIL).
Quick start
from banterapi import Bot, Intents
bot = Bot(intents=Intents.default() | Intents.MESSAGE_CONTENT)
@bot.event
async def on_ready():
print(f"logged in as {bot.user.username}")
@bot.event
async def on_message(message):
if message.content == "!ping":
await message.reply("pong")
bot.run("YOUR_TOKEN")
Slash commands
from banterapi import SlashOption, Optional, OPTION_STRING, OPTION_INTEGER
@bot.slash_command(
name="roll",
description="Roll an N-sided die",
options=[Optional("sides", type=OPTION_INTEGER, description="default 6")],
)
async def roll(interaction):
sides = interaction.options.get("sides", 6)
await interaction.respond(f"🎲 {sides}-sided die")
Optional(name, ...) is a shorthand for SlashOption(name, ..., required=False).
Response methods on interaction:
| Method | Use for |
|---|---|
respond(content, embed=, ephemeral=, components=) |
The visible reply. Once per interaction. |
defer(ephemeral=) |
Ack now, reply within 15 minutes. Shows a thinking indicator. |
followup(content, embed=, ...) |
Additional messages after respond. Repeatable. |
update(content, embed=, components=) |
Button only. Edits the source message in place. |
ephemeral=True makes the message visible only to the invoker.
Buttons
Attach buttons to any embed and handle clicks with @bot.on_button.
from banterapi import Embed
@bot.slash_command(name="confirm", description="Confirm or cancel")
async def confirm(interaction):
embed = Embed(title="Are you sure?")
embed.add_button("Yes", style="success", custom_id="confirm_yes")
embed.add_button("No", style="danger", custom_id="confirm_no")
await interaction.respond(embed=embed, ephemeral=True)
@bot.on_button("confirm_yes")
async def yes(interaction):
await interaction.update(content="Confirmed.", components=[])
@bot.on_button("confirm_no")
async def no(interaction):
await interaction.update(content="Cancelled.", components=[])
Glob match a family of buttons with a trailing * — useful for pagination where the page number rides in the id:
@bot.on_button("page_*")
async def page(interaction):
n = int(interaction.custom_id.removeprefix("page_"))
await interaction.update(embed=build_page(n))
add_button(label, style=, custom_id=, url=, emoji=, disabled=) — styles are primary, secondary, success, danger, link. link requires url; everything else needs custom_id to fire a handler. Up to 5 buttons per row, up to 5 rows per message.
Buttons work everywhere a message goes: bot.send_message(...), message.reply(...), interaction.respond(...), interaction.followup(...), interaction.update(...).
Embeds
embed = Embed(title="Status", description="All systems nominal.", color=0x57F287)
embed.add_field("Uptime", "12d 4h", inline=True)
embed.add_field("Users", "1,204", inline=True)
embed.set_footer("Last checked just now")
embed.set_thumbnail("https://example.com/icon.png")
await message.channel.send(embed=embed)
Color accepts an int (0x5865F2) or a CSS hex string ("#5865f2").
Events
@bot.event
async def on_ready(): ...
@bot.event
async def on_message(message): ...
@bot.event
async def on_message_edit(before, after): ...
@bot.event
async def on_member_join(member): ...
@bot.event
async def on_reaction_add(reaction, user): ...
The full event list lives in client.py. Names follow discord.py conventions where they overlap.
Permissions
from banterapi import Permissions, has_permissions
@bot.slash_command(name="ban", description="Ban a user")
@has_permissions(Permissions.BAN_MEMBERS)
async def ban(interaction): ...
Permissions is a flag enum. Combine with |, check with &. Decorators raise MissingPermissions which the bot can catch in an on_error handler.
Intents
intents = Intents.default() | Intents.MESSAGE_CONTENT
bot = Bot(intents=intents)
Intents.default() covers the common cases (guilds, members, messages without content, reactions). Add MESSAGE_CONTENT to receive message text in on_message.
Sending files
from banterapi import File
await message.channel.send(content="Here's the report.", file=File("report.pdf"))
await message.channel.send(files=[File("a.png"), File("b.png")])
Error handling
from banterapi import Forbidden, NotFound, RateLimited
try:
await message.channel.send("hi")
except Forbidden:
pass # bot lacks permission
except RateLimited as e:
await asyncio.sleep(e.retry_after)
Base class is BanterError; HTTP-specific errors inherit from HTTPException.
pip install banterbotapi
```python
from banterapi import Bot, Intents
bot = Bot(intents=Intents.default() | Intents.MESSAGE_CONTENT)
bot.run("YOUR_TOKEN")
Install name is banterbotapi, import name is banterapi (same pattern as Pillow/PIL).
Metadata
Release files for banterbotapi 1.0.43
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| banterbotapi-1.0.43.tar.gz | 25.2 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| banterbotapi-1.0.43-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 52.6 kB
Release files / banterbotapi-1.0.43.tar.gz
| Download URL | banterbotapi-1.0.43.tar.gz |
|---|---|
| Size | 25.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
3b75761eb9955cc8364233a807e9eb4e907507687743322a5231f2084c004e0c
|
|
BLAKE2b-256 checksum How to use checksums |
d24e393e322434e42761a3655e9acda557d567f509ad654bd41d274d5a1048ed
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.3
|
Release files / banterbotapi-1.0.43-py3-none-any.whl
| Download URL | banterbotapi-1.0.43-py3-none-any.whl |
|---|---|
| Size | 27.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
89e57b85eb954b22864721b9703198094e264382acf9822b67cb8a60bd4c54f6
|
|
BLAKE2b-256 checksum How to use checksums |
34832a26e7d4671670bf79a49985cc54ceff101be7c5b5397b95fc83d2f9c8b7
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.3
|
Security for banterbotapi 1.0.43
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.