scurrypy 0.1.0__py3-none-any.whl → 0.2.1__py3-none-any.whl

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.

Potentially problematic release.


This version of scurrypy might be problematic. Click here for more details.

discord/__init__.py CHANGED
@@ -3,6 +3,7 @@
3
3
  from .logger import Logger
4
4
  from .client import Client
5
5
  from .intents import Intents, set_intents
6
+ from .config import BaseConfig
6
7
 
7
8
  from .events import *
8
9
  from .resources import *
discord/client.py CHANGED
@@ -5,6 +5,7 @@ from .gateway import GatewayClient
5
5
  from .http import HTTPClient
6
6
  from .intents import Intents
7
7
  from .error import DiscordError
8
+ from .config import BaseConfig
8
9
 
9
10
  from .resources.guild import Guild
10
11
  from .resources.channel import Channel
@@ -28,6 +29,7 @@ class Client:
28
29
  token: str,
29
30
  application_id: int,
30
31
  intents: int = Intents.DEFAULT,
32
+ config: BaseConfig = None,
31
33
  debug_mode: bool = False,
32
34
  prefix = None,
33
35
  quiet: bool = False
@@ -43,6 +45,7 @@ class Client:
43
45
  """
44
46
  self.token = token
45
47
  self.application_id = application_id
48
+ self.config = config
46
49
 
47
50
  self._logger = Logger(debug_mode, quiet)
48
51
  self._ws = GatewayClient(token, intents, self._logger)
@@ -51,15 +54,16 @@ class Client:
51
54
  if prefix and (intents & Intents.MESSAGE_CONTENT == 0):
52
55
  self._logger.log_warn('Prefix set without message content enabled.')
53
56
 
54
- self.dispatcher = EventDispatcher(self.application_id, self._http, self._logger)
55
- self.prefix_dispatcher = PrefixDispatcher(self._http, self._logger, prefix)
56
- self.command_dispatcher = CommandDispatcher(self.application_id, self._http, self._logger)
57
+ self.dispatcher = EventDispatcher(self.application_id, self._http, self._logger, config)
58
+ self.prefix_dispatcher = PrefixDispatcher(self._http, self._logger, prefix, config)
59
+ self.command_dispatcher = CommandDispatcher(self.application_id, self._http, self._logger, config)
57
60
 
58
61
  self._global_commands = [] # SlashCommand
59
62
  self._guild_commands = {} # {guild_id : [commands], ...}
60
63
 
61
64
  self._is_set_up = False
62
65
  self._setup_hooks = []
66
+ self._shutdown_hooks = []
63
67
 
64
68
  self.emojis = BotEmojis(self._http, self.application_id)
65
69
 
@@ -125,6 +129,15 @@ class Client:
125
129
  """
126
130
  self._setup_hooks.append(func)
127
131
 
132
+ def shutdown_hook(self, func):
133
+ """Decorator registers a shutdown hook.
134
+ (Runs once before the bot exits the loop)
135
+
136
+ Args:
137
+ func (callable): callback to the shutdown function
138
+ """
139
+ self._shutdown_hooks.append(func)
140
+
128
141
  def application_from_id(self, application_id: int):
129
142
  """Creates an interactable application resource.
130
143
 
@@ -265,7 +278,7 @@ class Client:
265
278
  if self._setup_hooks:
266
279
  for hook in self._setup_hooks:
267
280
  self._logger.log_info(f"Setting hook {hook.__name__}")
268
- await hook()
281
+ await hook(self)
269
282
  self._logger.log_high_priority("Hooks set up.")
270
283
 
271
284
  # register GUILD commands
@@ -293,8 +306,25 @@ class Client:
293
306
  self._logger.log_error(f"Unspecified Error Type {type(e).__name__} - {e}")
294
307
  break
295
308
  finally:
296
- await self._ws.close()
297
- await self._http.close_session()
309
+ # Run hooks (with safe catching)
310
+ for hook in self._shutdown_hooks:
311
+ try:
312
+ self._logger.log_info(f"Executing shutdown hook {hook.__name__}")
313
+ await hook(self)
314
+ except Exception as e:
315
+ self._logger.log_error(f"{type(e).__name__}: {e}")
316
+
317
+ # Always close resources
318
+ try:
319
+ await self._ws.close()
320
+ except Exception as e:
321
+ self._logger.log_warn(f"WebSocket close failed: {e}")
322
+
323
+ try:
324
+ await self._http.close_session()
325
+ except Exception as e:
326
+ self._logger.log_warn(f"HTTP session close failed: {e}")
327
+
298
328
 
299
329
  def run(self):
300
330
  """Starts the bot.
discord/config.py ADDED
@@ -0,0 +1,6 @@
1
+ from dataclasses import dataclass
2
+
3
+ @dataclass
4
+ class BaseConfig:
5
+ """Config class that lives inside Client and can be extended by the dev to add persistent data (like a database)."""
6
+ pass
@@ -2,6 +2,7 @@ import asyncio
2
2
 
3
3
  from ..http import HTTPClient
4
4
  from ..logger import Logger
5
+ from ..config import BaseConfig
5
6
 
6
7
  from ..events.interaction_events import ApplicationCommandData, MessageComponentData, ModalData, InteractionEvent
7
8
  from ..resources.interaction import Interaction, InteractionDataTypes
@@ -28,7 +29,7 @@ class CommandDispatcher:
28
29
  }
29
30
  """Maps [`InteractionTypes`][discord.dispatch.command_dispatcher.InteractionTypes] to their respective dataclass."""
30
31
 
31
- def __init__(self, application_id: int, http: HTTPClient, logger: Logger):
32
+ def __init__(self, application_id: int, http: HTTPClient, logger: Logger, config: BaseConfig):
32
33
  self.application_id = application_id
33
34
  """Bot's application ID."""
34
35
 
@@ -38,6 +39,8 @@ class CommandDispatcher:
38
39
  self._logger = logger
39
40
  """Logger instance to log events."""
40
41
 
42
+ self.config = config
43
+
41
44
  self._component_handlers = {}
42
45
  """Mapping of component custom IDs to handler."""
43
46
 
@@ -114,7 +117,7 @@ class CommandDispatcher:
114
117
  Args:
115
118
  data (dict): interaction data
116
119
  """
117
- event = InteractionEvent(interaction=Interaction.from_dict(data, self._http))
120
+ event = InteractionEvent(config=self.config, interaction=Interaction.from_dict(data, self._http))
118
121
 
119
122
  event_data_obj = self.RESOURCE_MAP.get(event.interaction.type)
120
123
 
@@ -1,5 +1,6 @@
1
1
  from ..http import HTTPClient
2
2
  from ..logger import Logger
3
+ from ..config import BaseConfig
3
4
 
4
5
  from ..events.ready_event import *
5
6
  from ..events.reaction_events import *
@@ -40,7 +41,7 @@ class EventDispatcher:
40
41
  }
41
42
  """Mapping of event names to respective dataclass."""
42
43
 
43
- def __init__(self, application_id: int, http: HTTPClient, logger: Logger):
44
+ def __init__(self, application_id: int, http: HTTPClient, logger: Logger, config: BaseConfig):
44
45
  self.application_id = application_id
45
46
  """Bot's ID."""
46
47
 
@@ -50,6 +51,9 @@ class EventDispatcher:
50
51
  self._logger = logger
51
52
  """HTTP session for requests"""
52
53
 
54
+ self.config = config
55
+ """User-defined bot config for persistent data."""
56
+
53
57
  self._handlers = {}
54
58
  """Mapping of event names to handler."""
55
59
 
@@ -81,5 +85,6 @@ class EventDispatcher:
81
85
  handler = self._handlers.get(event_name, None)
82
86
  if handler:
83
87
  obj = cls.from_dict(data, self._http)
88
+ obj.config = self.config
84
89
  await handler(obj)
85
90
  self._logger.log_info(f"Event {event_name} Acknowledged.")
@@ -1,5 +1,6 @@
1
1
  from ..http import HTTPClient
2
2
  from ..logger import Logger
3
+ from ..config import BaseConfig
3
4
 
4
5
  from ..events.message_events import MessageCreateEvent
5
6
 
@@ -8,7 +9,7 @@ from ..models.member import MemberModel
8
9
 
9
10
  class PrefixDispatcher:
10
11
  """Handles text-based command messages that start with a specific prefix."""
11
- def __init__(self, http: HTTPClient, logger: Logger, prefix: str):
12
+ def __init__(self, http: HTTPClient, logger: Logger, prefix: str, config: BaseConfig):
12
13
  self._http = http
13
14
  """HTTP session for requests."""
14
15
 
@@ -18,6 +19,9 @@ class PrefixDispatcher:
18
19
  self.prefix = prefix
19
20
  """User-defined command prefix."""
20
21
 
22
+ self.config = config
23
+ """User-defined bot config for persistent data."""
24
+
21
25
  self._handlers = {}
22
26
  """Mapping of command prefix names to handler"""
23
27
 
@@ -37,6 +41,7 @@ class PrefixDispatcher:
37
41
  data (dict): Discord's raw event payload
38
42
  """
39
43
  event = MessageCreateEvent(
44
+ config=self.config,
40
45
  guild_id=data.get('guild_id'),
41
46
  message=Message.from_dict(data, self._http),
42
47
  member=MemberModel.from_dict(data.get('member'))
@@ -1,10 +1,11 @@
1
1
  from dataclasses import dataclass
2
2
  from typing import Optional
3
- from ..model import DataModel
3
+ from .event_model import EventModel
4
4
 
5
5
  @dataclass
6
- class GuildChannelEvent(DataModel):
6
+ class GuildChannelEvent(EventModel):
7
7
  """Base guild channel event."""
8
+
8
9
  id: int
9
10
  """ID of the guild channel."""
10
11
 
@@ -45,7 +46,7 @@ class GuildChannelDeleteEvent(GuildChannelEvent):
45
46
  pass
46
47
 
47
48
  @dataclass
48
- class ChannelPinsUpdateEvent(DataModel):
49
+ class ChannelPinsUpdateEvent(EventModel):
49
50
  """Pin update event."""
50
51
  channel_id: int
51
52
  guild_id: Optional[int]
@@ -0,0 +1,10 @@
1
+ from dataclasses import dataclass
2
+ from ..model import DataModel
3
+ from ..config import BaseConfig
4
+
5
+ @dataclass
6
+ class EventModel(DataModel):
7
+ """Event Model for event-driven fields common among all events."""
8
+
9
+ config: BaseConfig
10
+ """User-defined bot config for persistent data."""
@@ -1,11 +1,10 @@
1
1
  from dataclasses import dataclass
2
- from typing import Optional
3
- from ..model import DataModel
2
+ from .event_model import EventModel
4
3
  from ..models import MemberModel
5
4
  from ..resources.channel import Channel
6
5
 
7
6
  @dataclass
8
- class GuildEvent(DataModel):
7
+ class GuildEvent(EventModel):
9
8
  """Base guild event."""
10
9
  joined_at: str
11
10
  """ISO8601 timestamp of when app joined the guild."""
@@ -22,9 +21,6 @@ class GuildEvent(DataModel):
22
21
  channels: list[Channel]
23
22
  """Channels in the guild."""
24
23
 
25
- unavailable: Optional[bool]
26
- """If the guild is unavailable due to an outage."""
27
-
28
24
  class GuildCreateEvent(GuildEvent):
29
25
  """Received when the bot has joined a guild."""
30
26
  pass
@@ -1,6 +1,7 @@
1
1
  from dataclasses import dataclass, field
2
2
  from typing import Optional
3
3
  from ..model import DataModel
4
+ from ..config import BaseConfig
4
5
 
5
6
  from ..resources.interaction import Interaction
6
7
 
@@ -141,5 +142,8 @@ class InteractionEvent(DataModel):
141
142
  interaction: Interaction
142
143
  """Interaction resource object. See [`Interaction`][discord.resources.interaction.Interaction]."""
143
144
 
145
+ config: BaseConfig
146
+ """User-defined bot config for persistent data."""
147
+
144
148
  data: Optional[ApplicationCommandData | MessageComponentData | ModalData] = None
145
149
  """Interaction response data."""
@@ -1,12 +1,12 @@
1
1
  from dataclasses import dataclass
2
2
  from typing import Optional
3
- from ..model import DataModel
3
+ from .event_model import EventModel
4
4
 
5
5
  from ..resources.message import Message
6
6
  from ..models.member import MemberModel
7
7
 
8
8
  @dataclass
9
- class MessageCreateEvent(DataModel):
9
+ class MessageCreateEvent(EventModel):
10
10
  """Received when a message is created."""
11
11
  message: Message
12
12
  """Message resource object. See [`Resource.Message`][discord.resources.message.Message]."""
@@ -18,7 +18,7 @@ class MessageCreateEvent(DataModel):
18
18
  """Partial Member object of the author of the message. See [`MemberModel`][discord.models.member.MemberModel]."""
19
19
 
20
20
  @dataclass
21
- class MessageUpdateEvent(DataModel):
21
+ class MessageUpdateEvent(EventModel):
22
22
  """Received when a message is updated."""
23
23
  message: Message
24
24
  """Message resource object. See [`Resource.Message`][discord.resources.message.Message]."""
@@ -30,7 +30,7 @@ class MessageUpdateEvent(DataModel):
30
30
  """Partial Member object of the author of the message. See [`MemberModel`][discord.models.member.MemberModel]."""
31
31
 
32
32
  @dataclass
33
- class MessageDeleteEvent(DataModel):
33
+ class MessageDeleteEvent(EventModel):
34
34
  """Received when a message is deleted."""
35
35
 
36
36
  id: int
@@ -1,6 +1,6 @@
1
1
  from dataclasses import dataclass
2
2
  from typing import Optional
3
- from ..model import DataModel
3
+ from .event_model import EventModel
4
4
 
5
5
  from ..models.member import MemberModel
6
6
  from ..models.emoji import EmojiModel
@@ -15,7 +15,7 @@ class ReactionType:
15
15
  """A super emoji."""
16
16
 
17
17
  @dataclass
18
- class ReactionAddEvent(DataModel):
18
+ class ReactionAddEvent(EventModel):
19
19
  """Reaction added event."""
20
20
 
21
21
  type: int
@@ -46,7 +46,7 @@ class ReactionAddEvent(DataModel):
46
46
  """ID of the user who sent the message where the reaction was added."""
47
47
 
48
48
  @dataclass
49
- class ReactionRemoveEvent(DataModel):
49
+ class ReactionRemoveEvent(EventModel):
50
50
  """Reaction removed event."""
51
51
 
52
52
  type: int
@@ -70,7 +70,7 @@ class ReactionRemoveEvent(DataModel):
70
70
  burst: bool
71
71
  """If the emoji of the removed reaction is super."""
72
72
 
73
- class ReactionRemoveAllEvent(DataModel):
73
+ class ReactionRemoveAllEvent(EventModel):
74
74
  """Remove all reactions event."""
75
75
 
76
76
  channel_id: int
@@ -83,7 +83,7 @@ class ReactionRemoveAllEvent(DataModel):
83
83
  """ID of the guild where all reaction were removed (if in a guild)."""
84
84
 
85
85
  @dataclass
86
- class ReactionRemoveEmojiEvent(DataModel):
86
+ class ReactionRemoveEmojiEvent(EventModel):
87
87
  """All reactions of a specific emoji removed."""
88
88
 
89
89
  emoji: EmojiModel
@@ -1,5 +1,7 @@
1
1
  from dataclasses import dataclass
2
2
  from ..model import DataModel
3
+ from ..config import BaseConfig
4
+
3
5
  from ..models.user import UserModel
4
6
  from ..models.guild import ReadyGuildModel
5
7
  from ..models.application import ApplicationModel
@@ -28,3 +30,6 @@ class ReadyEvent(DataModel):
28
30
 
29
31
  application: ApplicationModel
30
32
  """Partial application object. Contains ID and flags."""
33
+
34
+ config: BaseConfig
35
+ """User-defined bot config for persistent data."""
@@ -0,0 +1,85 @@
1
+ Metadata-Version: 2.4
2
+ Name: scurrypy
3
+ Version: 0.2.1
4
+ Summary: Discord API Wrapper in Python
5
+ Author: Furmissile
6
+ Requires-Python: >=3.10
7
+ Description-Content-Type: text/markdown
8
+ License-File: LICENSE
9
+ Dynamic: license-file
10
+
11
+ # __Welcome to ScurryPy__
12
+
13
+ [![PyPI version](https://badge.fury.io/py/scurrypy.svg)](https://badge.fury.io/py/scurrypy)
14
+
15
+ Yet another Discord API wrapper in Python!
16
+
17
+ While this wrapper is mainly used for various squirrel-related shenanigans, it can also be used for more generic bot purposes.
18
+
19
+ ## Features
20
+ * Command and event handling
21
+ * Declarative style using decorators
22
+ * Supports both legacy and new features
23
+ * Respects Discord's rate limits
24
+
25
+ ## Something things to consider...
26
+ * This is an early version — feedback, ideas, and contributions are welcome! With that said, there will be bumps in the road so expect bugs and other flaws!
27
+ * Some features are not yet supported, such as sharding and automod, while others, like voice, will never be supported. While this library can handle many of your basic needs, common features such as sharding or auto-mod actions are not yet implemented. See the [license](LICENSE) for details on usage.
28
+
29
+
30
+ ## Getting Started
31
+ While this tab shows up in the docs, here are some complete examples where all you need to do is pop in your bot's credentials!
32
+
33
+ ## Installation
34
+ To install the ScurryPy package, run:
35
+ ```bash
36
+ pip install scurrypy
37
+ ```
38
+
39
+ ## Minimal Slash Command
40
+ The following demonstrates building and responding to a slash command.
41
+ ```python
42
+ import discord, os
43
+ from dotenv import load_dotenv
44
+
45
+ load_dotenv(dotenv_path='./path/to/env') # omit argument if your env file is on the same level
46
+
47
+ bot = discord.Client(
48
+ token=os.getenv("DISCORD_TOKEN"),
49
+ application_id=1234567890 # replace with your bot's user ID
50
+ )
51
+
52
+ @bot.command(
53
+ command=discord.SlashCommand(name='example', description='Demonstrate the minimal slash command!'),
54
+ guild_id=GUILD_ID # must be a guild ID your bot is in!
55
+ )
56
+ async def example(event: discord.InteractionEvent):
57
+ await event.interaction.respond(f'Hello, {event.interaction.member.user.username}!')
58
+
59
+ bot.run()
60
+ ```
61
+
62
+ ## Minimal Prefix Command (Legacy)
63
+ The following demonstrates building and responding to a message prefix command.
64
+ ```python
65
+ import discord, os
66
+ from dotenv import load_dotenv
67
+
68
+ load_dotenv(dotenv_path='./path/to/env') # omit argument if your env file is on the same level
69
+
70
+ bot = discord.Client(
71
+ token=os.getenv("DISCORD_TOKEN"),
72
+ application_id=1234567890, # replace with your bot's user ID
73
+ intents=discord.set_intents(message_content=True),
74
+ prefix='!' # your custom prefix
75
+ )
76
+
77
+ @bot.prefix_command
78
+ async def ping(event: discord.MessageCreateEvent): # the function name is the name of the command!
79
+ await event.message.send(f"Pong!")
80
+
81
+ bot.run()
82
+ ```
83
+
84
+ ## Like what you see?
85
+ See the docs for more!
@@ -1,5 +1,6 @@
1
- discord/__init__.py,sha256=2mkaOJP7-7iT_aSkrstLuq10QykiDa3Y2vvl-wD9r1c,185
2
- discord/client.py,sha256=kLwVFjUkl4qQWSj6hsxUk4F_6FDbW462roeHgRXxfW4,11986
1
+ discord/__init__.py,sha256=DPE5laK7mMQPeF2ky8D8QpokCDqsGlq6slHHhbNXmso,217
2
+ discord/client.py,sha256=sVgr5y_bci9aFUMgpOytiHlAljQyPS0Wl2C_yUvtJ-E,13139
3
+ discord/config.py,sha256=OH1A2mNKhDlGvQYASEsVUx2pNxP1YQ2a7a7z-IM5xFg,200
3
4
  discord/error.py,sha256=AlislRTna554cM6KC0KrwKugzYDYtx_9C8_3QFe4XDc,2070
4
5
  discord/gateway.py,sha256=H_WaUrpK8rl3rGlT3qNexpru7R6O6Y6GQPkQcDt_KX8,6555
5
6
  discord/http.py,sha256=cGFhGEeNebf1sgSUB4Xfnlj00twWLFi9AwO85gAAUDA,10955
@@ -7,17 +8,18 @@ discord/intents.py,sha256=Lf2fogFFDqilZeKJv7tcUgKmMW3D7ykK4bBNi-zDzYA,2866
7
8
  discord/logger.py,sha256=GBcvldIrSBnwNSgus-oa1NsYV8hU7f8_4J4VX_GmkxA,4700
8
9
  discord/model.py,sha256=Fr0PO_8UCgEep_Dk9eVtHmgzrlxkdsEYeuiS3EYK4hY,3015
9
10
  discord/dispatch/__init__.py,sha256=m7ixrbNhOV9QRORXPw6LSwxofQMAvLmPFBweBZu9ACc,20
10
- discord/dispatch/command_dispatcher.py,sha256=jOfO6GEQvp0muY3iE9otucsyBE36-xhMcZKMwHGnstU,5543
11
- discord/dispatch/event_dispatcher.py,sha256=CX-7htyG7Gi9KobFIZJYHx78km3BT0M8gymZEVCi9LM,2902
12
- discord/dispatch/prefix_dispatcher.py,sha256=IV2xKqCVaz-PGvg9etgqqUpMWQgvRnYEk6eURt4UqQc,1894
11
+ discord/dispatch/command_dispatcher.py,sha256=EZJfogU5YggOTVhQ3DGjOJgABjtU2EaDslCOfdleRl0,5648
12
+ discord/dispatch/event_dispatcher.py,sha256=EWLGYyjFtUTCKHN9MdYChm8KjIlMF41Iaa8KDCmpdfI,3085
13
+ discord/dispatch/prefix_dispatcher.py,sha256=Zt3eYhHPJjgTYdJi-lqLD4v-hvllI8yz5M8EjdbNTP8,2072
13
14
  discord/events/__init__.py,sha256=BcmwAj84-nzMZEkip-V903jD0ZCKqhySzlAx5wDwJoo,630
14
- discord/events/channel_events.py,sha256=lkBzNI-gKNgIPfIrOJhx-zjbK5v4bErEUurWp9L-VWw,1369
15
- discord/events/guild_events.py,sha256=4rDPbldG4kjsBmSuRasDoXc-2cYmjdJOP5PTAdEbRw8,1008
15
+ discord/events/channel_events.py,sha256=1Hle3UyYHRQr0ewNwsioMg2tmyAoiQ1ljsXiNd-J7l0,1379
16
+ discord/events/event_model.py,sha256=8KwIZl38mXVI7ExWwn4t4Va9lF8h4ed1UhnCv3aKqMY,297
17
+ discord/events/guild_events.py,sha256=-aDWbDKbaDRAG_gFKx2qMVejtbyenWFnPRl-LsytUbM,894
16
18
  discord/events/hello_event.py,sha256=O8Ketu_N943cnGaFkGsAHfWhgKXFQCYCqSD3EqdsXjA,225
17
- discord/events/interaction_events.py,sha256=5hlYOsV1ROiRXISAGCKcZo8vfk6oqiZcNzzZjSteiag,4361
18
- discord/events/message_events.py,sha256=M5xdaJH1zRzdZk0oN0Jykaeu9k09EjgZjeiIT_EkL1A,1475
19
- discord/events/reaction_events.py,sha256=xx7GD-fqakhJmS-X-HbuAUg9pg6Gqo_KRtLTdPJu7UE,2643
20
- discord/events/ready_event.py,sha256=iDuCTegyrN05FdYVPY0hsfJn1NABslkzsa_b2WxrRu0,792
19
+ discord/events/interaction_events.py,sha256=KdaKJ2xJeGJnPTywU5jHiyWP5dNO0PiWPZbrxwmIWFU,4476
20
+ discord/events/message_events.py,sha256=WCqt2EnrnlUqdd-Ue1RHfom5Wxw3OYkCwRh7C1X5suk,1484
21
+ discord/events/reaction_events.py,sha256=zilWFUVzreVo99TM5oAb6R8RIyr3sjCb47Q3D238l9k,2653
22
+ discord/events/ready_event.py,sha256=WvIp9teknvxV87ukraSMWk96YsBe2xWTbr4Ev9bsHQ8,909
21
23
  discord/models/__init__.py,sha256=T6C5C8RdkEPurA_zQas5riq3nrThMaSWl9Yasha0xXc,216
22
24
  discord/models/application.py,sha256=2sXtRysUc2TJ40FjdcrWgosmwMrp_h3ybddubQMixKM,924
23
25
  discord/models/emoji.py,sha256=6iz1DhWj_eTUj2KHmwMewjB3AdEBm68EmIZp2WFFCQg,932
@@ -45,8 +47,8 @@ discord/resources/guild.py,sha256=Unld1lWY3XynmRHU2FCi3-LA9VNp2thMI2BlILUTTxk,81
45
47
  discord/resources/interaction.py,sha256=8z91X49KSknaT1syBfLr0SHRgAxaQ-8lbhkb3LU21fg,4911
46
48
  discord/resources/message.py,sha256=RtvcCRx0lwW-mHPl3aNYoEvGffrvtpLsQ2fVWckywVI,7527
47
49
  discord/resources/user.py,sha256=vk89TnCVi-6ZgbDs_TZTCXrx_NfFS5Q9Wi_itYoaoyg,3085
48
- scurrypy-0.1.0.dist-info/licenses/LICENSE,sha256=NtspfRMAlryd1Eev4BYi9EFbKhvdmlCJJ2-ADUoEBoI,426
49
- scurrypy-0.1.0.dist-info/METADATA,sha256=uRHnWjovcV97VB7PQrhVDFUotTd53CGoAY9IVEmv0Ww,186
50
- scurrypy-0.1.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
51
- scurrypy-0.1.0.dist-info/top_level.txt,sha256=fJkrNbR-_8ubMBUcDEJBcfkpECrvSEmMrNKgvLlQFoM,8
52
- scurrypy-0.1.0.dist-info/RECORD,,
50
+ scurrypy-0.2.1.dist-info/licenses/LICENSE,sha256=NtspfRMAlryd1Eev4BYi9EFbKhvdmlCJJ2-ADUoEBoI,426
51
+ scurrypy-0.2.1.dist-info/METADATA,sha256=j-cNCLhQe_Y24X0B_S3glykd4-VITME74vrEYQ1MT8E,2909
52
+ scurrypy-0.2.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
53
+ scurrypy-0.2.1.dist-info/top_level.txt,sha256=fJkrNbR-_8ubMBUcDEJBcfkpECrvSEmMrNKgvLlQFoM,8
54
+ scurrypy-0.2.1.dist-info/RECORD,,
@@ -1,8 +0,0 @@
1
- Metadata-Version: 2.4
2
- Name: scurrypy
3
- Version: 0.1.0
4
- Summary: Discord API Wrapper in Python
5
- Author: Furmissile
6
- Requires-Python: >=3.10
7
- License-File: LICENSE
8
- Dynamic: license-file