Code Monkey home page Code Monkey logo

hikari-lightbulb's Introduction

PyPI

Lightbulb

Lightbulb is designed to be an easy to use command handler library that integrates with the Discord API wrapper library for Python, Hikari.

This library aims to make it simple for you to make your own Discord bots and provide all the utilities and functions you need to help make this job easier.

Installation

Use the package manager pip to install Lightbulb.

pip install hikari-lightbulb

Usage

# Import the command handler
import lightbulb

# Instantiate a Bot instance
bot = lightbulb.BotApp(token="your_token_here", prefix="your_prefix_here")

# Register the command to the bot
@bot.command
# Use the command decorator to convert the function into a command
@lightbulb.command("ping", "checks the bot is alive")
# Define the command type(s) that this command implements
@lightbulb.implements(lightbulb.PrefixCommand)
# Define the command's callback. The callback should take a single argument which will be
# an instance of a subclass of lightbulb.context.Context when passed in
async def ping(ctx: lightbulb.Context) -> None:
    # Send a message to the channel the command was used in
    await ctx.respond("Pong!")

# Run the bot
# Note that this is blocking meaning no code after this line will run
# until the bot is shut off
bot.run()

Issues

If you find any bugs, issues, or unexpected behaviour while using the library, you should open an issue with details of the problem and how to reproduce if possible. Please also open an issue for any new features you would like to see added.

Contributing

Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.

Please try to update tests as appropriate and ensure that documentation is updated if you add any features accessible through the public API.

If you use this library and like it, feel free to sign up to GitHub and star the project, it is greatly appreciated and lets me know that I'm going in the right direction!

Links

hikari-lightbulb's People

Contributors

ahnaf-zamil avatar atomicman007 avatar ben2224 avatar christian-tarello avatar davfsa avatar decxxx avatar dependabot[bot] avatar forbidden-a avatar googlegenius avatar hypergonial avatar ikbenolie5 avatar jonxslays avatar kpostekk avatar lzgirlcat avatar mrsrmn avatar norinorin avatar null-domain avatar parafoxia avatar perchunpak avatar sdf9s8d76f avatar tandemdude avatar thomm-o avatar tmpod avatar yakmm avatar yodapy avatar zeusabhijeet avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

hikari-lightbulb's Issues

`load_extensions_from` does not accept absolute directories

Summary

Submitting as feature request due to #167.

Currently only relative directories can be passed to BotApp.load_extensions_from, and absolute directories should be allowed.

Why is this needed?

It allows more control over the directories people pass, and also accounts for certain Pathlib methods returning absolute paths.

Ideal implementation

I know how this can be done and will contribute it.

Checklist

  • I have searched the issue tracker and have made sure it's not a duplicate. If it is a follow up of another issue, I have specified it.

Be able to set a default list of guilds for enabled guilds

Summary

Currently, you need to provide what guilds a slash command works in per command. If not provided, the default is None, however there is no default for setting a single guild or a list of guilds for every command like there is in Tanjun.

Problem

It would mean the user doesn't have to set it for every command, and update every single command should they need to, but instead just change one line.

Ideal implementation

In the lightbulb.Bot constructor, where any subclassed object would pass the list in through the init. None would remain the default. I have an idea of how this will work and will attempt to PR this in in the next few days, providing I can actually manage to do it.

Checklist

  • I have searched the issue tracker and have made sure it's not a duplicate.
    If it is a follow up of another issue, I have specified it.

The ability to add all slash commands from a file in one command

Summary

Currently, when loading an extension, you need to add all slash commands in that extension manually, or create something like the following to do it automatically:

import inspect
import sys

from lightbulb import slash_commands

...

def load(bot) -> None:
    for _, obj in inspect.getmembers(sys.modules[__name__], inspect.isclass):
        if issubclass(obj, slash_commands.SlashCommand):
            bot.add_slash_command(obj)

It would be nice to abstract this away from the user in some nice and convenient way, but as I elude to later, I am not positive there is an "ideal" implementation for something like this.

Problem

There isn't really a problem, per se, but would allow for extra convenience on the user's side, as many would like to have the autoscan method.

Ideal implementation

I'm not sure. Either some load_slash_commands equivalent of load_extensions (which would remove the ability for custom behaviours, potentially), or a method in the slash_commands (maybe something like auto_load) that can scan the current file for slash commands and add them (though this may be unintuitive).

Checklist

  • I have searched the issue tracker and have made sure it's not a duplicate.
    If it is a follow up of another issue, I have specified it.

Add max concurrency limit option

Summary

This command decorator should allow for the command to only have x running instances per the specified bucket, and raise an error if this limit was exceeded.

Why is this needed?

This feature would be extremely nice for commands that should not run more than one at a time (for example a typeracing command, where only a maximum of one instance of the command should be running in a channel at any given time), or commands that rely on their state not being altered by a different instance of themselves.

Ideal implementation

Example syntax:

@bot.command()
# A maximum of one instance per channel
@lightbulb.max_concurrency(1, lightbulb.ChannelBucket)
@lightbulb.command("thommo", "based")
@lightbulb.implements(...)
async def foo(ctx: lightbulb.Context) -> None:
    await asyncio.sleep(10.0) # Long operation
    await ctx.respond("foo")

Trying to execute a command that exceeded it's max concurrency should raise an error (for example: lightbulb.MaxConcurrencyReachedError) with information about the max uses & bucket-type used included in the exception.

Checklist

  • I have searched the issue tracker and have made sure it's not a duplicate. If it is a follow up of another issue, I have specified it.

Make slash command errors more descriptive

Summary

Slash command errors during creation are not very descriptive currently. Create more exception classes to
describe why creation may fail.

Problem

Ideal implementation

Checklist

  • I have searched the issue tracker and have made sure it's not a duplicate.
    If it is a follow up of another issue, I have specified it.

Error when passing integer instead of MessageFlag to Context.respond

Steps to reproduce

Try to use flags=64 in response instead of passing a flag object

Expected result

Flags should be applied correctly

Actual result

It errors

System info

hikari-lightbulb (2.2.0)

Further info

No response

Checklist

  • I have made sure to remove ANY sensitive information (bot token, passwords, credentials, personal details, etc.).
  • I have searched the issue tracker and have made sure it's not a duplicate. If it is a follow up of another issue, I have specified it.

Typo in method name

Steps to reproduce

https://github.com/tandemdude/hikari-lightbulb/blob/development/lightbulb/app.py#L275
https://github.com/tandemdude/hikari-lightbulb/blob/development/lightbulb/app.py#L968

Expected result

handle_message_create_for_prefix_commands

Actual result

handle_messsage_create_for_prefix_commands

System info

Irrelevant

Further info

Not gonna bother with a PR cos of how simple this is haha.

Checklist

  • I have made sure to remove ANY sensitive information (bot token, passwords, credentials, personal details, etc.).
  • I have searched the issue tracker and have made sure it's not a duplicate. If it is a follow up of another issue, I have specified it.

Consider managing application commands atomically

Summary

This allows lightbulb-based apps to sync application commands with as few requests as possible.

Why is this needed?

While it compares the local and the registered commands so that it won't make unnecessary requests, it's still gonna spam the API on first syncing (all commands are new and to be registered) or when there are many commands the metadata of which got changed. Using the PUT method instead would be nice for several reasons: no need to compare the commands and see if they change since it's bulk overwriting them; it's atomic, it may/may not be helpful if the bot goes down during the commands managing; fewer requests being made, getting rate limited could be avoided here.

Ideal implementation

We can leave the non-atomic function at that and have an option for the atomic one, or just completely ditch it.

Checklist

  • I have searched the issue tracker and have made sure it's not a duplicate. If it is a follow up of another issue, I have specified it.

Allow an option to not have command options auto resolve

Summary

Allow users to choose whether or not lightbulb auto resolves command options like hikari.User

Why is this needed?

Allow users more control, if they want to fetch the options themselves maybe

Ideal implementation

Probably adding an auto_resolve=False kwarg to command decorators, which defaults to True

Checklist

  • I have searched the issue tracker and have made sure it's not a duplicate. If it is a follow up of another issue, I have specified it.

Implement dark mode for docs

Summary

Add an extension that allows for the standard RTD theme to have a togglable dark mode.

Problem

Docs were only in light mode, when a lot of people would like to have a dark mode available.

Ideal implementation

I'm gonna make a PR for this in a bit.

Checklist

  • I have searched the issue tracker and have made sure it's not a duplicate.
    If it is a follow up of another issue, I have specified it.

Slash command checks

Summary

Implement a method to run checks prior to slash command execution, similar in function to how command
checks currently work.

Problem

Ideal implementation

Checklist

  • I have searched the issue tracker and have made sure it's not a duplicate.
    If it is a follow up of another issue, I have specified it.

Change dynamic cooldown callbacks return type to optional

Summary

The return type of dynamic cooldown callbacks should be an Optional. This would essentially disable the cooldown for the given condition.

Problem

At the moment, it's still unpractical to lift any invocation rate restrictions on specific people, roles, or any predicate in general. The dynamic_cooldown utility was a nice addition, but one still has to write a custom manager in order to achieve that behaviour.

Ideal implementation

Some type signatures would have to change and the implementation of add_cooldown would have to return early if the result of _get_bucket is None.

Checklist

  • I have searched the issue tracker and have made sure it's not a duplicate.
    If it is a follow up of another issue, I have specified it.

Slash command cooldowns

Summary

Implement a method to run checks prior to slash command execution, similar in function to how command
cooldowns currently work.

Problem

Ideal implementation

Checklist

  • I have searched the issue tracker and have made sure it's not a duplicate.
    If it is a follow up of another issue, I have specified it.

pycharm does not recognize lightbulb module

Steps to reproduce

  1. i ran the pip install hikari-lightbulb
  2. restarted pycharm
  3. and tried to import lightbulb

Expected result

.

Actual result

lightbulb not recognized

System info

Traceback (most recent call last):
  File "C:\Users\xxxx\xxx\xxx\folders\discord_bot_py\bot.py", line 3, in <module>
    import lightbulb
ModuleNotFoundError: No module named 'lightbulb'

Further info

havent tried it on visual studio code but i expect the same result

Checklist

  • I have made sure to remove ANY sensitive information (bot token, passwords, credentials, personal details, etc.).
  • I have searched the issue tracker and have made sure it's not a duplicate. If it is a follow up of another issue, I have specified it.

pass_options passes command name as option in SlashSubCommand

Steps to reproduce

  1. Create a SlashSubCommand
  2. Add the pass_options=True modifier
  3. Call the command

Expected result

Only the options specified via @lightbulb.option get passed.

Actual result

The command name is also passed as a kwarg.

System info

hikari-lightbulb (2.2.1)
hikari (2.0.0.dev108) [HEAD]
located at /home/hyper/.local/lib/python3.10/site-packages/hikari
CPython 3.10.2 GCC 11.1.0
Linux archlinux 5.16.12-zen1-1-zen #1 ZEN SMP PREEMPT Wed, 02 Mar 2022 12:22:53 +0000 x86_64

Further info

No response

Checklist

  • I have made sure to remove ANY sensitive information (bot token, passwords, credentials, personal details, etc.).
  • I have searched the issue tracker and have made sure it's not a duplicate. If it is a follow up of another issue, I have specified it.

The bug report template is broken

Summary

The system-info textarea field has the render attribute incorrectly indented.

Why is this needed?

So people can write bug reports d:

Ideal implementation

render keys should be in attributes.

Checklist

  • I have searched the issue tracker and have made sure it's not a duplicate. If it is a follow up of another issue, I have specified it.

Add ability to load extensions from a directory

Summary

Currently the load extension command can only accept a list of import strings, though passing in a series of Path objects (or even a series of os.PathLike type objects) could simplify this process and negate the need to use sometimes awkward import strings.

Problem

The issue here isn't massive -- it's mainly bringing over an, in my opinion, really nice feature in Tanjun.

Ideal implementation

Add a load_extensions method to accept a list of Path or os.Pathlike objects, as well as import strings. This would change user code like so:

Before:

commands = Path("./lightbulb_bot/commands").glob("*.py")

for c in commands:
    bot.load_extension(f"lightbulb_bot.commands.{c.stem}")

After:

bot.load_extensions(Path("./lightbulb_bot/commands").glob("*.py"))

Or even potentially:

bot.load_extensions("./lightbulb/commands")

I could probably PR this as well, as I think it wouldn't be amazingly hard. It would just depend on how the exact implementation worked out in the end.

Checklist

  • I have searched the issue tracker and have made sure it's not a duplicate.
    If it is a follow up of another issue, I have specified it.

Adding a new navigator for use in slash commands with buttons

Summary

Adding a new navigator for use in slash commands utilising buttons.
This is a new class called SlashNavigation, and works with pages from both StringPaginator and EmbedPaginator

Problem

Solves the fact that StringNavigation and EmbedNavigation can't be used within slash commands

Ideal implementation

Implemented on my fork here: https://github.com/neonjonn/hikari-lightbulb

Checklist

  • I have searched the issue tracker and have made sure it's not a duplicate.
    If it is a follow up of another issue, I have specified it.

CONSUME_REST prepends space to options after the first.

Steps to reproduce

  1. Create a command group.
  2. Give a subcommand 2 options.
  3. First option has no modifier.
  4. Second option has OptionModifier.CONSUME_REST
  5. Run the command with arg1 = beanos
  6. Run the command with arg2 = my second arg
  7. Print the repr of the args in the callback.
test = lightbulb.Plugin("test")

@test.command
@lightbulb.command("test", "Test command")
@lightbulb.implements(lightbulb.PrefixCommandGroup)
async def test_parent_command(_: lightbulb.PrefixContext) -> None:
    ...

@test_parent_command.child
@lightbulb.option("arg2", "The second arg.", modifier=lightbulb.OptionModifier.CONSUME_REST)
@lightbulb.option("arg1", "The first arg.")
@lightbulb.command("sub", "Run the subcommand.")
@lightbulb.implements(lightbulb.PrefixSubCommand)
async def test_sub_command(ctx: lightbulb.PrefixContext) -> None:
    print(repr(ctx.options.arg1))
    print(repr(ctx.options.arg2))

Expected result

'beanos'
'my second arg'

Actual result

'beanos'
' my second arg'

A space is prepended to the second arg.

System info

hikari-lightbulb (2.2.0)
hikari (2.0.0.dev107) [8ef27c29]
located at /home/jonx/projects/py/Starr/.venv/lib/python3.10/site-packages/hikari
CPython 3.10.2 GCC 11.1.0
Linux love 5.15.24-1-lts #1 SMP Wed, 16 Feb 2022 16:04:21 +0000 x86_64

Further info

Parsing wonkyness is happening it appears. :beanos:

Checklist

  • I have made sure to remove ANY sensitive information (bot token, passwords, credentials, personal details, etc.).
  • I have searched the issue tracker and have made sure it's not a duplicate. If it is a follow up of another issue, I have specified it.

Extension errors do not output a message when thrown

Steps to reproduce

One way to do this is attempting to unload an extension that doesn't exist.

Expected Result

An error with a full text output.

Actual Result

image

System info

Windows 10 (WSL, Debian 11)
Python 3.9.7
Lightbulb @ development

Checklist

  • I have made sure to remove ANY sensitive information (bot token, passwords,
    credentials, personal details, etc).
  • I have searched the issue tracker and have made sure it's not a duplicate.
    If it is a follow up of another issue, I have specified it.

issue with bot has guild permissions check

This is similar to #102 I suppose.

Steps to reproduce

@lightbulb.checks.bot_has_guild_permissions(Permissions.MANAGE_CHANNELS)
@lightbulb.command()
async def test(self, ctx: lightbulb.Context):
    await ctx.respond('test')โ€Š

Expected Result

The command works if the user has manage channel permissions or administrator.

Actual Result

If the bot has admin with no other perms it works, if i give it manage channel perms without admin it works, but if i give it both admin and manage channels it doesn't work.

proof of permission + error:
unknown
(shows a list of the bots permissions)

unknown
(the equivalent of an error using an error handler)

Checklist

  • I have made sure to remove ANY sensitive information (bot token, passwords,
    credentials, personal details, etc).
  • I have searched the issue tracker and have made sure it's not a duplicate.
    If it is a follow up of another issue, I have specified it.

Docs Enchancement

Summary

Better readability and less confusion

Problem

Added a warning box that warns about some of the less known slash commands mechanics
that are undocumented here

Subcommands not inheriting plugin checks

Steps to reproduce

  1. Create prefix command
  2. Create subcommand, pass inherit_checks=True into command wrapper
  3. plugin.add_checks(lightbulb.owner_only) in the load() function

Expected result

  • Calling the parent command and sub command should result in lightbulb.errors.NotOwner getting thrown

Actual result

  • Calling the parent command forces lightbulb.errors.NotOwner to get thrown, but calling its sub command doesn't throw that error and instead executes the command successfully without any errors

System info

hikari-lightbulb (2.1.2)
hikari (2.0.0.dev104) [HEAD]
located at C:\Users\{UserName}\AppData\Local\Programs\Python\Python39\lib\site-packages\hikari
CPython 3.9.5 MSC v.1928 64 bit (AMD64)
Windows DESKTOP-62T69ZP 10 10.0.19043 AMD64 AMD64 Family 23 Model 1 Stepping 1, AuthenticAMD

Further info

No response

Checklist

  • I have made sure to remove ANY sensitive information (bot token, passwords, credentials, personal details, etc.).
  • I have searched the issue tracker and have made sure it's not a duplicate. If it is a follow up of another issue, I have specified it.

Make hikari-lightbulb fully compliant with mypy

Summary

The project should be fully compliant with mypy's type checking.

Problem

Ideal implementation

Checklist

  • I have searched the issue tracker and have made sure it's not a duplicate.
    If it is a follow up of another issue, I have specified it.

IndexError exception raised when someone sends the prefix alone

Steps to reproduce

1.Make a bot with the prefix ! for example, and run it.
2.go to a channel the bot has access to.
3.send ! (your prefix)
4.check your console output

Expected Result

On Message event is processed by my listeners, but ignored by lightbulb command processing

Actual Result

On message event is processed by my listeners after raising an error due to lightbulb command handler trying to process it

System info

Python 3.9.1 latest lightbulb version

Further info

Traceback (most recent call last):
  File "/home/forbidden/Documents/python-projects/Yotta/.venv/lib/python3.9/site-packages/lightbulb/command_handler.py", line 903, in handle
    await self.process_commands_for_event(event)
  File "/home/forbidden/Documents/python-projects/Yotta/.venv/lib/python3.9/site-packages/lightbulb/command_handler.py", line 826, in process_commands_for_event
    command = self._validate_command_exists(invoked_with)
  File "/home/forbidden/Documents/python-projects/Yotta/.venv/lib/python3.9/site-packages/lightbulb/command_handler.py", line 740, in _validate_command_exists
    if (command := self.get_command(invoked_with)) is not None:
  File "/home/forbidden/Documents/python-projects/Yotta/.venv/lib/python3.9/site-packages/lightbulb/command_handler.py", line 442, in get_command
    this = self._commands.get(tokens.pop(0))
IndexError: pop from empty list

Checklist

  • I have made sure to remove ANY sensitive information (bot token, passwords,
    credentials, personal details, etc).
  • I have searched the issue tracker and have made sure it's not a duplicate.
    If it is a follow up of another issue, I have specified it.

DefaultHelpCommand shows plugins that are not supposed to be shown to the user (user failed plugin checks)

Steps to reproduce

  1. Use the DefaultHelpCommand
  2. Have a plugin check fail in a certain guild
  3. Execute [prefix]help in that certain guild

Expected result

The plugin which fails their checks should not be showing on the main page of the DefaultHelpCommand (because there is no use for it)

Actual result

The plugin which fails their checks still show up on the main page of the DefaultHelpCommand

System info

hikari-lightbulb (2.2.0)
hikari (2.0.0.dev107) [HEAD]
located at /usr/local/lib/python3.9/site-packages/hikari
CPython 3.9.7 GCC 11.2.0
Linux aa157632c23e 5.10.0-9-amd64 #1 SMP Debian 5.10.70-1 (2021-09-30) x86_64 x86_64

Further info

No response

Checklist

  • I have made sure to remove ANY sensitive information (bot token, passwords, credentials, personal details, etc.).
  • I have searched the issue tracker and have made sure it's not a duplicate. If it is a follow up of another issue, I have specified it.

Slash Command Variable Arguments

Summary

A way to specify variable arguments for slash commands.

Why is this needed?

While splitting a string argument and parsing it manually is not too difficult, using a string argument removes some really nice features of slash commands like auto-complete for most types. It also makes it much harder for a user to specify things like users with names that are not one word or have unusual characters.

Alternatively, manually adding the max number of options to a command and treating it like varargs takes a lot of lines of code and makes it much harder to read. Not to mention, actually collecting every option into a list or tuple for iteration is also very hard to read and tedious.

Ideal implementation

With a decorator like @lightbulb.option('users', 'A bunch of users', List[hikari.User]) or @lightbulb.option('users', 'A bunch of users', hikari.User, variable_args=True). Then context.options.users would have a list of the specified users.

Internally, I believe it could function like this. Register the slash command as having 25 optional options of the correct type (or less if other non-variable arguments are given), and collect as many that were input into a list or tuple in the context.

A not very internal workaround I am currently using is as follows for a command foo to have variable numbers of User arguments. It would have to be adjusted when collected arguments to only get the ones of type User.

while len(foo.options) < 25:
    option(f'user{len(foo.options)}', 'Bar?', User, required=False)(foo)

async def foo(context):
    users = filter(None, context.options._options.values())

Checklist

  • I have searched the issue tracker and have made sure it's not a duplicate. If it is a follow up of another issue, I have specified it.

Replace issue templates with issue forms

Summary

See hikari-py/hikari#884 -- the proposition is the same, really. I am also prepared to do this if you want. I think the Lightbulb templates are basically the same as Hikari's, so should be pretty easy to port.

Checklist

  • I have searched the issue tracker and have made sure it's not a duplicate.
    If it is a follow up of another issue, I have specified it.

Latest development branch - Issue at import lightbulb command

Steps to reproduce

With the latest development branch I'm facing an issue at the import lightbulb command itself. I'm seeing a AttributeError: module 'hikari' has no attribute 'AutocompleteInteraction'. This was resolved when I installed older version of the development branch.

Replication:

  1. Install latest lightbulb development branch from git.
    pip install git+https://github.com/tandemdude/hikari-lightbulb@development
  2. Use import lightbulb in your code.
  3. You'll get an error when you run your code.
    image

Expected result

There shouldn't be any error at import lightbulb command when development branch is used

Actual result

With the current version we are getting AttributeError: module 'hikari' has no attribute 'AutocompleteInteraction' error.

Error's Traceback:
Traceback (most recent call last): File "C:\DiscordBot\bot.py", line 3, in <module> import lightbulb File "C:\Users\user\AppData\Local\Programs\Python\Python310\lib\site-packages \lightbulb\__init__.py", line 153, in <module> from lightbulb import app File "C:\Users\user\AppData\Local\Programs\Python\Python310\lib\site-packages \lightbulb\app.py", line 42, in <module> from lightbulb import decorators File "C:\Users\user\AppData\Local\Programs\Python\Python310\lib\site-packages \lightbulb\decorators.py", line 39, in <module> [hikari.CommandInteractionOption, hikari.AutocompleteInteraction], AttributeError: module 'hikari' has no attribute 'AutocompleteInteraction'

image

System info

python -m lightbulb output:

Traceback (most recent call last):
  File "C:\Python\Python310\lib\runpy.py", line 187, in _run_module_as_main
    mod_name, mod_spec, code = _get_module_details(mod_name, _Error)
  File "C:\Python\Python310\lib\runpy.py", line 146, in _get_module_details
    return _get_module_details(pkg_main_name, error)
  File "C:\Python\Python310\lib\runpy.py", line 110, in _get_module_details
    __import__(pkg_name)
  File "C:\Python\Python310\lib\site-packages\lightbulb\__init__.py", line 153, in <module>
    from lightbulb import app
  File "C:\Python\Python310\lib\site-packages\lightbulb\app.py", line 42, in <module>
    from lightbulb import decorators
  File "C:\Python\Python310\lib\site-packages\lightbulb\decorators.py", line 39, in <module>
    [hikari.CommandInteractionOption, hikari.AutocompleteInteraction],
AttributeError: module 'hikari' has no attribute 'AutocompleteInteraction'

Further info

No response

Checklist

  • I have made sure to remove ANY sensitive information (bot token, passwords, credentials, personal details, etc.).
  • I have searched the issue tracker and have made sure it's not a duplicate. If it is a follow up of another issue, I have specified it.

Black- and whitelist check to make black- and whitelists command independent

Summary

A black- and whitelist check where you would be able to put a list of userids into and those people wouldn't or would be able to use the command.

Problem

This makes black- and whitelists command independent and you won't have to check in the command itself.

Ideal implementation

@checks.blacklist(user_ids=[...], role_ids=[...], guild_ids=[...], channel_ids=[...])

@checks.whitelist(user_ids=[...], role_ids=[...], guild_ids=[...], channel_ids=[...])

Checklist

  • I have searched the issue tracker and have made sure it's not a duplicate.
  • If it is a follow up of another issue, I have specified it.

Allow us to access each member's permissions

Summary

Just like in discord.py where we can access/know what permissions the member/user has by doing member.permissions.MANAGE_GUILD or something like that.

Problem

We had to loop through each member's permissions, it's tedious and very time-consuming!

Guild specific plugins

Summary

Currently you can only have commands configurable for guilds per-command or for all commands.

I propose adding functionality to make plugins configurable on a per guild basis like how you can pass guild ids into individual commands.

Why is this needed?

This would allow devs to, instead of having to list the enabled guilds for each command in a plugin, they can set it up from the plugin and not have to worry about ensuring each command has the correct guild ids passed into them.

Ideal implementation

I think it would be best done when initializing the class, the same way its done for commands
plugin = lightbulb.Plugin("Management", guilds = [<id 1>, <id 2>])

Checklist

  • I have searched the issue tracker and have made sure it's not a duplicate. If it is a follow up of another issue, I have specified it.

Setting a default of 0 to an integer option sets the option to `None` instead

Summary

@plugin.command()
@lightbulb.option("bonus", "A fixed number to add to the total roll.", int, default=0)
@lightbulb.option("sides", "The number of sides each die will have.", int, default=6)
@lightbulb.option("number", "The number of dice to roll.", int)
@lightbulb.command("dice", "Roll one or more dice.")
@lightbulb.implements(commands.PrefixCommand, commands.SlashCommand)
async def dice(ctx) -> None:
    print(ctx.options.number)
    print(ctx.options.sides)
    print(ctx.options.bonus)

/dice 6 -> 6 6 None

@plugin.command()
@lightbulb.option("bonus", "A fixed number to add to the total roll.", int, default=1)
@lightbulb.option("sides", "The number of sides each die will have.", int, default=6)
@lightbulb.option("number", "The number of dice to roll.", int)
@lightbulb.command("dice", "Roll one or more dice.")
@lightbulb.implements(commands.PrefixCommand, commands.SlashCommand)
async def dice(ctx) -> None:
    print(ctx.options.number)
    print(ctx.options.sides)
    print(ctx.options.bonus)

/dice 6 -> 6 6 1

Why is this needed?

The expected behaviour should see bonus == 0.

Ideal implementation

To be decided.

Checklist

  • I have searched the issue tracker and have made sure it's not a duplicate. If it is a follow up of another issue, I have specified it.

Custom Cooldowns

Summary

Allow for dynamic cooldowns that vary based on a given predicate

Ideal implementation

def predicate(ctx: Context) -> Cooldown:
    if ctx.author_id == 123456789:
        return Cooldown(60, 1, UserBucket)

@custom_cooldown(predicate)
@command()
async def test(ctx: Context) -> None: ...

Checklist

  • I have searched the issue tracker and have made sure it's not a duplicate.
    If it is a follow up of another issue, I have specified it.

Rename permission check

Summary

Rename the bot_has_permissions check to bot_has_channel_permissions for consistency with bot_has_guild_permissions

Problem

Inconsistency and confusion

Ideal implementation

Rename the functions

Checklist

  • I have searched the issue tracker and have made sure it's not a duplicate.
    If it is a follow up of another issue, I have specified it.

Reloading plugin raises "Command is already registered" on L481

Steps to reproduce

  1. Clone down https://github.com/PythonTryHard/repro (will be archived after issue closes)
  2. Run bot.py from inside the directory

Expected result

The bot reloading the extension normally.

Actual result

โžœ python .\bot.py
I 2022-02-02 16:08:17,474 lightbulb.app: Extension loaded 'repro.command.sanity'
I 2022-02-02 16:08:17,478 lightbulb.app: Extension unloaded 'repro.command.sanity'
Traceback (most recent call last):
  File "F:\dev\.env\remi-0WewpwuQ-py3.10\lib\site-packages\lightbulb\app.py", line 481, in reload_extensions
    self.load_extensions(extension)
  File "F:\dev\.env\remi-0WewpwuQ-py3.10\lib\site-packages\lightbulb\app.py", line 412, in load_extensions
    ext.load(self)
  File "F:\dev\remi\repro\command\sanity\__init__.py", line 10, in load
    bot.add_plugin(sanity_plugin)
  File "F:\dev\.env\remi-0WewpwuQ-py3.10\lib\site-packages\lightbulb\app.py", line 814, in add_plugin
    self._add_command_to_correct_attr(command)
  File "F:\dev\.env\remi-0WewpwuQ-py3.10\lib\site-packages\lightbulb\app.py", line 316, in _add_command_to_correct_attr
    raise errors.CommandAlreadyExists(
lightbulb.errors.CommandAlreadyExists: A prefix command with name or alias 'sanity' is already registered.

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "F:\dev\remi\repro\bot.py", line 30, in <module>
    bot.reload_extensions("repro.command.sanity")
  File "F:\dev\.env\remi-0WewpwuQ-py3.10\lib\site-packages\lightbulb\app.py", line 485, in reload_extensions
    self.load_extensions(extension)
  File "F:\dev\.env\remi-0WewpwuQ-py3.10\lib\site-packages\lightbulb\app.py", line 412, in load_extensions
    ext.load(self)
  File "F:\dev\remi\repro\command\sanity\__init__.py", line 10, in load
    bot.add_plugin(sanity_plugin)
  File "F:\dev\.env\remi-0WewpwuQ-py3.10\lib\site-packages\lightbulb\app.py", line 814, in add_plugin
    self._add_command_to_correct_attr(command)
  File "F:\dev\.env\remi-0WewpwuQ-py3.10\lib\site-packages\lightbulb\app.py", line 316, in _add_command_to_correct_attr
    raise errors.CommandAlreadyExists(
lightbulb.errors.CommandAlreadyExists: A prefix command with name or alias 'sanity' is already registered.

System info

hikari-lightbulb (2.1.3)
hikari (2.0.0.dev105) [a3825788]
located at F:\dev\.env\remi-0WewpwuQ-py3.10\lib\site-packages\hikari
CPython 3.10.0 MSC v.1929 64 bit (AMD64)
Windows Sewa 10 10.0.19043 AMD64 Intel64 Family 6 Model 61 Stepping 4, GenuineIntel

Further info

When I first debugged the issue, I focused on sys.modules as I thought it held information on what are being loaded in. With the debugger console, I ran pprint([i for i in sys.modules if "repro" in i]) to check the load status and got the following:

  • (in repro/bot.py) Before loading sanity extension:
[]
  • (in repro/bot.py) After loading sanity extension, before reloading:
['repro',
 'repro.command.sanity.sanity',
 'repro.command.sanity',
 'repro.command']
  • (in lightbulb/app.py) After unloading sanity extension @ L480:
['repro', 'repro.command.sanity.sanity', 'repro.command']

Checklist

  • I have made sure to remove ANY sensitive information (bot token, passwords, credentials, personal details, etc.).
  • I have searched the issue tracker and have made sure it's not a duplicate. If it is a follow up of another issue, I have specified it.

Greedy converters

Summary

Currently converters can only take one of a particular object at one time. It would be good for there to be some sort of greedy converter functionality, similar to d.py, that could take multiple of a single object type and put it in a list.

Problem

See above.

Ideal implementation

async def command(self, ctx, targets: lightbulb.greedy_member_converter):
    print(type(targets))

# Output:
<class 'list'> (or even tuple)

Or something like that. I'll leave you to decide how you think it would work best.

Checklist

  • I have searched the issue tracker and have made sure it's not a duplicate.
    If it is a follow up of another issue, I have specified it.

Add more properties to errors

Summary

Add more properties to errors to make it easier to create custom error messages. e.g. lightbulb.errors.NSFWChannelOnly would have a command property and a channel property etc

Problem

Make it easier to create custom error messages

Ideal implementation

just CommandErrorEvent.exception.command etc

Checklist

  • I have searched the issue tracker and have made sure it's not a duplicate.
    If it is a follow up of another issue, I have specified it.

role converter doesn't convert mentions

Steps to reproduce

async def command(ctx, role: role_converter) -> None:
    pass

Pass in a role mention for the role argument

Expected Result

The mention should get converted to a role object

Actual Result

An error (ConverterFailure) is raised

System info

Lightbulb 57

Checklist

  • I have made sure to remove ANY sensitive information (bot token, passwords,
    credentials, personal details, etc).
  • I have searched the issue tracker and have made sure it's not a duplicate.
    If it is a follow up of another issue, I have specified it.

Add logging when loading and unloading extensions

Summary

A logging kwarg to output when an extension loads to the terminal.

Problem

When loading extensions manually in a for loop, it's very easy to add your own logs. However, this is not the case with load_extensions_from.

Ideal implementation

BotApp.load_extensions_from(..., log=False)

or

BotApp.load_extensions_from(..., output=False)

As load_extension does not log automatically, having this kwarg default to False would keep it consistent.

I plan to add this myself.

Checklist

  • I have searched the issue tracker and have made sure it's not a duplicate.
    If it is a follow up of another issue, I have specified it.

has_permissions not checking the specified check from the author, returning error instead

Steps to reproduce

Had a test command running up, Having the lightbulb.has_permissions(hikari.Permissions.MANAGE_MESSAGES) as the check for my subcommand set

    @lightbulb.group()
    async def prefix(self, ctx: lightbulb.Context):
        pass

    @lightbulb.has_permissions(hikari.Permissions.MANAGE_MESSAGES)
    @prefix.command(name="set")
    async def set(self, ctx: lightbulb.Context, prefix: str):
        await ctx.respond('test')

Expected Result

Should have checked whether the author has MANAGE_MESSAGES permissions and worked for every guy having manage messages permissions and other higher role with greater permissions..

Actual Result

Despite of having admin, the command didn't work returning an error that the author doesn't have permissions

Checklist

  • I have made sure to remove ANY sensitive information (bot token, passwords,
    credentials, personal details, etc).
  • I have searched the issue tracker and have made sure it's not a duplicate.
    If it is a follow up of another issue, I have specified it.

Make install dev requirements easier

Summary

Currently you install from requirements.txt, then install nox and everything separately. A single dev_requirements.txt would make it a lot easier to contribute.

I'll work on this now.

Checklist

  • I have searched the issue tracker and have made sure it's not a duplicate.
    If it is a follow up of another issue, I have specified it.

Features to add in lightbulb V2

Summary

Features that should be added in lightbulb V2. Please comment on this issue with anything you would like to see added during the rewrite.

Please check the TODO list before adding your suggestion as it may already be written there.

Problem

I want to know what people would like to see from the lightbulb rewrite.

Ideal implementation

I'll figure it out later ๐Ÿ˜‰

Checklist

  • I have searched the issue tracker and have made sure it's not a duplicate.
    If it is a follow up of another issue, I have specified it.

check fails with admin permissions

Steps to reproduce

The has_guild_permissions check is not passing when the command invoker has admin permissions

@has_guild_permissions(hikari.Permissions.MANAGE_NICKNAMES)
@command()
async def command(ctx) -> None:
    pass

Invoke the command with admin permissions

Expected Result

Check should have passed

Actual Result

Check fails and raises MissingRequiredPermission

System info

Most recent lightbulb dev version

Checklist

  • I have made sure to remove ANY sensitive information (bot token, passwords,
    credentials, personal details, etc).
  • I have searched the issue tracker and have made sure it's not a duplicate.
    If it is a follow up of another issue, I have specified it.

`KeyError` thrown from reload_extensions() when trying to reload an unloaded extensions

Steps to reproduce

Note: sanity is a valid plugin.

bot = lightbulb.BotApp(token="token here", prefix='!', banner=None)
bot.reload_extensions("sanity")

Expected result

lightbulb.ExtensionNotLoaded or similar exceptions gets thrown

Actual result

KeyError gets thrown, as seen below:

Python 3.10.0 (default, Dec  1 2021, 23:25:09) [GCC 9.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import hikari
>>> import lightbulb
>>>
>>> bot = lightbulb.BotApp(token="token here", prefix='!', banner=None)
>>> bot.reload_extensions("sanity")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/my_username/.env/remi-1yTFt6OI-py3.10/lib/python3.10/site-packages/lightbulb/app.py", line 478, in reload_extensions
    old = sys.modules[extension]
KeyError: 'sanity'

System info

hikari-lightbulb (2.1.3)
hikari (2.0.0.dev105) [a3825788]
located at /home/my_username/.env/remi-1yTFt6OI-py3.10/lib/python3.10/site-packages/hikari
CPython 3.10.0 GCC 9.3.0
Linux h1mm3l 5.13.0-22-lowlatency #22~20.04.1-Ubuntu SMP PREEMPT Tue Nov 9 16:34:04 UTC 2021 x86_64 x86_64

Further info

No response

Checklist

  • I have made sure to remove ANY sensitive information (bot token, passwords, credentials, personal details, etc.).
  • I have searched the issue tracker and have made sure it's not a duplicate. If it is a follow up of another issue, I have specified it.

Exceptions missing parameters

The ones I could find are:

  • ExtensionMissingLoad
  • ExtensionMissingUnload
  • ExtensionNotLoaded
  • ExtensionAreladyLoaded
  • ConverterFailure
    probably more but cba list em all

Original

Command error exception is empty

I have a simple error handler for my bot whenever an error occurs. This code used to work when I used 0.0.53 but after updating to 0.0.55, it broke.

@lightbulb.listener(lightbulb.events.CommandErrorEvent)
async def on_command_error(self, event):
    channel = await self.bot.rest.fetch_channel(event.message.channel_id)
    await channel.send(f"An error occured: {event.exception}")
    return

Before update it worked,
Screenshot_from_2020-11-17_12-17-58

But after update, it doesn't work,
Screenshot_from_2020-11-17_12-29-13

Original

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.