Skip to content

Commit 9cd8378

Browse files
feat: merge enhanced (#895)
* feat: new Command object There are still countless TODOs, this is a progress commit * fix: import error * feat: option decorator btw i havent tested any of these * fix: attempt to fix circular import * fix: circular import * refactor: replace errors with LibraryException * refactor: few small refactors * refactor: test * feat: implement Command obj in decorators I still haven't tested these btw * feat: working subcommand system Have not made it work in extensions yet * feat: more customizable subcommand system * feat: working Command system in Extensions * refactor: add a TODO * refactor: tidy up the code, improve coro calling * refactor: rename Command.base to Command.name * feat: better group behavior * refactor: replace a few more base= with name=, tidy up code * refactor: remove client field from Command and properly teardown commands * refactor: different method of looping * feat: implement default_scope functionality * refactor: remove options param from Command.group() * refactor: make autocomplete work, change typehints, make user and message command rely on command, properly sync Command objects inside Extensions * feat: implement autodefer and spread_to_rows These are put in a new utils.py file * fix: commands and autocomplete with self not passed when inside Extensions * style: add typehints * refactor: tweak default scope setting * docs: some docstrings filled in * docs: more docstrings, organization of code * refactor: move resolving commands outside of __sync * refactor: change __all__ from list to tuple * fix: subcommands error with variables * fix: incorrect error * docs: utils.py docstrings * feat: new way of creating an ActionRow (pun intended) * refactor: make option decorator better * refactor: change Command.self to Command.extension * docs: fix incorrect typehint * docs: modify docstring * docs: new docs page * docs: add doc file * docs: move line * docs: modify docstring of spread_to_rows * refactor: rename variables * feat: implement Command.error decorator * fix: typehint * docs: attempt to fix parameters of Client docstring * ci: correct from checks. * docs: fix docstring * style: delete a blank line * docs: update quickstart * ci: correct from checks. * docs: modify quickstart * docs: document new features * docs: testing * docs: testing * docs: make it look good * docs: fix formatting * docs: add migration docs Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
1 parent e4cbb1c commit 9cd8378

File tree

14 files changed

+1385
-172
lines changed

14 files changed

+1385
-172
lines changed

docs/migration.rst

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,3 +62,116 @@ portal and add the intent to your current intents when connecting:
6262
from interactions import Client, Intents
6363
6464
bot = Client("TOKEN", intents=Intents.DEFAULT | Intents.GUILD_MESSAGE_CONTENT)
65+
66+
4.1.0 → 4.3.0
67+
~~~~~~~~~~~~~~~
68+
69+
``4.3.0`` introduces a new method of creating commands, subcommands, and options.
70+
There are also numerous new features, such as a default scope and utilities.
71+
72+
The following example shows and explains how to create commands effortlessly and use new features mentioned above:
73+
74+
.. code-block:: python
75+
76+
import interactions
77+
78+
bot = interactions.Client("TOKEN", default_scope=1234567890)
79+
# the default scope will be applied to all commands except for those
80+
# that disable the feature in the command decorator via: `default_scope=False`
81+
82+
@bot.command()
83+
async def command_name(ctx):
84+
"""Command description"""
85+
... # do something here.
86+
# the name of the command is the coroutine name.
87+
# the description is the first line of the docstring or "No description set".
88+
89+
@bot.command(default_scope=False)
90+
@interactions.option(str, name="opt1") # description is optional.
91+
@interactions.option(4, name="opt2", description="This is an option.")
92+
@interactions.option(interactions.Channel, name="opt3", required=True)
93+
async def command_with_options(
94+
ctx, opt1: str, opt2, int, opt3: interactions.Channel = None
95+
):
96+
... # do something here.
97+
# the default scope is disabled for this command, so this is a global command.
98+
# the option type is positional only, and can be a python type, an integer,
99+
# or supported interactions.py objects.
100+
# all other options are keyword only arguments.
101+
# the type amd name of the option are required, the rest are optional.
102+
103+
# Subcommand system:
104+
@bot.command()
105+
async def base_command(ctx):
106+
... # do something here.
107+
# this is the base command of the subcommand system.
108+
109+
@base_command.subcommand()
110+
async def subcommand1(ctx, base_res: interactions.BaseResult):
111+
... # do something here.
112+
# this is a subcommand of the base command.
113+
# the base result is the result of the base command, it is optional to have.
114+
# /base_command subcommand1
115+
116+
# create subcommands *before* creating groups!
117+
118+
@base_command.group()
119+
async def group1(ctx, base_res: interactions.BaseResult):
120+
... # do something here.
121+
# this symbolizes a group for subcommands.
122+
123+
@group.subcommand()
124+
async def subcommand2(ctx, group_res: interactions.GroupResult):
125+
raise Exception("pretend an error happened here")
126+
# this is a subcommand of the group.
127+
# the group result is the result of the group, it is optional to have.
128+
# /base_command group1 subcommand2
129+
130+
@base_command.group()
131+
async def group2(ctx):
132+
# this symbolizes a group for subcommands.
133+
# here, we will intentionally return StopCommand:
134+
return interactions.StopCommand
135+
# if this is returned, any callbacks afterwards in the same
136+
# command will not be executed.
137+
# for example, subcommand3 will not be executed.
138+
139+
@group2.subcommand()
140+
async def subcommand3(ctx):
141+
... # do something here.
142+
# this is a subcommand of the group.
143+
# this will NOT be executed.
144+
# /base_command group2 subcommand3
145+
146+
@base_command.error
147+
async def base_command_error(ctx, error):
148+
... # do something here.
149+
# remember the exception in subcommand2?
150+
# here, you can handle any errors that occur in the base command.
151+
# this is the error handler for the base command.
152+
# the error is the exception raised by the command.
153+
# you can have optional res, *args, and **kwargs
154+
# if your command is a subcommand or
155+
# there are options that you want to access.
156+
157+
# utilities
158+
@bot.command()
159+
@interactions.autodefer() # configurable
160+
async def autodefer_command(ctx):
161+
# it will automatically defer the command if the command is not
162+
# executed within the configured `delay` in the autodefer decorator.
163+
164+
# ActionRow.new() utility:
165+
b1 = Button(style=1, custom_id="b1", label="b1")
166+
b2 = Button(style=1, custom_id="b2", label="b2")
167+
b3 = Button(style=1, custom_id="b3", label="b3")
168+
b4 = Button(style=1, custom_id="b4", label="b4")
169+
170+
await ctx.send("Components:", components=interactions.ActionRow.new(b1, b2, b3, b4))
171+
# instead of the cumbersome ActionRow(components=[b1, b2, b3, b4])
172+
173+
# spread_to_rows utility:
174+
await ctx.send("Components:", components=interactions.spread_to_rows(b1, b2, b3, b4, max_in_row=2))
175+
# configurable
176+
177+
bot.start()

docs/models.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,4 @@ Interaction Models
99
models.command.rst
1010
models.component.rst
1111
models.misc.rst
12+
models.utils.rst

docs/models.utils.rst

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
.. currentmodule:: interactions
2+
3+
Utilities
4+
==========================
5+
6+
.. automodule:: interactions.client.models.utils
7+
:members:
8+
:noindex:

0 commit comments

Comments
 (0)