Simple and extensible IRC bot framework written in Python with plugin architecture and database support
npx @tessl/cli install tessl/pypi-sopel@8.0.0A simple, lightweight, and extensible IRC bot framework written in Python. Sopel provides a comprehensive platform for building IRC bots with a plugin architecture, built-in database support, configuration management, and extensive IRC protocol handling. It's designed to be easy to use, run, and extend with custom plugins.
pip install sopelimport sopelFor plugin development:
from sopel import plugin, config, db, tools
from sopel.bot import Sopel, SopelWrapperFor configuration management:
from sopel.config import Config, types# Create a basic bot instance
from sopel import config, bot
# Load configuration and create bot
settings = config.Config('/path/to/config.cfg')
sopel_bot = bot.Sopel(settings)
# Start the bot
sopel_bot.run()from sopel import plugin
@plugin.command('hello')
def hello_command(bot, trigger):
"""Say hello to a user."""
bot.say(f"Hello, {trigger.nick}!")
@plugin.rule(r'.*how are you.*')
def how_are_you(bot, trigger):
"""Respond when someone asks how we are."""
bot.say("I'm doing great, thanks for asking!")from sopel.config import Config, types
class MyPluginSection(types.StaticSection):
api_key = types.ValidatedAttribute('api_key')
timeout = types.ValidatedAttribute('timeout', int, default=30)
# Register the configuration section
config.define_section('myplugin', MyPluginSection)Sopel is built around several key architectural components:
Sopel class manages IRC connections, plugin loading, and message routingThis modular design enables developers to create everything from simple utility bots to complex IRC automation systems with minimal setup while maintaining full extensibility.
Complete plugin development system with decorators for commands, rules, events, and advanced features like rate limiting, privilege checking, and capability negotiation.
# Core plugin decorators
def command(command_name: str): ...
def rule(pattern: str): ...
def event(event_types: list): ...
def interval(seconds: int): ...
# Access control decorators
def require_admin(): ...
def require_privilege(level: AccessLevel): ...
def require_chanmsg(): ...
# Rate limiting decorators
def rate(user: int = 0, channel: int = 0, global_rate: int = 0): ...Powerful configuration system with section-based organization, type validation, environment variable overrides, and runtime configuration management.
class Config:
def __init__(self, filename: str, validate: bool = True): ...
def define_section(self, name: str, cls_, validate: bool = True): ...
def save(self): ...
class StaticSection:
pass
# Configuration attribute types
class ValidatedAttribute: ...
class ListAttribute: ...
class ChoiceAttribute: ...SQLAlchemy-based database layer supporting multiple backends (SQLite, MySQL, PostgreSQL, etc.) with convenient methods for storing user, channel, and plugin data.
class SopelDB:
def get_nick_value(self, nick: str, key: str): ...
def set_nick_value(self, nick: str, key: str, value): ...
def get_channel_value(self, channel: str, key: str): ...
def set_channel_value(self, channel: str, key: str, value): ...
def get_plugin_value(self, plugin: str, key: str): ...
def set_plugin_value(self, plugin: str, key: str, value): ...Complete IRC client implementation with connection management, capability negotiation, mode parsing, and user/channel tracking.
class Sopel:
def say(self, text: str, destination: str = None): ...
def action(self, text: str, destination: str = None): ...
def notice(self, text: str, destination: str = None): ...
def join(self, channel: str, password: str = None): ...
def part(self, channel: str, message: str = None): ...
def kick(self, nick: str, channel: str, message: str = None): ...Comprehensive utility functions for IRC formatting, time handling, web operations, mathematical calculations, and logging.
# Formatting utilities
def bold(text: str) -> str: ...
def color(text: str, fg: int = None, bg: int = None) -> str: ...
def plain(text: str) -> str: ...
# Time utilities
def format_time(dt, zone=None, format=None): ...
def seconds_to_human(seconds: int, precision: int = 2) -> str: ...
# Web utilities
def get_user_agent(): ...
def get_session(): ...
# Identifier handling
class Identifier(str): ...Sopel provides command-line tools for running bots, managing configuration, and handling plugins:
sopel: Main bot runner with daemon support and configuration optionssopel-config: Interactive configuration wizard and management toolsopel-plugins: Plugin installation, management, and information tool# Access levels for privilege checking
class AccessLevel(enum.IntFlag):
VOICE: int
HALFOP: int
OP: int
ADMIN: int
OWNER: int
OPER: int
# Plugin capability negotiation
class CapabilityNegotiation(enum.Enum):
NONE: str
OPTIONAL: str
REQUIRED: str
# Trigger context for plugin functions
class Trigger:
nick: str
user: str
host: str
sender: str
args: list
event: str
raw: str
is_privmsg: bool
hostmask: str
account: str
def group(self, n: int) -> str: ...
def groups(self) -> tuple: ...
# Bot wrapper for plugin functions
class SopelWrapper:
nick: str
channels: dict
users: dict
db: SopelDB
settings: Config
def say(self, text: str, destination: str = None): ...
def reply(self, text: str, destination: str = None): ...
def action(self, text: str, destination: str = None): ...