A minimalist, dynamic wrapper framework for discord.py with built-in database management.
Project description
mycord
A minimalist, dynamic wrapper framework for discord.py with built-in database management.
mycord simplifies Discord bot development by providing a lightweight abstraction layer over discord.py, featuring automatic cog loading, integrated SQLite database management, and utility tools.
Table of Contents
Installation
Prerequisites
- Python 3.8+
- pip
From Source
Clone the repository and install in development mode:
git clone https://github.com/amri4/mycord.git
cd mycord
pip install -e .
Dependencies
discord.py>=2.0.0- Discord API wrapperpython-dotenv>=1.0.0- Environment variable management
Quick Start
Basic Bot Setup
Create a main bot file (e.g., main.py):
from mycord import MyBot
import asyncio
# Initialize the bot
bot = MyBot(command_prefix="!")
@bot.event
async def on_ready():
print(f"{bot.user} is now running!")
async def main():
# Load cogs from ./cogs directory
await bot.autoload_cogs("./cogs")
await bot.start("YOUR_DISCORD_TOKEN")
asyncio.run(main())
Environment Setup
Create a .env file in your project root:
TOKEN=your_discord_bot_token_here
Or use a custom token variable name:
bot.run_bot(token_env_name="DISCORD_TOKEN")
Core Components
MyBot
The main bot class extending discord.ext.commands.Bot with integrated database and utilities.
Features
- Automatic environment loading - Finds and loads
.envfiles automatically - Integrated database - Built-in SQLite database accessible from bot instance
- Dynamic cog loading - Automatically load all Python files from a directory
- Database proxy - Access database methods directly from bot instance
- Token management - Flexible token retrieval from environment variables
Constructor
MyBot(command_prefix, db_name="mycord_data.db", **options)
Parameters:
command_prefix(str): Prefix for bot commands (e.g., "!", ".")db_name(str): Name of SQLite database file. Default:"mycord_data.db"**options: Additional keyword arguments passed todiscord.ext.commands.Bot
Attributes:
_db- Internal database instancetools- Reference to the Tools utility class
Methods
autoload_cogs(directory: str = "./cogs")
Automatically scans a directory and loads all Python files as Discord cogs.
await bot.autoload_cogs("./cogs")
Parameters:
directory(str): Path to cogs directory. Default:"./cogs"
Behavior:
- Creates the directory if it doesn't exist
- Loads all
.pyfiles (except those starting with_) - Prints success/failure messages to console
- Continues loading even if a cog fails
get_env(key: str, default: str = None) -> str
Retrieve environment variables.
token = bot.get_env("TOKEN")
api_key = bot.get_env("API_KEY", default="default_key")
Parameters:
key(str): Environment variable namedefault(str): Default value if key not found
Returns: Environment variable value or default
run_bot(token_env_name: str = "TOKEN")
Start the bot with automatic token retrieval.
bot.run_bot() # Uses TOKEN env var
bot.run_bot(token_env_name="DISCORD_TOKEN") # Uses DISCORD_TOKEN env var
Parameters:
token_env_name(str): Environment variable containing the token. Default:"TOKEN"
Database Proxy
Access database methods directly from the bot:
bot.create_table("users", "id INTEGER PRIMARY KEY, name TEXT")
bot.insert("users", "id, name", (1, "Alice"))
user = bot.fetchone("users", "id = ?", (1,))
DB
A SQLite database wrapper for simple data persistence.
Constructor
DB(db_name="mycord_data.db")
Parameters:
db_name(str): SQLite database filename
Attributes:
conn- SQLite connection objectcursor- SQLite cursor for executing queries
Methods
create_table(name: str, columns: str)
Create a new table.
db.create_table("users", "id INTEGER PRIMARY KEY, name TEXT, age INTEGER")
insert(table: str, columns: str, values: tuple)
Insert a new row into a table.
db.insert("users", "name, age", ("Alice", 30))
insert_replace(table: str, columns: str, values: tuple)
Insert a row, replacing if a unique constraint conflict occurs.
db.insert_replace("users", "id, name, age", (1, "Alice", 31))
fetchone(table: str, condition: str = None, values: tuple = ())
Fetch a single row from a table.
user = db.fetchone("users")
user = db.fetchone("users", "id = ?", (1,))
user = db.fetchone("users", "name = ? AND age > ?", ("Alice", 25))
Parameters:
table(str): Table namecondition(str): WHERE clause without "WHERE" keywordvalues(tuple): Parameterized query values
Returns: Tuple of row data or None if not found
fetchall(table: str)
Fetch all rows from a table.
all_users = db.fetchall("users")
Parameters:
table(str): Table name
Returns: List of tuples
update(table: str, set_values: str, condition: str, values: tuple)
Update rows in a table.
db.update("users", "age = ?", "id = ?", (31, 1))
Parameters:
table(str): Table nameset_values(str): SET clause (e.g., "age = ?")condition(str): WHERE clausevalues(tuple): Parameterized values
delete(table: str, condition: str, values: tuple)
Delete rows from a table.
db.delete("users", "id = ?", (1,))
exists(table: str, condition: str, values: tuple) -> bool
Check if a row exists in a table.
if db.exists("users", "id = ?", (1,)):
print("User exists!")
Returns: Boolean
close()
Close the database connection.
db.close()
Cog
A base class for Discord cogs with automatic module injection for easy access to discord.py and discord.ext.commands utilities.
Overview
When you create a Cog subclass, all non-private attributes from discord and discord.ext.commands are automatically injected into your cog's module, allowing you to use them without explicit imports.
Example
from mycord import Cog
class MyCog(Cog):
def __init__(self, bot):
self.bot = bot
@commands.command(name="ping")
async def ping_command(self, ctx):
await ctx.send(f"Pong! {round(self.bot.latency * 1000)}ms")
async def setup(bot):
await bot.add_cog(MyCog(bot))
The commands.command decorator is automatically available without importing discord.ext.commands.
How It Works
The __init_subclass__ hook injects module-level attributes:
- All public members from
discordmodule - All public members from
discord.ext.commandsmodule
This allows cleaner, more concise cog files.
Tools
A utility class providing helper methods for common Discord bot operations.
Methods
chance(percentage: float) -> bool
Return True with the given probability (0-100).
if Tools.chance(50):
print("50% chance succeeded!")
if Tools.chance(10):
print("Only 10% chance!")
Parameters:
percentage(float): Probability as a percentage (0-100)
Returns: Boolean
timestamp() -> str
Get the current timestamp as a formatted string.
current_time = Tools.timestamp()
print(current_time) # Output: "2024-01-15 14:30:45"
Returns: String in format "YYYY-MM-DD HH:MM:SS"
API Reference
Imports
from mycord import MyBot, DB, Cog, Tools
All classes are automatically injected into your main module's namespace, so you can use them directly after importing.
Examples
Complete Bot with Database
import asyncio
from mycord import MyBot, DB
# Create bot
bot = MyBot(command_prefix="!", db_name="bot_data.db")
@bot.event
async def on_ready():
print(f"{bot.user} logged in!")
# Initialize database
bot.create_table(
"user_points",
"user_id INTEGER PRIMARY KEY, points INTEGER DEFAULT 0"
)
@bot.command(name="points")
async def get_points(ctx):
user_id = ctx.author.id
# Use database through bot instance
result = bot.fetchone("user_points", "user_id = ?", (user_id,))
if result:
points = result[1]
await ctx.send(f"You have {points} points!")
else:
await ctx.send("No data found!")
async def main():
await bot.autoload_cogs("./cogs")
await bot.start("YOUR_TOKEN")
asyncio.run(main())
Creating a Cog with Commands
Create cogs/moderation.py:
from mycord import Cog
class ModerationCog(Cog):
def __init__(self, bot):
self.bot = bot
@commands.command(name="kick")
@commands.has_permissions(kick_members=True)
async def kick_member(self, ctx, member: Member, *, reason=None):
await member.kick(reason=reason)
await ctx.send(f"Kicked {member.mention}")
@commands.command(name="ban")
@commands.has_permissions(ban_members=True)
async def ban_member(self, ctx, member: Member, *, reason=None):
await member.ban(reason=reason)
await ctx.send(f"Banned {member.mention}")
async def setup(bot):
await bot.add_cog(ModerationCog(bot))
Using Tools
from mycord import Tools
# Random chance
if Tools.chance(75):
print("75% roll succeeded!")
# Logging with timestamps
log_message = f"[{Tools.timestamp()}] Bot started successfully"
Requirements
| Package | Version | Purpose |
|---|---|---|
| discord.py | >=2.0.0 | Discord API wrapper |
| python-dotenv | >=1.0.0 | Environment variable management |
| Python | >=3.8 | Runtime |
License
MIT License - See LICENSE file for details
Author
Created by amri4
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file mycord-1.0.1.tar.gz.
File metadata
- Download URL: mycord-1.0.1.tar.gz
- Upload date:
- Size: 6.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5120c90fa9c351a099616da0d318dcdefcc45ccfd8ceb68a10fad3f4e955b1ee
|
|
| MD5 |
fd13007761a2e9149ad60675d608ef97
|
|
| BLAKE2b-256 |
827ee51c2fddb8714b5b463942b051e41a694ac4ca96c326084bf31c0827c60d
|
File details
Details for the file mycord-1.0.1-py3-none-any.whl.
File metadata
- Download URL: mycord-1.0.1-py3-none-any.whl
- Upload date:
- Size: 7.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4c486673760e482b0db6632c868e6f53fa5b9d0bf7eab058d4a28b02b3a93c84
|
|
| MD5 |
bdce4cea83d841356ffe7eb10d3691d2
|
|
| BLAKE2b-256 |
0db46805d5e942461136004c1200eafe5bdc30dc3a1ddc28532dcd5c5e241690
|