A library provides declarative ui for discord.py
Project description
ductile-ui
A library provides declarative UI for discord.py.
Features
- Declarative UI, inspired by React.
- Component-oriented with State
- Fully typed
Installation
Python3.10 or higher is required
discord.py^2.2.0 is required; any compatibility under 2.1.x or 1.x is not guaranteed
Using the latest stable release of discord.py is recommended
pip install ductile-ui
Usage/Examples
You can define component as return value of View.render()
.
To store state, use State
.
# This example requires the 'message_content' privileged intent to function.
import random
import discord
from discord.ext import commands
from ductile import State, View, ViewObject
from ductile.controller import MessageableController
from ductile.ui import Button
class Bot(commands.Bot):
def __init__(self) -> None:
super().__init__(command_prefix="!", intents=discord.Intents.all())
async def on_ready(self) -> None:
print(f"Logged in as {self.user}")
print("Ready!")
class CounterView(View):
def __init__(self) -> None:
super().__init__()
self.count = State(0, self)
def render(self) -> ViewObject:
e = discord.Embed(title="Counter", description=f"Count: {self.count.get_state()}")
async def handle_increment(interaction: discord.Interaction) -> None:
await interaction.response.defer()
self.count.set_state(lambda x: x + 1)
async def handle_decrement(interaction: discord.Interaction) -> None:
await interaction.response.defer()
self.count.set_state(lambda x: x - 1)
async def stop(interaction: discord.Interaction) -> None:
await interaction.response.defer()
self.stop()
# Define UI using ViewObject
return ViewObject(
embeds=[e],
components=[
Button("+1", style={"color": "blurple", "row": 0}, on_click=handle_increment),
Button("-1", style={"color": "blurple", "row": 0}, on_click=handle_decrement),
Button(
"random",
style={"color": "green", "row": 1},
# if you passed synchronous function to Button.on_click,
# library automatically calls `await interaction.response.defer()`.
on_click=lambda _: self.count.set_state(random.randint(0, 100)),
),
Button("stop", style={"color": "red", "row": 1}, on_click=stop),
],
)
bot = Bot()
@bot.command(name="counter")
async def send_counter(ctx: commands.Context) -> None:
controller = MessageableController(CounterView(), messageable=ctx.channel)
await controller.send()
timed_out, states = await controller.wait()
await ctx.send(f"Timed out: {timed_out}\nCount: {states['count']}")
bot.run("MY_COOL_BOT_TOKEN")
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
ductile_ui-0.4.0.tar.gz
(58.8 kB
view details)
Built Distribution
File details
Details for the file ductile_ui-0.4.0.tar.gz
.
File metadata
- Download URL: ductile_ui-0.4.0.tar.gz
- Upload date:
- Size: 58.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.5.1
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 7c4a85773bafb964abd989873d0d8fdafb527455d14653a15bb03e65726a42c9 |
|
MD5 | aa11f6e090e2f605d08715c92751fd59 |
|
BLAKE2b-256 | 5642e2c648dc67b155e8c044212b5ba08d7a454343da127144cb1338d739b806 |
File details
Details for the file ductile_ui-0.4.0-py3-none-any.whl
.
File metadata
- Download URL: ductile_ui-0.4.0-py3-none-any.whl
- Upload date:
- Size: 22.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.5.1
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | cc47758700c8e716d8a81f935f5e5e4810ef8206efa565a1bbb857528107f895 |
|
MD5 | 5abb75e34762ee886d8cf725ec575d90 |
|
BLAKE2b-256 | 27283f2eec0a7c67838b7e331c5c19290615cffce53f40b80c6a5a877b4753e6 |