Creating a Bot
Grace includes a utility script to simplify interaction with your bot. Running grace --help displays all available commands. Outside of a project directory, only grace new is available — the rest require a generated project to run from (they import bot.app/bot.bot, see the CLI reference).
Generate Your Bot
Throughout this guide, we'll create a bot called task-bot:
grace new task-bot
By default, a database is scaffolded alongside your bot. Pass --no-database to skip it — you can always add one later with grace generate database (see Database Management):
grace new task-bot --no-database
Switch to its directory:
cd task-bot
Directory Structure
The generated project includes:
| File/Folder | Description |
|---|---|
alembic.ini |
Alembic configuration file for migrations (only if a database was included) |
bot/ |
Contains your bot logic — primary work area |
bot/extensions/ |
Cogs generated with grace generate cog live here |
bot/models/ |
Models generated with grace generate model live here |
bot/helpers/ |
Shared helper code for your bot |
config/ |
Configuration files and settings (see Configuration) |
db/ |
Database migrations, seeds, and Alembic environment (only if a database was included) |
lib/ |
Shared libraries or utilities |
logs/ |
Log files generated by the application |
README.md |
Project overview and documentation |
pyproject.toml |
Project packaging configuration file |
.env |
Environment variables file (hidden) |
The bot/__init__.py file wires everything together — it creates the Application and Bot instances that the grace CLI imports whenever it runs a command inside your project:
from grace.application import Application
def _create_bot(app):
from bot.task_bot import TaskBot
return TaskBot(app)
app = Application()
bot = _create_bot(app)
Your bot's class itself lives in bot/task_bot.py and subclasses grace.bot.Bot:
from logging import info
from grace.bot import Bot
class TaskBot(Bot):
async def on_ready(self):
info(f"{self.user.name}:#{self.user.id} is online and ready to use!")
Building and Running Your Bot
Minimal Configuration
Your bot requires a Discord token to function. To obtain one:
- Create a Discord application at the Discord Developer Portal
- Copy your bot's token
- Paste it in
.envafterDISCORD_TOKEN=
DISCORD_TOKEN=Paste your token here
Security Warning
Do not share your token or .env file. Reset it immediately if it's accidentally revealed.
Remember to invite your bot into your Discord server for testing.
Run Your Bot
Launch your bot with:
grace run --watch
The --watch flag enables hot reload — see Watcher for how it works.
If configured correctly, the output will look like:
[2025-04-18 01:22:25] development _show_application_info cli INFO
| Discord.py version: 2.5.2
| PID: 895923
| Environment: development
| Syncing command: True
| Watcher enabled: True
| Using database: task_bot_development.db with sqlite
[2025-04-18 01:22:25] development __init__ selector_events DEBUG Using selector: EpollSelector
2025-04-18 01:22:25 WARNING discord.ext.commands.bot Privileged message content intent is missing, commands may not work as expected.
[2025-04-18 01:22:25] development _async_setup_hook bot WARNING Privileged message content intent is missing, commands may not work as expected.
2025-04-18 01:22:25 INFO discord.client logging in using static token
[2025-04-18 01:22:25] development login client INFO logging in using static token
[2025-04-18 01:22:26] development setup_hook bot WARNING Syncing application commands. This may take some time.
2025-04-18 01:22:26 INFO discord.gateway Shard ID None has connected to Gateway (Session ID: 79ad3f472e8e83f31ee61a522a38150f).
[2025-04-18 01:22:26] development received_message gateway INFO Shard ID None has connected to Gateway (Session ID: 79ad3f472e8e83f31ee61a522a38150f).
[2025-04-18 01:22:28] development on_ready task_bot INFO TaskBot:#123456789123456789 is online and ready to use!
Next Steps
Now that your bot is running, give it something to do — start with Models & Migrations to define a Task model, then Extensions to add commands.