Skip to content

Soheab/discord-ext-subcommands

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

4 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

discord-ext-subcommands

Python Version discord.py Version License: MPL 2.0

A powerful Discord.py extension that revolutionizes command organization by allowing you to define subcommands across multiple files and cogs. Say goodbye to monolithic command files and embrace modular, maintainable bot architecture.

Table of Contents

Why Use This?

🎯 Modular Organization: Split large command groups across multiple files for better code organization
πŸ”§ Easy Maintenance: Each subcommand lives in its own logical cog, making updates and debugging simpler
πŸ”„ Flexible: Works seamlessly with prefix commands, slash commands, and hybrid commands
πŸ“ Clean Architecture: Keep related functionality together while maintaining separation of concerns
⚑ Automatic Management: Handles the complex task of connecting subcommands to their parent groups automatically

Perfect for large bots where command groups become unwieldy when defined in a single file!

Installation

This extension is not available on PyPI, so you need to install it directly from the GitHub repository. Use the following command:

Requirements

  • Python 3.12+
  • git
python -m pip install "discord-ext-subcommands @ git+https://github.com/soheab/discord-ext-subcommands"

Inspiration

This project is based on pycord-multicog by @Dorukyum and adapted for discord.py.

Quick Start

import discord
from discord.ext import commands
from discord.ext.subcommands import MultiFilesSubcommandsManager, subcommand

# Main bot file
bot = commands.Bot(..)
manager = MultiFilesSubcommandsManager(bot)

# Create a command group
@bot.hybrid_group(name="admin")
async def admin_group(ctx):
    """Administrative commands"""
    pass

# In a separate cog file
class ModerationCog(commands.Cog):
    def __init__(self, bot):
        self.bot = bot

    @subcommand("admin")  # This will be attached to the admin group
    @commands.hybrid_command(name="ban")
    async def admin_ban(self, ctx, user: discord.Member, *, reason="No reason provided"):
        """Ban a user from the server"""
        await ctx.send(f"Banned {user.mention} for: {reason}")

async def setup(bot):
    await bot.add_cog(ModerationCog(bot))

πŸ’‘ Tip: This example shows how you can keep your main command groups in your bot file while distributing related subcommands across multiple cog files, making your code more organized and maintainable.

Usage Guide

Step-by-Step Setup

1. Initialize the Manager

from discord.ext.subcommands import MultiFilesSubcommandsManager

bot = commands.Bot(...)
manager = MultiFilesSubcommandsManager(bot)

2. Create Command Groups

Define your main command groups wherever you like:

@bot.hybrid_group(name="admin")
async def admin_group(ctx):
    """Administrative commands"""
    pass

@bot.group(name="economy")
async def economy_group(ctx):
    """Economy commands"""
    pass

πŸ’‘ Best Practice: Define your main groups in your bot file or a dedicated commands file for better organization.

3. Add Subcommands in Separate Files

Use the @subcommand() decorator to attach commands to existing groups:

from discord.ext.subcommands import subcommand

class EconomyCog(commands.Cog):
    @subcommand("economy")
    @commands.command(name="balance")
    async def check_balance(self, ctx, user: discord.Member = None):
        """Check user's balance"""
        user = user or ctx.author
        await ctx.send(f"{user.name} has 1000 coins")

    @subcommand("economy")
    @commands.command(name="pay")
    async def pay_user(self, ctx, user: discord.Member, amount: int):
        """Pay another user"""
        await ctx.send(f"Paid {amount} coins to {user.mention}")

πŸ”— Key Point: The @subcommand("economy") decorator automatically connects these commands to the economy group defined elsewhere.

4. Nested Groups

You can create complex command hierarchies:

# Main group
@bot.hybrid_group(name="server")
async def server_group(ctx):
    """Server management commands"""
    pass

# Nested group
@server_group.group(name="settings")
async def server_settings_group(ctx):
    """Server settings management"""
    pass

# Can use the subcommand decorator too-
# -if it's not in the same file.
# @subcommand("server")
# @commands.hybrid_group(name="settings")
# async def server_settings_group(ctx):
#     """Server settings management"""
#     pass

# Subcommand for nested group
class ConfigCog(commands.Cog):
    @subcommand("server settings")  # Note: full qualified name
    @commands.hybrid_command(name="prefix")
    async def set_prefix(self, ctx, new_prefix: str):
        """Set the server's command prefix"""
        await ctx.send(f"Prefix set to: {new_prefix}")

πŸ—οΈ Advanced: Use the full qualified name (e.g., "server settings") to target nested groups. The extension handles the hierarchy automatically.

Examples

Check out the examples directory for complete working examples:

  • Basic Bot: Simple setup with extenions that includes all command types

API Reference

MultiFilesSubcommandsManager

The central manager class that orchestrates subcommand organization across your bot.

Constructor Parameters

Parameter Type Default Description
bot commands.Bot Required The bot instance to manage
copy_group_error_handler bool False Copy error handlers from groups to subcommands
check_group_type bool False Enforce group type compatibility

Methods

remove()
Cleanly removes the manager and detaches all subcommands. This is done automatically for a cog when it is removed.

raise_for_remaining_commands()
Raises an error if any subcommands couldn't be attached to their groups. Useful for debugging configuration issues.

@subcommand(group_name)

A decorator that marks a command as a subcommand of an existing group.

Parameters

Parameter Type Description
group_name str The qualified name of the target group (e.g., "admin", "server settings")

Supported Command Types

Command Type Decorator Notes
Prefix Commands @commands.command() Traditional text-based commands
Hybrid Commands @commands.hybrid_command() Both prefix and slash support
Slash Commands @app_commands.command() Discord slash commands only
Command Groups @commands.group() / app_commands.Group For nested command structures

License

This project is licensed under the Mozilla Public License 2.0.


Made with ❀️ for the Discord.py community

Report Bug β€’ Request Feature β€’ Star on GitHub

About

A Discord.py extension for subcommands accross multiple files.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages