Commands
CommandRouter decouples command declaration from the Bot instance. Each command module creates its own router and registers commands against it. The bot merges routers into its registry via attach_router or load_extension.
Usage
from fastapi_interactions import CommandRouter
router = CommandRouter()
@router.command(name="ping", description="Check bot latency")
async def ping(ctx):
return "Pong!"
Guild Commands
Commands can be scoped to a specific guild for instant propagation during development. Global commands can take up to an hour to appear everywhere, making guild-scoped commands ideal for testing.
Pass a guild_id when creating the router:
from fastapi_interactions import CommandRouter
dev_router = CommandRouter(guild_id="123456789")
@dev_router.command(name="test", description="A test command")
async def test(ctx):
return "This command only exists in the test server."
Guild-scoped commands appear immediately in the specified server. When ready for production, create a separate router without a guild_id:
from fastapi_interactions import CommandRouter
prod_router = CommandRouter()
@prod_router.command(name="test", description="A test command")
async def test(ctx):
return "This command is global."
Both routers can coexist:
bot.include_router(dev_router)
bot.include_router(prod_router)
When syncing with bot.sync_commands(), guild-scoped commands are sent to the guild endpoint while global commands are sent to the global endpoint.
Reference
fastapi_interactions.commands.CommandRouter
Source code in fastapi_interactions/commands.py
| class CommandRouter:
def __init__(self, name: str = None, guild_id: Optional[Snowflake] = None):
self.name = name or self.__infer_name()
self.guild_id: Optional[Snowflake] = guild_id
self.commands: dict[str, Command] = {}
def __infer_name(self) -> str:
frame = sys._getframe(2)
return frame.f_globals.get("__name__", "Unknown")
def __len__(self) -> int:
return len(list(self.commands.keys()))
def __str__(self) -> str:
return f"{list(self.commands.keys())}"
def command(self, name: str, description: str) -> None:
"""
Add a slash command to this router.
The decorated function is registered as the handler for the command
and will be included when the router is attached to the application.
Args:
name: Unique command name.
description: User-facing command description.
Example:
```python
@router.command("hello", "Say hello")
async def hello(ctx):
return "Hello!"
```
"""
def decorator(func):
meta = getattr(
func, "_command_meta", CommandMeta(name="", description="", type=1)
)
meta.name = name
meta.description = description
self.commands[name] = Command(
callback=func, meta=meta, guild_id=self.guild_id
)
func.__dict__.pop("_command_meta", None)
return func
return decorator
|
command
command(name: str, description: str) -> None
Add a slash command to this router.
The decorated function is registered as the handler for the command
and will be included when the router is attached to the application.
Parameters:
| Name |
Type |
Description |
Default |
name
|
str
|
|
required
|
description
|
str
|
User-facing command description.
|
required
|
Example
@router.command("hello", "Say hello")
async def hello(ctx):
return "Hello!"
Source code in fastapi_interactions/commands.py
| def command(self, name: str, description: str) -> None:
"""
Add a slash command to this router.
The decorated function is registered as the handler for the command
and will be included when the router is attached to the application.
Args:
name: Unique command name.
description: User-facing command description.
Example:
```python
@router.command("hello", "Say hello")
async def hello(ctx):
return "Hello!"
```
"""
def decorator(func):
meta = getattr(
func, "_command_meta", CommandMeta(name="", description="", type=1)
)
meta.name = name
meta.description = description
self.commands[name] = Command(
callback=func, meta=meta, guild_id=self.guild_id
)
func.__dict__.pop("_command_meta", None)
return func
return decorator
|
fastapi_interactions.commands.Command
dataclass
Source code in fastapi_interactions/commands.py
| @dataclass(slots=True)
class Command:
callback: callable
meta: CommandMeta
guild_id: Optional[Snowflake] = None
|
Source code in fastapi_interactions/commands.py
| @dataclass(slots=True)
class CommandMeta:
name: str
description: str
options: list[CommandOption] = field(default_factory=list)
type: int = 1
def as_payload(self):
return {
"name": self.name,
"description": self.description,
"type": self.type,
"options": [option.as_payload() for option in self.options],
}
|
fastapi_interactions.commands.CommandOption
dataclass
Source code in fastapi_interactions/commands.py
| @dataclass
class CommandOption:
name: str
description: str
type: OptionType = OptionType.STRING
required: bool = True
def as_payload(self):
return {
"name": self.name,
"description": self.description,
"type": self.type,
"required": self.required,
}
|