DiscordPYComponents 0.2.33__tar.gz → 1.0.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (27) hide show
  1. discordpycomponents-1.0.0/DiscordPYComponents.egg-info/PKG-INFO +257 -0
  2. discordpycomponents-1.0.0/PKG-INFO +257 -0
  3. discordpycomponents-1.0.0/README.md +245 -0
  4. discordpycomponents-1.0.0/py_components/__init__.py +73 -0
  5. discordpycomponents-1.0.0/py_components/components.py +556 -0
  6. discordpycomponents-1.0.0/py_components/enums.py +55 -0
  7. discordpycomponents-1.0.0/py_components/http.py +88 -0
  8. discordpycomponents-1.0.0/py_components/registry.py +43 -0
  9. discordpycomponents-1.0.0/py_components/ui.py +134 -0
  10. discordpycomponents-1.0.0/py_components/view.py +102 -0
  11. discordpycomponents-1.0.0/pyproject.toml +17 -0
  12. discordpycomponents-0.2.33/DiscordPYComponents.egg-info/PKG-INFO +0 -68
  13. discordpycomponents-0.2.33/PKG-INFO +0 -68
  14. discordpycomponents-0.2.33/README.md +0 -60
  15. discordpycomponents-0.2.33/py_components/__init__.py +0 -4
  16. discordpycomponents-0.2.33/py_components/components.py +0 -26
  17. discordpycomponents-0.2.33/py_components/enums.py +0 -5
  18. discordpycomponents-0.2.33/py_components/http.py +0 -15
  19. discordpycomponents-0.2.33/py_components/registry.py +0 -10
  20. discordpycomponents-0.2.33/py_components/ui.py +0 -48
  21. discordpycomponents-0.2.33/py_components/view.py +0 -33
  22. discordpycomponents-0.2.33/pyproject.toml +0 -11
  23. {discordpycomponents-0.2.33 → discordpycomponents-1.0.0}/DiscordPYComponents.egg-info/SOURCES.txt +0 -0
  24. {discordpycomponents-0.2.33 → discordpycomponents-1.0.0}/DiscordPYComponents.egg-info/dependency_links.txt +0 -0
  25. {discordpycomponents-0.2.33 → discordpycomponents-1.0.0}/DiscordPYComponents.egg-info/requires.txt +0 -0
  26. {discordpycomponents-0.2.33 → discordpycomponents-1.0.0}/DiscordPYComponents.egg-info/top_level.txt +0 -0
  27. {discordpycomponents-0.2.33 → discordpycomponents-1.0.0}/setup.cfg +0 -0
@@ -0,0 +1,257 @@
1
+ Metadata-Version: 2.4
2
+ Name: DiscordPYComponents
3
+ Version: 1.0.0
4
+ Summary: Discord Components V2 for discord.py — full layout, content and interactive components
5
+ Author: 2gm49
6
+ License: MIT
7
+ Project-URL: Homepage, https://pypi.org/project/DiscordPYComponents/
8
+ Project-URL: Documentation, https://docs.discord.com/developers/components/overview
9
+ Requires-Python: >=3.10
10
+ Description-Content-Type: text/markdown
11
+ Requires-Dist: aiohttp
12
+
13
+ # DiscordPYComponents
14
+
15
+ **Discord Components V2 for discord.py** — a lightweight helper library for building rich, interactive messages with the modern Components V2 system.
16
+
17
+ > **Requires the `IS_COMPONENTS_V2` flag (`1 << 15`).**
18
+ > When this flag is set, traditional `content` and `embeds` are disabled; all content must be sent as components.
19
+
20
+ PyPI: https://pypi.org/project/DiscordPYComponents/
21
+
22
+ Official Discord docs:
23
+ - [Components Overview](https://docs.discord.com/developers/components/overview)
24
+ - [Using Message Components](https://docs.discord.com/developers/components/using-message-components)
25
+ - [Component Reference](https://docs.discord.com/developers/components/reference)
26
+
27
+ ## Installation
28
+
29
+ ```bash
30
+ pip install DiscordPYComponents
31
+ ```
32
+
33
+ ## Requirements
34
+
35
+ - Python 3.10+
36
+ - discord.py (or any library that gives you a bot token + channel/interaction)
37
+ - aiohttp
38
+
39
+ ## Quick start
40
+
41
+ ```python
42
+ from py_components import (
43
+ UI, TextDisplay, Button, ButtonStyle, Container, Separator, Section, Thumbnail
44
+ )
45
+
46
+ @bot.command()
47
+ async def menu(ctx):
48
+ ui = UI(
49
+ TextDisplay("# Welcome"),
50
+ TextDisplay("Choose an option below:"),
51
+ Button("Confirm", custom_id="confirm", style=ButtonStyle.SUCCESS),
52
+ Button("Cancel", custom_id="cancel", style=ButtonStyle.DANGER),
53
+ )
54
+ await ui.send(ctx)
55
+ ```
56
+
57
+ ## Component types
58
+
59
+ ### Content components
60
+
61
+ | Class | Type | Description |
62
+ |-------|------|-------------|
63
+ | `TextDisplay` / `Text` | 10 | Markdown text (1–4000 chars) |
64
+ | `Thumbnail` | 11 | Small image (Section accessory only) |
65
+ | `MediaGallery` | 12 | 1–10 images / media items |
66
+ | `File` | 13 | Displays an uploaded attachment |
67
+
68
+ ### Layout components
69
+
70
+ | Class | Type | Description |
71
+ |-------|------|-------------|
72
+ | `ActionRow` | 1 | Holds up to 5 Buttons **or** one Select menu |
73
+ | `Section` | 9 | 1–3 TextDisplays + optional accessory (Button or Thumbnail) |
74
+ | `Separator` | 14 | Vertical padding / visual divider |
75
+ | `Container` | 17 | Groups children with optional accent colour bar |
76
+
77
+ ### Interactive components
78
+
79
+ | Class | Type | Description |
80
+ |-------|------|-------------|
81
+ | `Button` | 2 | Clickable button |
82
+ | `StringSelect` | 3 | Dropdown of string options |
83
+ | `UserSelect` | 5 | Select users |
84
+ | `RoleSelect` | 6 | Select roles |
85
+ | `MentionableSelect` | 7 | Select users **or** roles |
86
+ | `ChannelSelect` | 8 | Select channels |
87
+
88
+ ## Button styles
89
+
90
+ | Style | Value | Colour / behaviour |
91
+ |-------|-------|--------------------|
92
+ | `ButtonStyle.PRIMARY` | 1 | Blurple |
93
+ | `ButtonStyle.SECONDARY` | 2 | Grey |
94
+ | `ButtonStyle.SUCCESS` | 3 | Green |
95
+ | `ButtonStyle.DANGER` | 4 | Red |
96
+ | `ButtonStyle.LINK` | 5 | Grey – opens a URL (requires `url=`) |
97
+ | `ButtonStyle.PREMIUM` | 6 | Blurple – requires `sku_id=` |
98
+
99
+ ```python
100
+ Button("Click me", custom_id="btn1", style=ButtonStyle.PRIMARY)
101
+ Button("Docs", style=ButtonStyle.LINK, url="https://discord.com/developers/docs")
102
+ Button("Buy", style=ButtonStyle.PREMIUM, sku_id="1234567890")
103
+ ```
104
+
105
+ ## Building a rich layout
106
+
107
+ ```python
108
+ from py_components import (
109
+ UI, Container, TextDisplay, Section, Thumbnail,
110
+ Separator, SeparatorSpacing, MediaGallery, Button, ButtonStyle
111
+ )
112
+
113
+ ui = UI(
114
+ Container(
115
+ TextDisplay("# Server Status"),
116
+ Separator(divider=True, spacing=SeparatorSpacing.SMALL),
117
+ Section(
118
+ TextDisplay("**Online** — 1 204 members"),
119
+ TextDisplay("Peak today: 312"),
120
+ accessory=Thumbnail("https://cdn.discordapp.com/icons/.../icon.png"),
121
+ ),
122
+ Separator(),
123
+ MediaGallery(
124
+ "https://example.com/chart1.png",
125
+ "https://example.com/chart2.png",
126
+ ),
127
+ accent_color=0x5865F2, # Discord blurple
128
+ ),
129
+ Button("Refresh", custom_id="refresh", style=ButtonStyle.PRIMARY),
130
+ )
131
+ await ui.send(ctx)
132
+ ```
133
+
134
+ Top-level components can be mixed freely. The `UI` class automatically wraps loose `Button`s into `ActionRow`s (max 5 per row). Place select menus inside an explicit `ActionRow` yourself:
135
+
136
+ ```python
137
+ from py_components import ActionRow, StringSelect, SelectOption
138
+
139
+ ui = UI(
140
+ TextDisplay("Pick a colour:"),
141
+ ActionRow(
142
+ StringSelect(
143
+ custom_id="colour",
144
+ options=[
145
+ SelectOption("Red", "red"),
146
+ SelectOption("Green", "green"),
147
+ SelectOption("Blue", "blue"),
148
+ ],
149
+ placeholder="Choose…",
150
+ )
151
+ ),
152
+ )
153
+ ```
154
+
155
+ ## View & callbacks
156
+
157
+ ```python
158
+ from py_components import View, ButtonStyle
159
+
160
+ view = View()
161
+
162
+ async def on_confirm(interaction):
163
+ await interaction.response.send_message("Confirmed!", ephemeral=True)
164
+
165
+ view.add_button("Confirm", custom_id="confirm", style=ButtonStyle.SUCCESS, callback=on_confirm)
166
+ view.add_button("Cancel", custom_id="cancel", style=ButtonStyle.SECONDARY)
167
+
168
+ # Send the payload yourself or combine with UI
169
+ payload = view.to_payload()
170
+ ```
171
+
172
+ You can also use the decorator helper:
173
+
174
+ ```python
175
+ from py_components import button, View
176
+
177
+ @button("Click Me", custom_id="my_btn")
178
+ async def on_click(interaction):
179
+ await interaction.response.send_message("Clicked!")
180
+ ```
181
+
182
+ ## Global registry
183
+
184
+ ```python
185
+ from py_components import default_registry
186
+
187
+ @default_registry.route("confirm")
188
+ async def handle_confirm(interaction):
189
+ await interaction.response.send_message("OK")
190
+
191
+ # Later, in your interaction listener:
192
+ await default_registry.dispatch(interaction.data["custom_id"], interaction)
193
+ ```
194
+
195
+ ## File attachments
196
+
197
+ Upload the file with the message and reference it with the `File` component:
198
+
199
+ ```python
200
+ from py_components import UI, File, TextDisplay
201
+
202
+ ui = UI(
203
+ TextDisplay("Here is the report:"),
204
+ File("report.pdf"), # becomes attachment://report.pdf
205
+ )
206
+
207
+ # When calling the raw HTTP helper you would also pass the file bytes;
208
+ # with discord.py you can combine the payload with files=...
209
+ await ui.send(ctx)
210
+ ```
211
+
212
+ ## Responding to interactions
213
+
214
+ ```python
215
+ @bot.event
216
+ async def on_interaction(interaction):
217
+ if interaction.type.name == "component":
218
+ custom_id = interaction.data.get("custom_id")
219
+ # … route to your callbacks …
220
+ # or reply with a new V2 message:
221
+ ui = UI(TextDisplay(f"You pressed `{custom_id}`"))
222
+ await ui.reply(interaction, ephemeral=True)
223
+ ```
224
+
225
+ ## Payload shape
226
+
227
+ Every payload produced by this library looks like:
228
+
229
+ ```json
230
+ {
231
+ "flags": 32768,
232
+ "components": [
233
+ { "type": 10, "content": "Hello" },
234
+ {
235
+ "type": 1,
236
+ "components": [
237
+ { "type": 2, "style": 1, "label": "OK", "custom_id": "ok" }
238
+ ]
239
+ }
240
+ ]
241
+ }
242
+ ```
243
+
244
+ You can also obtain the dict with `ui.to_payload()` / `view.to_payload()` and send it through any HTTP client or discord.py’s low-level methods.
245
+
246
+ ## Limitations (Discord-side)
247
+
248
+ - Once a message is sent with `IS_COMPONENTS_V2` the flag cannot be removed.
249
+ - `content`, `embeds`, `stickers` and `poll` are disabled on V2 messages.
250
+ - Attachments only appear when referenced by a `File` or media component.
251
+ - Max 40 components per message.
252
+ - Buttons must live in an ActionRow (or as a Section accessory).
253
+ - Only one select menu per ActionRow.
254
+
255
+ ## License
256
+
257
+ MIT
@@ -0,0 +1,257 @@
1
+ Metadata-Version: 2.4
2
+ Name: DiscordPYComponents
3
+ Version: 1.0.0
4
+ Summary: Discord Components V2 for discord.py — full layout, content and interactive components
5
+ Author: 2gm49
6
+ License: MIT
7
+ Project-URL: Homepage, https://pypi.org/project/DiscordPYComponents/
8
+ Project-URL: Documentation, https://docs.discord.com/developers/components/overview
9
+ Requires-Python: >=3.10
10
+ Description-Content-Type: text/markdown
11
+ Requires-Dist: aiohttp
12
+
13
+ # DiscordPYComponents
14
+
15
+ **Discord Components V2 for discord.py** — a lightweight helper library for building rich, interactive messages with the modern Components V2 system.
16
+
17
+ > **Requires the `IS_COMPONENTS_V2` flag (`1 << 15`).**
18
+ > When this flag is set, traditional `content` and `embeds` are disabled; all content must be sent as components.
19
+
20
+ PyPI: https://pypi.org/project/DiscordPYComponents/
21
+
22
+ Official Discord docs:
23
+ - [Components Overview](https://docs.discord.com/developers/components/overview)
24
+ - [Using Message Components](https://docs.discord.com/developers/components/using-message-components)
25
+ - [Component Reference](https://docs.discord.com/developers/components/reference)
26
+
27
+ ## Installation
28
+
29
+ ```bash
30
+ pip install DiscordPYComponents
31
+ ```
32
+
33
+ ## Requirements
34
+
35
+ - Python 3.10+
36
+ - discord.py (or any library that gives you a bot token + channel/interaction)
37
+ - aiohttp
38
+
39
+ ## Quick start
40
+
41
+ ```python
42
+ from py_components import (
43
+ UI, TextDisplay, Button, ButtonStyle, Container, Separator, Section, Thumbnail
44
+ )
45
+
46
+ @bot.command()
47
+ async def menu(ctx):
48
+ ui = UI(
49
+ TextDisplay("# Welcome"),
50
+ TextDisplay("Choose an option below:"),
51
+ Button("Confirm", custom_id="confirm", style=ButtonStyle.SUCCESS),
52
+ Button("Cancel", custom_id="cancel", style=ButtonStyle.DANGER),
53
+ )
54
+ await ui.send(ctx)
55
+ ```
56
+
57
+ ## Component types
58
+
59
+ ### Content components
60
+
61
+ | Class | Type | Description |
62
+ |-------|------|-------------|
63
+ | `TextDisplay` / `Text` | 10 | Markdown text (1–4000 chars) |
64
+ | `Thumbnail` | 11 | Small image (Section accessory only) |
65
+ | `MediaGallery` | 12 | 1–10 images / media items |
66
+ | `File` | 13 | Displays an uploaded attachment |
67
+
68
+ ### Layout components
69
+
70
+ | Class | Type | Description |
71
+ |-------|------|-------------|
72
+ | `ActionRow` | 1 | Holds up to 5 Buttons **or** one Select menu |
73
+ | `Section` | 9 | 1–3 TextDisplays + optional accessory (Button or Thumbnail) |
74
+ | `Separator` | 14 | Vertical padding / visual divider |
75
+ | `Container` | 17 | Groups children with optional accent colour bar |
76
+
77
+ ### Interactive components
78
+
79
+ | Class | Type | Description |
80
+ |-------|------|-------------|
81
+ | `Button` | 2 | Clickable button |
82
+ | `StringSelect` | 3 | Dropdown of string options |
83
+ | `UserSelect` | 5 | Select users |
84
+ | `RoleSelect` | 6 | Select roles |
85
+ | `MentionableSelect` | 7 | Select users **or** roles |
86
+ | `ChannelSelect` | 8 | Select channels |
87
+
88
+ ## Button styles
89
+
90
+ | Style | Value | Colour / behaviour |
91
+ |-------|-------|--------------------|
92
+ | `ButtonStyle.PRIMARY` | 1 | Blurple |
93
+ | `ButtonStyle.SECONDARY` | 2 | Grey |
94
+ | `ButtonStyle.SUCCESS` | 3 | Green |
95
+ | `ButtonStyle.DANGER` | 4 | Red |
96
+ | `ButtonStyle.LINK` | 5 | Grey – opens a URL (requires `url=`) |
97
+ | `ButtonStyle.PREMIUM` | 6 | Blurple – requires `sku_id=` |
98
+
99
+ ```python
100
+ Button("Click me", custom_id="btn1", style=ButtonStyle.PRIMARY)
101
+ Button("Docs", style=ButtonStyle.LINK, url="https://discord.com/developers/docs")
102
+ Button("Buy", style=ButtonStyle.PREMIUM, sku_id="1234567890")
103
+ ```
104
+
105
+ ## Building a rich layout
106
+
107
+ ```python
108
+ from py_components import (
109
+ UI, Container, TextDisplay, Section, Thumbnail,
110
+ Separator, SeparatorSpacing, MediaGallery, Button, ButtonStyle
111
+ )
112
+
113
+ ui = UI(
114
+ Container(
115
+ TextDisplay("# Server Status"),
116
+ Separator(divider=True, spacing=SeparatorSpacing.SMALL),
117
+ Section(
118
+ TextDisplay("**Online** — 1 204 members"),
119
+ TextDisplay("Peak today: 312"),
120
+ accessory=Thumbnail("https://cdn.discordapp.com/icons/.../icon.png"),
121
+ ),
122
+ Separator(),
123
+ MediaGallery(
124
+ "https://example.com/chart1.png",
125
+ "https://example.com/chart2.png",
126
+ ),
127
+ accent_color=0x5865F2, # Discord blurple
128
+ ),
129
+ Button("Refresh", custom_id="refresh", style=ButtonStyle.PRIMARY),
130
+ )
131
+ await ui.send(ctx)
132
+ ```
133
+
134
+ Top-level components can be mixed freely. The `UI` class automatically wraps loose `Button`s into `ActionRow`s (max 5 per row). Place select menus inside an explicit `ActionRow` yourself:
135
+
136
+ ```python
137
+ from py_components import ActionRow, StringSelect, SelectOption
138
+
139
+ ui = UI(
140
+ TextDisplay("Pick a colour:"),
141
+ ActionRow(
142
+ StringSelect(
143
+ custom_id="colour",
144
+ options=[
145
+ SelectOption("Red", "red"),
146
+ SelectOption("Green", "green"),
147
+ SelectOption("Blue", "blue"),
148
+ ],
149
+ placeholder="Choose…",
150
+ )
151
+ ),
152
+ )
153
+ ```
154
+
155
+ ## View & callbacks
156
+
157
+ ```python
158
+ from py_components import View, ButtonStyle
159
+
160
+ view = View()
161
+
162
+ async def on_confirm(interaction):
163
+ await interaction.response.send_message("Confirmed!", ephemeral=True)
164
+
165
+ view.add_button("Confirm", custom_id="confirm", style=ButtonStyle.SUCCESS, callback=on_confirm)
166
+ view.add_button("Cancel", custom_id="cancel", style=ButtonStyle.SECONDARY)
167
+
168
+ # Send the payload yourself or combine with UI
169
+ payload = view.to_payload()
170
+ ```
171
+
172
+ You can also use the decorator helper:
173
+
174
+ ```python
175
+ from py_components import button, View
176
+
177
+ @button("Click Me", custom_id="my_btn")
178
+ async def on_click(interaction):
179
+ await interaction.response.send_message("Clicked!")
180
+ ```
181
+
182
+ ## Global registry
183
+
184
+ ```python
185
+ from py_components import default_registry
186
+
187
+ @default_registry.route("confirm")
188
+ async def handle_confirm(interaction):
189
+ await interaction.response.send_message("OK")
190
+
191
+ # Later, in your interaction listener:
192
+ await default_registry.dispatch(interaction.data["custom_id"], interaction)
193
+ ```
194
+
195
+ ## File attachments
196
+
197
+ Upload the file with the message and reference it with the `File` component:
198
+
199
+ ```python
200
+ from py_components import UI, File, TextDisplay
201
+
202
+ ui = UI(
203
+ TextDisplay("Here is the report:"),
204
+ File("report.pdf"), # becomes attachment://report.pdf
205
+ )
206
+
207
+ # When calling the raw HTTP helper you would also pass the file bytes;
208
+ # with discord.py you can combine the payload with files=...
209
+ await ui.send(ctx)
210
+ ```
211
+
212
+ ## Responding to interactions
213
+
214
+ ```python
215
+ @bot.event
216
+ async def on_interaction(interaction):
217
+ if interaction.type.name == "component":
218
+ custom_id = interaction.data.get("custom_id")
219
+ # … route to your callbacks …
220
+ # or reply with a new V2 message:
221
+ ui = UI(TextDisplay(f"You pressed `{custom_id}`"))
222
+ await ui.reply(interaction, ephemeral=True)
223
+ ```
224
+
225
+ ## Payload shape
226
+
227
+ Every payload produced by this library looks like:
228
+
229
+ ```json
230
+ {
231
+ "flags": 32768,
232
+ "components": [
233
+ { "type": 10, "content": "Hello" },
234
+ {
235
+ "type": 1,
236
+ "components": [
237
+ { "type": 2, "style": 1, "label": "OK", "custom_id": "ok" }
238
+ ]
239
+ }
240
+ ]
241
+ }
242
+ ```
243
+
244
+ You can also obtain the dict with `ui.to_payload()` / `view.to_payload()` and send it through any HTTP client or discord.py’s low-level methods.
245
+
246
+ ## Limitations (Discord-side)
247
+
248
+ - Once a message is sent with `IS_COMPONENTS_V2` the flag cannot be removed.
249
+ - `content`, `embeds`, `stickers` and `poll` are disabled on V2 messages.
250
+ - Attachments only appear when referenced by a `File` or media component.
251
+ - Max 40 components per message.
252
+ - Buttons must live in an ActionRow (or as a Section accessory).
253
+ - Only one select menu per ActionRow.
254
+
255
+ ## License
256
+
257
+ MIT