Skip to content

Commit 0ac9bc2

Browse files
committed
chore: attempt of rebase
2 parents 2dcf18c + c03c0ab commit 0ac9bc2

34 files changed

+472
-168
lines changed

docs/quickstart.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -354,7 +354,7 @@ But how to send it? You can't use ``ctx.send`` for it. Take a look at :ref:`Moda
354354
355355
Modals
356356
******
357-
Modals are a new way to interact with a user. Currently only a ``TextInput`` component is supported. You can have up to three ``TextInput`` in a Modal.
357+
Modals are a new way to interact with a user. Currently only a ``TextInput`` component is supported. You can have up to five ``TextInput`` in a Modal.
358358
359359
.. code-block:: python
360360

examples/bot.py

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
# This code shows a very brief and small example of how to create a bot with our library.
2+
# This example does not cover all the features of the library, but it is enough to get you started.
3+
# In order to learn more about how to use the library, please head over to our documentation:
4+
# https://interactionspy.rtfd.io/en/latest/
5+
6+
# The first thing you need to do is import the library.
7+
import interactions
8+
9+
# Now, let's create an instance of a bot.
10+
# When you make a bot, we refer to it as the "client."
11+
# The client is the main object that interacts with the Gateway, what talks to Discord.
12+
# The client is also the main object that interacts with the API, what makes requests with Discord.
13+
client = interactions.Client("your bot token will go here.")
14+
15+
# With our client established, let's have the library inform us when the client is ready.
16+
# These are known as event listeners. An event listener can be established in one of two ways.
17+
# You can provide the name of the event, prefixed by an "on_", or by telling the event decorator what event it is.
18+
@client.event
19+
async def on_ready():
20+
# We can use the client "me" attribute to get information about the bot.
21+
print(f"We're online! We've logged in as {client.me.name}.")
22+
23+
# We're also able to use property methods to gather additional data.
24+
print(f"Our latency is {round(client.latency)} ms.")
25+
26+
27+
@client.event("message_create")
28+
async def name_this_however_you_want(message: interactions.Message):
29+
# Whenever we specify any other event type that isn't "READY," the function underneath
30+
# the decorator will most likely have an argument required. This argument is the data
31+
# that is being supplied back to us developers, which we call a data model.
32+
33+
# In this example, we're listening to messages being created. This means we can expect
34+
# a "message" argument to be passed to the function, which will be the data model of such.
35+
36+
# We can use the data model to access the data we need.
37+
print(
38+
f"We've received a message from {message.author.name}. The message is: {message.content}."
39+
)
40+
41+
42+
# Now, let's create a command.
43+
# A command is a function that is called when a user types out a command.
44+
# The command is called with a context object, which contains information about the user, the channel, and the guild.
45+
# Context is what we call the described information given from an interaction response, what comes from a command.
46+
# The context object in this case is a class for commands, but can also be one for components if used that way.
47+
@client.command(name="hello-world", description='A command that says "hello world!"')
48+
async def hello_world(ctx: interactions.CommandContext):
49+
# "ctx" is an abbreviation of the context object.
50+
# You don't need to type hint this, but it's recommended to do so.
51+
52+
# Now, let's send back a response.
53+
# Note that when you make an interaction response, you can no longer run anything in this function.
54+
# The interaction response should be the LAST thing you do when a command is ran.
55+
await ctx.send("hello world!")
56+
57+
# Because of this, this line of code right here will not execute.
58+
print("we ran.")
59+
60+
61+
# After we've declared all of the bot code we want, we need to tell the library to run our bot.
62+
# In this example, we've decided to do some things in a different way without explicitly saying it:
63+
64+
# - we'll be syncing the commands automatically.
65+
# if you want to do this manually, you can do it by passing disable_sync=False in the Client
66+
# object on line 8.
67+
# - we are not setting a presence.
68+
# - we are not automatically sharding, and registering the connection under 1 shard.
69+
# - we are using default intents, which are Gateway intents excluding privileged ones.
70+
client.start()

interactions/__init__.py

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,13 @@
11
"""
2-
(interactions)
3-
discord-interactions
2+
interactions.py
43
5-
Easy, simple, scalable and modular: a Python API wrapper for interactions.
4+
Easy, simple, scalable and modular: a Python library for interactions.
65
76
To see the documentation, please head over to the link here:
8-
https://discord-interactions.rtfd.io/en/latest for ``stable`` builds.
9-
https://discord-interactions.rtfd.io/en/unstable for ``unstable`` builds.
7+
https://interactionspy.rtfd.io/en/latest for ``stable`` builds.
8+
https://interactionspy.rtfd.io/en/unstable for ``unstable`` builds.
109
11-
(c) 2021 goverfl0w.
12-
Co-authored by DeltaXW.
10+
(c) 2021 interactions-py.
1311
"""
1412
from .api.models.channel import * # noqa: F401 F403
1513
from .api.models.flags import * # noqa: F401 F403
@@ -23,10 +21,10 @@
2321
from .api.models.team import * # noqa: F401 F403
2422
from .api.models.user import * # noqa: F401 F403
2523
from .base import * # noqa: F401 F403
26-
from .client import * # noqa: F401 F403
27-
from .context import * # noqa: F401 F403
28-
from .decor import * # noqa: F401 F403
29-
from .enums import * # noqa: F401 F403
30-
from .models.command import * # noqa: F401 F403
31-
from .models.component import * # noqa: F401 F403
32-
from .models.misc import * # noqa: F401 F403
24+
from .client.bot import * # noqa: F401 F403
25+
from .client.context import * # noqa: F401 F403
26+
from .client.decor import * # noqa: F401 F403
27+
from .client.enums import * # noqa: F401 F403
28+
from .client.models.command import * # noqa: F401 F403
29+
from .client.models.component import * # noqa: F401 F403
30+
from .client.models.misc import * # noqa: F401 F403

interactions/api/__init__.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
from .cache import * # noqa: F401 F403
1010
from .enums import * # noqa: F401 F403
1111
from .error import * # noqa: F401 F403
12-
from .gateway import * # noqa: F401 F403
12+
from .gateway.client import * # noqa: F401 F403
13+
from .gateway.heartbeat import * # noqa: F401 F403
1314
from .http import * # noqa: F401 F403
1415
from .models import * # noqa: F401 F403

interactions/api/enums.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
# Normal libraries
21
from enum import IntEnum
32

43
# TODO: post-v4: Implement this into the new error system at a later point.
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
"""
2+
interactions.api.gateway
3+
4+
This section of the library maintains and
5+
handles all of the Gateway work.
6+
"""
7+
from .client import * # noqa: F401 F403
8+
from .heartbeat import * # noqa: F401 F403

interactions/api/gateway.py renamed to interactions/api/gateway/client.py

Lines changed: 26 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
from json import dumps, loads
55

66
from asyncio import (
7-
AbstractEventLoop,
87
Event,
98
Task,
109
ensure_future,
@@ -17,42 +16,23 @@
1716
from time import perf_counter
1817
from typing import Any, Dict, List, Optional, Tuple, Union
1918

20-
from aiohttp import WSMessage
21-
from aiohttp.http import WS_CLOSED_MESSAGE
22-
23-
from ..base import get_logger
24-
from ..enums import InteractionType, OptionType
25-
from ..models.command import Option
26-
from .dispatch import Listener
27-
from .enums import OpCodeType
28-
from .error import GatewayException
29-
from .http.client import HTTPClient
30-
from .models.flags import Intents
31-
from .models.misc import MISSING
32-
from .models.presence import ClientPresence
19+
from aiohttp import WSMessage, WSMsgType
20+
from aiohttp.http import WS_CLOSED_MESSAGE, WS_CLOSING_MESSAGE
21+
22+
from ...base import get_logger
23+
from ...client.enums import InteractionType, OptionType
24+
from ...client.models import Option
25+
from ..dispatch import Listener
26+
from ..enums import OpCodeType
27+
from ..error import GatewayException
28+
from ..http.client import HTTPClient
29+
from ..models.flags import Intents
30+
from ..models.misc import MISSING
31+
from ..models.presence import ClientPresence
32+
from .heartbeat import _Heartbeat
3333

3434
log = get_logger("gateway")
3535

36-
__all__ = ("_Heartbeat", "WebSocketClient")
37-
38-
39-
class _Heartbeat:
40-
"""An internal class representing the heartbeat in a WebSocket connection."""
41-
42-
event: Event
43-
delay: float
44-
45-
def __init__(self, loop: AbstractEventLoop) -> None:
46-
"""
47-
:param loop: The event loop to base the asynchronous manager.
48-
:type loop: AbstractEventLoop
49-
"""
50-
try:
51-
self.event = Event(loop=loop) if version_info < (3, 10) else Event()
52-
except TypeError:
53-
pass
54-
self.delay = 0.0
55-
5636

5737
class WebSocketClient:
5838
"""
@@ -199,7 +179,7 @@ async def _establish_connection(
199179

200180
if stream is None:
201181
continue
202-
if self._client is None or stream == WS_CLOSED_MESSAGE:
182+
if self._client is None or stream == WS_CLOSED_MESSAGE or stream == WSMsgType.CLOSE:
203183
await self._establish_connection()
204184
break
205185

@@ -537,8 +517,18 @@ async def __receive_packet_stream(self) -> Optional[Dict[str, Any]]:
537517
"""
538518

539519
packet: WSMessage = await self._client.receive()
540-
if packet == WS_CLOSED_MESSAGE:
520+
521+
if packet == WSMsgType.CLOSE:
522+
await self._client.close()
541523
return packet
524+
525+
elif packet == WS_CLOSED_MESSAGE:
526+
return packet
527+
528+
elif packet == WS_CLOSING_MESSAGE:
529+
await self._client.close()
530+
return WS_CLOSED_MESSAGE
531+
542532
return loads(packet.data) if packet and isinstance(packet.data, str) else None
543533

544534
async def _send_packet(self, data: Dict[str, Any]) -> None:

interactions/api/gateway.pyi renamed to interactions/api/gateway/client.pyi

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -8,21 +8,17 @@ from typing import Any, Dict, List, Optional, Tuple, Union, Iterable
88

99
from aiohttp import ClientWebSocketResponse
1010

11-
from ..models import Option
12-
from ..api.models.misc import MISSING
13-
from ..api.models.presence import ClientPresence
14-
from .dispatch import Listener
15-
from .http.client import HTTPClient
16-
from .models.flags import Intents
11+
from .heartbeat import _Heartbeat
12+
from ...client.models import Option
13+
from ...api.models.misc import MISSING
14+
from ...api.models.presence import ClientPresence
15+
from ..dispatch import Listener
16+
from ..http.client import HTTPClient
17+
from ..models.flags import Intents
1718

1819
log: Logger
1920
__all__: Iterable[str]
2021

21-
class _Heartbeat:
22-
event: Event
23-
delay: float
24-
def __init__(self, loop: AbstractEventLoop) -> None: ...
25-
2622
class WebSocketClient:
2723
_loop: AbstractEventLoop
2824
_dispatch: Listener
@@ -42,7 +38,6 @@ class WebSocketClient:
4238
_last_ack: float
4339
latency: float
4440
ready: Event
45-
4641
def __init__(
4742
self,
4843
token: str,
@@ -53,7 +48,9 @@ class WebSocketClient:
5348
async def _manage_heartbeat(self) -> None: ...
5449
async def __restart(self): ...
5550
async def _establish_connection(
56-
self, shard: Optional[List[Tuple[int]]] = MISSING, presence: Optional[ClientPresence] = MISSING
51+
self,
52+
shard: Optional[List[Tuple[int]]] = MISSING,
53+
presence: Optional[ClientPresence] = MISSING,
5754
) -> None: ...
5855
async def _handle_connection(
5956
self,
@@ -64,7 +61,9 @@ class WebSocketClient:
6461
async def wait_until_ready(self) -> None: ...
6562
def _dispatch_event(self, event: str, data: dict) -> None: ...
6663
def __contextualize(self, data: dict) -> object: ...
67-
def __sub_command_context(self, data: Union[dict, Option], _context: Optional[object] = MISSING) -> Union[Tuple[str], dict]: ...
64+
def __sub_command_context(
65+
self, data: Union[dict, Option], _context: Optional[object] = MISSING
66+
) -> Union[Tuple[str], dict]: ...
6867
def __option_type_context(self, context: object, type: int) -> dict: ...
6968
@property
7069
async def __receive_packet_stream(self) -> Optional[Dict[str, Any]]: ...
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
from asyncio import AbstractEventLoop, Event
2+
from sys import version_info
3+
4+
5+
class _Heartbeat:
6+
"""An internal class representing the heartbeat in a WebSocket connection."""
7+
8+
event: Event
9+
delay: float
10+
11+
def __init__(self, loop: AbstractEventLoop) -> None:
12+
"""
13+
:param loop: The event loop to base the asynchronous manager.
14+
:type loop: AbstractEventLoop
15+
"""
16+
try:
17+
self.event = Event(loop=loop) if version_info < (3, 10) else Event()
18+
except TypeError:
19+
pass
20+
self.delay = 0.0
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
from asyncio import AbstractEventLoop, Event
2+
3+
class _Heartbeat:
4+
event: Event
5+
delay: float
6+
def __init__(self, loop: AbstractEventLoop) -> None: ...

0 commit comments

Comments
 (0)