HoshinoBot Configuration System: How to Enable and Configure Modules
HoshinoBot uses a Python-based configuration system where you rename config_example to config, edit __bot__.py to define network settings and the MODULES_ON set, and optionally create per-module Python or JSON files to customize individual plugin behavior.
The HoshinoBot configuration system is a pure-Python architecture built on top of the nonebot framework that manages global settings and selective module loading. Located in the ice9coffee/hoshinobot repository, this system relies on a centralized config package located at hoshino/config (renamed from config_example) to control everything from network ports to which plugins are active at runtime.
How the Configuration System Works
The bootstrap process begins in hoshino/__init__.py, where the hoshino.init() function loads the global configuration package and registers enabled modules as nonebot plugins.
When you first deploy the bot, you must rename the hoshino/config_example directory to hoshino/config. This allows Python to resolve import hoshino.config during startup. The config package’s own __init__.py validates constants like RES_DIR, ensures required directories exist, and imports per-module configurations for every entry listed in MODULES_ON.
According to the source code in hoshino/__init__.py (lines 52-70), the startup sequence follows these steps:
- Load global config –
nonebot.init(config)receives the importedhoshino.configpackage - Validate environment – The config package expands resource paths and creates
~/.hoshinofor user data - Import module configs – The system iterates over
config.MODULES_ONand runsimportlib.import_module('hoshino.config.' + module) - Register plugins –
nonebot.load_plugins()loads each module underhoshino/modules/<module>/as an active plugin
Global Configuration File (__bot__.py)
The file hoshino/config_example/__bot__.py serves as the template for your global settings. After renaming the folder, edit this file to define network parameters, permission lists, and the active module set.
Key configuration variables include:
- PORT and HOST – Define the listening address (use
0.0.0.0for public access, though127.0.0.1is safer for local testing) - SUPERUSERS – A list of QQ numbers with administrative privileges
- BLACK_LIST and WHITE_LIST – Optional ban and allow lists for user IDs
- COMMAND_START – Prefix characters for bot commands (empty string
''matches any message) - RES_PROTOCOL and RES_DIR – Control how static resources (images, audio) are served (
file,http, orbase64) - MODULES_ON – A Python set containing the folder names of modules to load at startup
# hoshino/config/__bot__.py
PORT = 8080
HOST = '127.0.0.1'
SUPERUSERS = [10000]
BLACK_LIST = []
COMMAND_START = {''}
RES_PROTOCOL = 'file'
RES_DIR = r'./res/'
MODULES_ON = {
'botmanage',
'dice',
'groupmaster',
'pcrclanbattle',
'priconne',
# 'setu', # uncomment to enable
# 'twitter', # uncomment to enable
}
Enabling and Disabling Modules
Module activation is controlled entirely by the MODULES_ON set in your global configuration. To enable a module, add its directory name (case-sensitive) to this set. To disable it, remove the entry or comment it out with #.
The directory name must match exactly the folder located under hoshino/modules/. For example, to enable the setu image-search module:
MODULES_ON = {
'botmanage',
'dice',
'groupmaster',
'setu', # newly enabled module
}
After modifying MODULES_ON, restart the bot with python run.py. The bootstrap code in hoshino/__init__.py will dynamically import any existing configuration for that module and register its plugins.
Per-Module Configuration Methods
HoshinoBot supports two methods for configuring individual modules: Python-based config files and JSON-based data files.
Method 1: Python Config Files
Create a file named hoshino/config/<module>.py to store module-specific constants. The module’s code imports this file directly from the config package.
For example, to configure API keys for the setu module, create hoshino/config/setu.py:
# hoshino/config/setu.py
API_KEY = "your_api_key_here"
PROXY = "http://127.0.0.1:7890"
The module source retrieves these values using:
from hoshino.config import setu as cfg
api_key = cfg.API_KEY
Method 2: JSON Config Files
For modules requiring structured data (such as gacha pools or translation dictionaries), place a config.json file inside the module’s directory. The helper function hoshino.util.load_config() reads this file into a Python dictionary.
As implemented in hoshino/util/__init__.py (lines 28-36), this helper resolves the path relative to the calling module’s __file__ and returns an empty dict if the file is missing.
Example usage within a module:
from hoshino.util import load_config
cfg = load_config(__file__) # reads <module_dir>/config.json
greeting = cfg.get('greeting', 'Hello!')
The priconne gacha module demonstrates this pattern with its hoshino/modules/priconne/gacha/config.json file, which defines summon pools and rarity rates:
{
"default": ["pool_a", "pool_b"],
"pool_a": {
"name": "Standard Pool",
"rarity": {"5": 0.5, "4": 3.5}
}
}
Step-by-Step Configuration Guide
Follow these steps to configure a fresh HoshinoBot deployment:
-
Clone and install dependencies:
git clone https://github.com/ice9coffee/hoshinobot.git cd hoshinobot pip install -r requirements.txt -
Prepare the configuration directory:
mv hoshino/config_example hoshino/config -
Edit global settings in
hoshino/config/__bot__.py:- Set
SUPERUSERSto your QQ ID - Configure
RES_DIRandRES_PROTOCOLfor your environment - Populate
MODULES_ONwith the modules you want active
- Set
-
Add module-specific configs (optional):
- Create
hoshino/config/<module>.pyfor API keys and secrets - Create
hoshino/modules/<module>/config.jsonfor data-driven modules
- Create
-
Launch the bot:
python run.py
The bot will validate the global config, import each enabled module’s specific configuration, and start listening on the configured HOST:PORT.
Summary
- HoshinoBot configuration is pure Python; rename
config_exampletoconfigto activate the system - Global settings live in
hoshino/config/__bot__.py, including theMODULES_ONset that controls which modules load - Module activation requires adding the exact folder name to
MODULES_ONand restarting the bot - Per-module configs can be Python files (
hoshino/config/<module>.py) for code constants or JSON files (config.json) for structured data - JSON loading uses the
load_config(__file__)helper fromhoshino.util, which safely handles missing files
Frequently Asked Questions
Where is the main configuration file located in HoshinoBot?
The main configuration file is hoshino/config/__bot__.py. However, you must first rename the hoshino/config_example directory to hoshino/config when deploying the bot. This renaming step is required so that Python can import the configuration as the hoshino.config package during startup.
How do I enable a new module in HoshinoBot?
Add the module’s folder name (exactly as it appears under hoshino/modules/) to the MODULES_ON set inside hoshino/config/__bot__.py. For example, to enable the twitter module, add 'twitter' to the set, save the file, and restart the bot with python run.py. The bootstrap code in hoshino/__init__.py will then import the module’s config and register it as a nonebot plugin.
What is the difference between Python and JSON config files in HoshinoBot?
Python config files (hoshino/config/<module>.py) are used for code-level constants like API keys, database URLs, and feature flags that the module imports directly. JSON config files (config.json placed inside the module directory) are used for structured data like item lists, gacha pools, or message templates, and are loaded at runtime using hoshino.util.load_config(__file__). Python configs are imported during bootstrap, while JSON configs are read dynamically when the module executes.
Can I run HoshinoBot without configuring every module?
Yes. The MODULES_ON set controls exactly which modules load, and you can leave unused modules out of this set. Additionally, if a module looks for a JSON config file via load_config() and the file does not exist, the function returns an empty dictionary without raising an exception, allowing the module to use default hardcoded values. However, some modules may fail to function correctly if they require specific API keys defined in a Python config file that is missing.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →