scurrypy 0.3.2__tar.gz → 0.6.5__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 (86) hide show
  1. scurrypy-0.6.5/LICENSE +16 -0
  2. scurrypy-0.6.5/PKG-INFO +110 -0
  3. scurrypy-0.6.5/README.md +98 -0
  4. scurrypy-0.6.5/pyproject.toml +25 -0
  5. scurrypy-0.6.5/scurrypy/__init__.py +429 -0
  6. scurrypy-0.6.5/scurrypy/client.py +331 -0
  7. {scurrypy-0.3.2/discord → scurrypy-0.6.5/scurrypy}/client_like.py +8 -1
  8. scurrypy-0.6.5/scurrypy/dispatch/command_dispatcher.py +205 -0
  9. scurrypy-0.6.5/scurrypy/dispatch/event_dispatcher.py +96 -0
  10. {scurrypy-0.3.2/discord → scurrypy-0.6.5/scurrypy}/dispatch/prefix_dispatcher.py +31 -12
  11. {scurrypy-0.3.2/discord → scurrypy-0.6.5/scurrypy}/error.py +6 -18
  12. scurrypy-0.6.5/scurrypy/events/__init__.py +1 -0
  13. {scurrypy-0.3.2/discord → scurrypy-0.6.5/scurrypy}/events/channel_events.py +9 -2
  14. scurrypy-0.6.5/scurrypy/events/gateway_events.py +31 -0
  15. {scurrypy-0.3.2/discord → scurrypy-0.6.5/scurrypy}/events/guild_events.py +4 -1
  16. {scurrypy-0.3.2/discord → scurrypy-0.6.5/scurrypy}/events/interaction_events.py +34 -17
  17. {scurrypy-0.3.2/discord → scurrypy-0.6.5/scurrypy}/events/message_events.py +12 -8
  18. {scurrypy-0.3.2/discord → scurrypy-0.6.5/scurrypy}/events/reaction_events.py +6 -6
  19. {scurrypy-0.3.2/discord → scurrypy-0.6.5/scurrypy}/events/ready_event.py +1 -3
  20. scurrypy-0.6.5/scurrypy/gateway.py +183 -0
  21. scurrypy-0.6.5/scurrypy/http.py +336 -0
  22. {scurrypy-0.3.2/discord → scurrypy-0.6.5/scurrypy}/intents.py +5 -7
  23. {scurrypy-0.3.2/discord → scurrypy-0.6.5/scurrypy}/logger.py +14 -60
  24. scurrypy-0.6.5/scurrypy/model.py +71 -0
  25. scurrypy-0.6.5/scurrypy/models.py +258 -0
  26. scurrypy-0.6.5/scurrypy/parts/__init__.py +2 -0
  27. scurrypy-0.6.5/scurrypy/parts/channel.py +42 -0
  28. scurrypy-0.6.5/scurrypy/parts/command.py +90 -0
  29. scurrypy-0.6.5/scurrypy/parts/components.py +224 -0
  30. scurrypy-0.6.5/scurrypy/parts/components_v2.py +144 -0
  31. scurrypy-0.6.5/scurrypy/parts/embed.py +83 -0
  32. scurrypy-0.6.5/scurrypy/parts/message.py +134 -0
  33. scurrypy-0.6.5/scurrypy/parts/modal.py +16 -0
  34. {scurrypy-0.3.2/discord → scurrypy-0.6.5/scurrypy}/parts/role.py +2 -14
  35. scurrypy-0.6.5/scurrypy/resources/__init__.py +1 -0
  36. {scurrypy-0.3.2/discord → scurrypy-0.6.5/scurrypy}/resources/application.py +1 -2
  37. {scurrypy-0.3.2/discord → scurrypy-0.6.5/scurrypy}/resources/bot_emojis.py +1 -1
  38. {scurrypy-0.3.2/discord → scurrypy-0.6.5/scurrypy}/resources/channel.py +9 -8
  39. {scurrypy-0.3.2/discord → scurrypy-0.6.5/scurrypy}/resources/guild.py +14 -16
  40. {scurrypy-0.3.2/discord → scurrypy-0.6.5/scurrypy}/resources/interaction.py +57 -36
  41. {scurrypy-0.3.2/discord → scurrypy-0.6.5/scurrypy}/resources/message.py +15 -16
  42. {scurrypy-0.3.2/discord → scurrypy-0.6.5/scurrypy}/resources/user.py +3 -4
  43. scurrypy-0.6.5/scurrypy.egg-info/PKG-INFO +110 -0
  44. scurrypy-0.6.5/scurrypy.egg-info/SOURCES.txt +50 -0
  45. scurrypy-0.6.5/scurrypy.egg-info/requires.txt +2 -0
  46. scurrypy-0.6.5/scurrypy.egg-info/top_level.txt +1 -0
  47. scurrypy-0.3.2/LICENSE +0 -5
  48. scurrypy-0.3.2/PKG-INFO +0 -85
  49. scurrypy-0.3.2/README.md +0 -75
  50. scurrypy-0.3.2/discord/__init__.py +0 -10
  51. scurrypy-0.3.2/discord/client.py +0 -349
  52. scurrypy-0.3.2/discord/dispatch/command_dispatcher.py +0 -163
  53. scurrypy-0.3.2/discord/dispatch/event_dispatcher.py +0 -91
  54. scurrypy-0.3.2/discord/events/__init__.py +0 -33
  55. scurrypy-0.3.2/discord/gateway.py +0 -175
  56. scurrypy-0.3.2/discord/http.py +0 -292
  57. scurrypy-0.3.2/discord/model.py +0 -90
  58. scurrypy-0.3.2/discord/models/__init__.py +0 -8
  59. scurrypy-0.3.2/discord/models/application.py +0 -37
  60. scurrypy-0.3.2/discord/models/emoji.py +0 -34
  61. scurrypy-0.3.2/discord/models/guild.py +0 -35
  62. scurrypy-0.3.2/discord/models/integration.py +0 -23
  63. scurrypy-0.3.2/discord/models/interaction.py +0 -26
  64. scurrypy-0.3.2/discord/models/member.py +0 -27
  65. scurrypy-0.3.2/discord/models/role.py +0 -53
  66. scurrypy-0.3.2/discord/models/user.py +0 -15
  67. scurrypy-0.3.2/discord/parts/__init__.py +0 -28
  68. scurrypy-0.3.2/discord/parts/action_row.py +0 -257
  69. scurrypy-0.3.2/discord/parts/attachment.py +0 -18
  70. scurrypy-0.3.2/discord/parts/channel.py +0 -20
  71. scurrypy-0.3.2/discord/parts/command.py +0 -102
  72. scurrypy-0.3.2/discord/parts/components_v2.py +0 -270
  73. scurrypy-0.3.2/discord/parts/embed.py +0 -154
  74. scurrypy-0.3.2/discord/parts/message.py +0 -179
  75. scurrypy-0.3.2/discord/parts/modal.py +0 -21
  76. scurrypy-0.3.2/discord/resources/__init__.py +0 -10
  77. scurrypy-0.3.2/pyproject.toml +0 -23
  78. scurrypy-0.3.2/scurrypy.egg-info/PKG-INFO +0 -85
  79. scurrypy-0.3.2/scurrypy.egg-info/SOURCES.txt +0 -57
  80. scurrypy-0.3.2/scurrypy.egg-info/top_level.txt +0 -1
  81. {scurrypy-0.3.2/discord → scurrypy-0.6.5/scurrypy}/config.py +0 -0
  82. {scurrypy-0.3.2/discord → scurrypy-0.6.5/scurrypy}/dispatch/__init__.py +0 -0
  83. {scurrypy-0.3.2/discord → scurrypy-0.6.5/scurrypy}/events/hello_event.py +0 -0
  84. {scurrypy-0.3.2/discord → scurrypy-0.6.5/scurrypy}/parts/component_types.py +0 -0
  85. {scurrypy-0.3.2 → scurrypy-0.6.5}/scurrypy.egg-info/dependency_links.txt +0 -0
  86. {scurrypy-0.3.2 → scurrypy-0.6.5}/setup.cfg +0 -0
scurrypy-0.6.5/LICENSE ADDED
@@ -0,0 +1,16 @@
1
+ Copyright (c) 2025 Furmissile. All rights reserved.
2
+
3
+ Permission is granted to view, use, modify, and distribute copies of this software
4
+ and its source code, provided that:
5
+
6
+ 1. Attribution to the original author, Furmissile, is preserved in all copies and
7
+ derivative works.
8
+ 2. The name "ScurryPy" and associated branding may not be used to promote derived
9
+ projects without explicit permission.
10
+ 3. This license and copyright notice must be included in all copies or substantial
11
+ portions of the software.
12
+ 4. This software is provided "as is", without warranty of any kind, express or
13
+ implied. The author assumes no liability for any damages arising from its use.
14
+
15
+ 5. This software may not be used for commercial purposes without written consent
16
+ from the author.
@@ -0,0 +1,110 @@
1
+ Metadata-Version: 2.4
2
+ Name: scurrypy
3
+ Version: 0.6.5
4
+ Summary: Dataclass-driven Discord API Wrapper in Python
5
+ Author: Furmissile
6
+ Requires-Python: >=3.10
7
+ Description-Content-Type: text/markdown
8
+ License-File: LICENSE
9
+ Requires-Dist: aiohttp>=3.8.0
10
+ Requires-Dist: websockets>=11.0.0
11
+ Dynamic: license-file
12
+
13
+ # __ScurryPy__
14
+
15
+ [![PyPI version](https://badge.fury.io/py/scurrypy.svg)](https://badge.fury.io/py/scurrypy)
16
+
17
+ A dataclass-driven Discord API wrapper in Python!
18
+
19
+ While this wrapper is mainly used for various squirrel-related shenanigans, it can also be used for more generic bot purposes.
20
+
21
+ ## Features
22
+ * Easy to extend
23
+ * Command, and event handling
24
+ * Unix shell-style wildcards for component routing
25
+ * Declarative style using decorators
26
+ * Supports both legacy and new features
27
+ * Respects Discord's rate limits
28
+ * No `__future__` hacks to avoid circular import
29
+ * Capable of sharding
30
+
31
+ ## Benchmarks
32
+ Not convinced ScurryPy has a place among top libraries? See the benchmarks below!
33
+
34
+ ### Test Environment
35
+
36
+ - **Python**: 3.11.6
37
+ - **OS**: Windows 11
38
+ - **Method**: New Python process per measurement
39
+ - **Tool**: See benchmarks folder
40
+
41
+ ### Results Summary
42
+
43
+ ```
44
+ Library Time (ms) Memory Δ (MB) Objects
45
+ --------------------------------------------------------
46
+ scurrypy 8.9 0.44 1417
47
+ hikari 1710.3 27.67 53658
48
+ discord 252.5 7.64 14099
49
+ disnake 185.9 6.31 12111
50
+ ```
51
+
52
+ *(See `benchmark.py` for how this test was done.)*
53
+
54
+ ## Getting Started
55
+
56
+ *Note: This section also appears in the documentation, but here are complete examples ready to use with your bot credentials.*
57
+
58
+ ### Installation
59
+
60
+ To install the ScurryPy package, run:
61
+
62
+ ```bash
63
+ pip install scurrypy
64
+ ```
65
+
66
+ ## Minimal Slash Command
67
+
68
+ The following demonstrates building and responding to a slash command.
69
+
70
+ ```py
71
+ import scurrypy
72
+
73
+ client = scurrypy.Client(
74
+ token='your-token',
75
+ application_id=APPLICATION_ID # your bot's application ID
76
+ )
77
+
78
+ @client.command(
79
+ scurrypy.SlashCommand('example', 'Demonstrate the minimal slash command!'),
80
+ GUILD_ID # must be a guild ID your bot is in
81
+ )
82
+ async def example(bot: scurrypy.Client, event: scurrypy.InteractionEvent):
83
+ await event.interaction.respond(f'Hello, {event.interaction.member.user.username}!')
84
+
85
+ client.run()
86
+ ```
87
+
88
+ ## Minimal Prefix Command (Legacy)
89
+
90
+ The following demonstrates building and responding to a message prefix command.
91
+
92
+ ```py
93
+ import scurrypy
94
+
95
+ client = scurrypy.Client(
96
+ token='your-token',
97
+ application_id=APPLICATION_ID, # your bot's application ID
98
+ intents=scurrypy.set_intents(message_content=True),
99
+ prefix='!' # your custom prefix
100
+ )
101
+
102
+ @client.prefix_command("ping")
103
+ async def on_ping(bot: scurrypy.Client, event: scurrypy.MessageCreateEvent):
104
+ await event.message.send("Pong!")
105
+
106
+ client.run()
107
+ ```
108
+
109
+ ## Like What You See?
110
+ Explore the full [documentation](https://furmissile.github.io/scurrypy) for more examples, guides, and API reference.
@@ -0,0 +1,98 @@
1
+ # __ScurryPy__
2
+
3
+ [![PyPI version](https://badge.fury.io/py/scurrypy.svg)](https://badge.fury.io/py/scurrypy)
4
+
5
+ A dataclass-driven Discord API wrapper in Python!
6
+
7
+ While this wrapper is mainly used for various squirrel-related shenanigans, it can also be used for more generic bot purposes.
8
+
9
+ ## Features
10
+ * Easy to extend
11
+ * Command, and event handling
12
+ * Unix shell-style wildcards for component routing
13
+ * Declarative style using decorators
14
+ * Supports both legacy and new features
15
+ * Respects Discord's rate limits
16
+ * No `__future__` hacks to avoid circular import
17
+ * Capable of sharding
18
+
19
+ ## Benchmarks
20
+ Not convinced ScurryPy has a place among top libraries? See the benchmarks below!
21
+
22
+ ### Test Environment
23
+
24
+ - **Python**: 3.11.6
25
+ - **OS**: Windows 11
26
+ - **Method**: New Python process per measurement
27
+ - **Tool**: See benchmarks folder
28
+
29
+ ### Results Summary
30
+
31
+ ```
32
+ Library Time (ms) Memory Δ (MB) Objects
33
+ --------------------------------------------------------
34
+ scurrypy 8.9 0.44 1417
35
+ hikari 1710.3 27.67 53658
36
+ discord 252.5 7.64 14099
37
+ disnake 185.9 6.31 12111
38
+ ```
39
+
40
+ *(See `benchmark.py` for how this test was done.)*
41
+
42
+ ## Getting Started
43
+
44
+ *Note: This section also appears in the documentation, but here are complete examples ready to use with your bot credentials.*
45
+
46
+ ### Installation
47
+
48
+ To install the ScurryPy package, run:
49
+
50
+ ```bash
51
+ pip install scurrypy
52
+ ```
53
+
54
+ ## Minimal Slash Command
55
+
56
+ The following demonstrates building and responding to a slash command.
57
+
58
+ ```py
59
+ import scurrypy
60
+
61
+ client = scurrypy.Client(
62
+ token='your-token',
63
+ application_id=APPLICATION_ID # your bot's application ID
64
+ )
65
+
66
+ @client.command(
67
+ scurrypy.SlashCommand('example', 'Demonstrate the minimal slash command!'),
68
+ GUILD_ID # must be a guild ID your bot is in
69
+ )
70
+ async def example(bot: scurrypy.Client, event: scurrypy.InteractionEvent):
71
+ await event.interaction.respond(f'Hello, {event.interaction.member.user.username}!')
72
+
73
+ client.run()
74
+ ```
75
+
76
+ ## Minimal Prefix Command (Legacy)
77
+
78
+ The following demonstrates building and responding to a message prefix command.
79
+
80
+ ```py
81
+ import scurrypy
82
+
83
+ client = scurrypy.Client(
84
+ token='your-token',
85
+ application_id=APPLICATION_ID, # your bot's application ID
86
+ intents=scurrypy.set_intents(message_content=True),
87
+ prefix='!' # your custom prefix
88
+ )
89
+
90
+ @client.prefix_command("ping")
91
+ async def on_ping(bot: scurrypy.Client, event: scurrypy.MessageCreateEvent):
92
+ await event.message.send("Pong!")
93
+
94
+ client.run()
95
+ ```
96
+
97
+ ## Like What You See?
98
+ Explore the full [documentation](https://furmissile.github.io/scurrypy) for more examples, guides, and API reference.
@@ -0,0 +1,25 @@
1
+ [build-system]
2
+ requires = ["setuptools>=61"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "scurrypy"
7
+ version = "0.6.5"
8
+
9
+ description = "Dataclass-driven Discord API Wrapper in Python"
10
+ readme = "README.md"
11
+ authors = [{ name = "Furmissile" }]
12
+ requires-python = ">=3.10"
13
+ dependencies = [
14
+ "aiohttp>=3.8.0",
15
+ "websockets>=11.0.0"
16
+ ]
17
+
18
+ [tool.setuptools]
19
+ packages = [
20
+ "scurrypy",
21
+ "scurrypy.dispatch",
22
+ "scurrypy.events",
23
+ "scurrypy.resources",
24
+ "scurrypy.parts"
25
+ ]
@@ -0,0 +1,429 @@
1
+ # scurrypy
2
+
3
+ import importlib
4
+ from typing import TYPE_CHECKING
5
+
6
+ __all__ = [
7
+ # top-level modules
8
+ "Logger", "Client", "Intents", "set_intents", "BaseConfig",
9
+
10
+ # events
11
+ "InteractionTypes", "ReadyEvent",
12
+ "ReactionAddEvent", "ReactionRemoveEvent", "ReactionRemoveEmojiEvent", "ReactionRemoveAllEvent",
13
+ "GuildCreateEvent", "GuildUpdateEvent", "GuildDeleteEvent",
14
+ "MessageCreateEvent", "MessageUpdateEvent", "MessageDeleteEvent",
15
+ "GuildChannelCreateEvent", "GuildChannelUpdateEvent", "GuildChannelDeleteEvent", "ChannelPinsUpdateEvent",
16
+ "InteractionEvent",
17
+
18
+ # models
19
+ "UserModel", "EmojiModel", "GuildModel", "ApplicationModel", "ReadyGuildModel", "IntegrationModel",
20
+ "InteractionCallbackDataModel", "InteractionCallbackModel", "MemberModel", "RoleColors", "RoleModel",
21
+
22
+ # parts
23
+ "ChannelTypes", "GuildChannel",
24
+ "CommandTypes", "CommandOptionTypes", "SlashCommand", "UserCommand", "MessageCommand",
25
+ "ComponentV2Types", "SectionPart", "TextDisplay", "Thumbnail", "MediaGalleryItem", "MediaGallery",
26
+ "File", "SeparatorTypes", "Separator", "ContainerPart", "Label",
27
+ "ComponentTypes", "ActionRowPart", "ButtonStyles", "Button", "SelectOption", "StringSelect",
28
+ "TextInputStyles", "TextInput", "DefaultValue", "UserSelect", "RoleSelect", "MentionableSelect",
29
+ "ChannelSelect",
30
+ "EmbedAuthor", "EmbedThumbnail", "EmbedField", "EmbedImage", "EmbedFooter", "EmbedPart",
31
+ "MessageFlags", "MessageReferenceTypes", "MessageReference", "Attachment", "MessagePart", "Role", "ModalPart",
32
+
33
+ # resources
34
+ "ApplicationFlags", "Application",
35
+ "BotEmojis",
36
+ "PinnedMessage", "Channel",
37
+ "Guild",
38
+ "InteractionCallbackTypes", "Interaction",
39
+ "Message",
40
+ "User",
41
+ ]
42
+
43
+ # For editor support / autocomplete
44
+ if TYPE_CHECKING:
45
+ from .logger import Logger
46
+ from .client import Client
47
+ from .intents import Intents, set_intents
48
+ from .config import BaseConfig
49
+
50
+ from .dispatch.command_dispatcher import InteractionTypes
51
+
52
+ # events
53
+ from .events.ready_event import ReadyEvent
54
+ from .events.reaction_events import (
55
+ ReactionAddEvent,
56
+ ReactionRemoveEvent,
57
+ ReactionRemoveEmojiEvent,
58
+ ReactionRemoveAllEvent,
59
+ )
60
+ from .events.guild_events import (
61
+ GuildCreateEvent,
62
+ GuildUpdateEvent,
63
+ GuildDeleteEvent,
64
+ )
65
+ from .events.message_events import (
66
+ MessageCreateEvent,
67
+ MessageUpdateEvent,
68
+ MessageDeleteEvent,
69
+ )
70
+ from .events.channel_events import (
71
+ GuildChannelCreateEvent,
72
+ GuildChannelUpdateEvent,
73
+ GuildChannelDeleteEvent,
74
+ ChannelPinsUpdateEvent,
75
+ )
76
+ from .events.interaction_events import InteractionEvent
77
+
78
+ # models
79
+ from .models import (
80
+ UserModel,
81
+ EmojiModel,
82
+ GuildModel,
83
+ ApplicationModel,
84
+ ReadyGuildModel,
85
+ IntegrationModel,
86
+ InteractionCallbackDataModel,
87
+ InteractionCallbackModel,
88
+ MemberModel,
89
+ RoleColors,
90
+ RoleModel
91
+ )
92
+
93
+ # parts
94
+ from .parts.channel import (
95
+ ChannelTypes,
96
+ GuildChannel
97
+ )
98
+
99
+ from .parts.command import (
100
+ CommandTypes,
101
+ CommandOptionTypes,
102
+ SlashCommand,
103
+ UserCommand,
104
+ MessageCommand
105
+ )
106
+
107
+ from .parts.components_v2 import (
108
+ ComponentV2Types,
109
+ SectionPart,
110
+ TextDisplay,
111
+ Thumbnail,
112
+ MediaGalleryItem,
113
+ MediaGallery,
114
+ File,
115
+ SeparatorTypes,
116
+ Separator,
117
+ ContainerPart,
118
+ Label
119
+ )
120
+
121
+ from .parts.components import (
122
+ ComponentTypes,
123
+ ActionRowPart,
124
+ ButtonStyles,
125
+ Button,
126
+ SelectOption,
127
+ StringSelect,
128
+ TextInputStyles,
129
+ TextInput,
130
+ DefaultValue,
131
+ # SelectMenu,
132
+ UserSelect,
133
+ RoleSelect,
134
+ MentionableSelect,
135
+ ChannelSelect
136
+ )
137
+
138
+ from .parts.embed import (
139
+ EmbedAuthor,
140
+ EmbedThumbnail,
141
+ EmbedField,
142
+ EmbedImage,
143
+ EmbedFooter,
144
+ EmbedPart
145
+ )
146
+
147
+ from .parts.message import (
148
+ MessageFlags,
149
+ # MessageFlagParams,
150
+ MessageReferenceTypes,
151
+ MessageReference,
152
+ Attachment,
153
+ MessagePart
154
+ )
155
+
156
+ from .parts.modal import ModalPart
157
+ from .parts.role import Role
158
+
159
+ # resources
160
+ from .resources.application import (
161
+ ApplicationFlags,
162
+ Application
163
+ )
164
+
165
+ from .resources.bot_emojis import BotEmojis
166
+
167
+ from .resources.channel import (
168
+ # MessagesFetchParams,
169
+ # PinsFetchParams,
170
+ # ThreadFromMessageParams,
171
+ PinnedMessage,
172
+ Channel
173
+ )
174
+
175
+ from .resources.guild import (
176
+ # FetchGuildMembersParams,
177
+ # FetchGuildParams,
178
+ Guild
179
+ )
180
+
181
+ from .resources.interaction import (
182
+ # InteractionDataTypes,
183
+ InteractionCallbackTypes,
184
+ Interaction
185
+ )
186
+
187
+ from .resources.message import Message
188
+
189
+ from .resources.user import (
190
+ # FetchUserGuildsParams,
191
+ User
192
+ )
193
+
194
+ _lazy_modules = [
195
+ # top-level modules
196
+ (
197
+ "scurrypy.logger",
198
+ [
199
+ "Logger"
200
+ ]
201
+ ),
202
+ (
203
+ "scurrypy.client",
204
+ [
205
+ "Client"
206
+ ]
207
+ ),
208
+ (
209
+ "scurrypy.intents",
210
+ [
211
+ "Intents",
212
+ "set_intents"
213
+ ]
214
+ ),
215
+ (
216
+ "scurrypy.config",
217
+ [
218
+ "BaseConfig"
219
+ ]
220
+ ),
221
+ (
222
+ "scurrypy.models",
223
+ [
224
+ "UserModel",
225
+ "EmojiModel",
226
+ "GuildModel",
227
+ "ApplicationModel",
228
+ "ReadyGuildModel",
229
+ "IntegrationModel",
230
+ "InteractionCallbackDataModel",
231
+ "InteractionCallbackModel",
232
+ "MemberModel",
233
+ "RoleColors",
234
+ "RoleModel"
235
+ ]
236
+ ),
237
+
238
+ # Events
239
+ (
240
+ "scurrypy.events.ready_event",
241
+ [
242
+ "ReadyEvent"
243
+ ]
244
+ ),
245
+ (
246
+ "scurrypy.events.reaction_events",
247
+ [
248
+ "ReactionAddEvent",
249
+ "ReactionRemoveEvent",
250
+ "ReactionRemoveEmojiEvent",
251
+ "ReactionRemoveAllEvent"
252
+ ]
253
+ ),
254
+ (
255
+ "scurrypy.events.guild_events",
256
+ [
257
+ "GuildCreateEvent",
258
+ "GuildUpdateEvent",
259
+ "GuildDeleteEvent"
260
+ ]
261
+ ),
262
+ (
263
+ "scurrypy.events.message_events",
264
+ [
265
+ "MessageCreateEvent",
266
+ "MessageUpdateEvent",
267
+ "MessageDeleteEvent"
268
+ ]
269
+ ),
270
+ (
271
+ "scurrypy.events.channel_events",
272
+ [
273
+ "GuildChannelCreateEvent",
274
+ "GuildChannelUpdateEvent",
275
+ "GuildChannelDeleteEvent",
276
+ "ChannelPinsUpdateEvent"
277
+ ]
278
+ ),
279
+ (
280
+ "scurrypy.events.interaction_events",
281
+ [
282
+ "InteractionEvent"
283
+ ]
284
+ ),
285
+
286
+ # Parts
287
+ (
288
+ "scurrypy.parts.channel",
289
+ [
290
+ "ChannelTypes",
291
+ "GuildChannel"
292
+ ]
293
+ ),
294
+ (
295
+ "scurrypy.parts.command",
296
+ [
297
+ "CommandTypes",
298
+ "CommandOptionTypes",
299
+ "SlashCommand",
300
+ "UserCommand",
301
+ "MessageCommand"
302
+ ]
303
+ ),
304
+ (
305
+ "scurrypy.parts.components_v2",
306
+ [
307
+ "ComponentV2Types",
308
+ "SectionPart",
309
+ "TextDisplay",
310
+ "Thumbnail",
311
+ "MediaGalleryItem",
312
+ "MediaGallery",
313
+ "File",
314
+ "SeparatorTypes",
315
+ "Separator",
316
+ "ContainerPart",
317
+ "Label"
318
+ ]
319
+ ),
320
+ (
321
+ "scurrypy.parts.components",
322
+ [
323
+ "ComponentTypes",
324
+ "ActionRowPart",
325
+ "ButtonStyles",
326
+ "Button",
327
+ "SelectOption",
328
+ "StringSelect",
329
+ "TextInputStyles",
330
+ "TextInput",
331
+ "DefaultValue",
332
+ "UserSelect",
333
+ "RoleSelect",
334
+ "MentionableSelect",
335
+ "ChannelSelect"
336
+ ]
337
+ ),
338
+ (
339
+ "scurrypy.parts.embed",
340
+ [
341
+ "EmbedAuthor",
342
+ "EmbedThumbnail",
343
+ "EmbedField",
344
+ "EmbedImage",
345
+ "EmbedFooter",
346
+ "EmbedPart"
347
+ ]
348
+ ),
349
+ (
350
+ "scurrypy.parts.message",
351
+ [
352
+ "MessageFlags",
353
+ "MessageReferenceTypes",
354
+ "MessageReference",
355
+ "Attachment",
356
+ "MessagePart"
357
+ ]
358
+ ),
359
+ (
360
+ "scurrypy.parts.modal",
361
+ [
362
+ "ModalPart"
363
+ ]
364
+ ),
365
+
366
+ # resources
367
+ (
368
+ "scurrypy.resources.application",
369
+ [
370
+ "ApplicationFlags",
371
+ "Application"
372
+ ]
373
+ ),
374
+ (
375
+ "scurrypy.resources.bot_emojis",
376
+ [
377
+ "BotEmojis"
378
+ ]
379
+ ),
380
+ (
381
+ "scurrypy.resources.channel",
382
+ [
383
+ "PinnedMessage",
384
+ "Channel"
385
+ ]
386
+ ),
387
+ (
388
+ "scurrypy.resources.guild",
389
+ [
390
+ "Guild"
391
+ ]
392
+ ),
393
+ (
394
+ "scurrypy.resources.interaction",
395
+ [
396
+ "InteractionCallbackTypes",
397
+ "Interaction"
398
+ ]
399
+ ),
400
+ (
401
+ "scurrypy.resources.message",
402
+ [
403
+ "Message"
404
+ ]
405
+ ),
406
+ (
407
+ "scurrypy.resources.user",
408
+ [
409
+ "User"
410
+ ]
411
+ )
412
+ ]
413
+
414
+ _mapping = {name: module_path
415
+ for module_path, names in _lazy_modules
416
+ for name in names
417
+ }
418
+
419
+ def __getattr__(name: str):
420
+ if name not in _mapping:
421
+ raise AttributeError(f"module {__name__} has no attribute {name}")
422
+
423
+ module = importlib.import_module(_mapping[name])
424
+ attr = getattr(module, name)
425
+ globals()[name] = attr # cache it for future lookups
426
+ return attr
427
+
428
+ def __dir__():
429
+ return sorted(list(globals().keys()) + __all__)