Skip to content

Conversation

@cxyfer
Copy link
Owner

@cxyfer cxyfer commented Jul 4, 2025

Summary

  • Added comprehensive TOML configuration support using config.toml
  • Implemented environment variable override mechanism for sensitive data
  • Maintained backward compatibility with existing .env files
  • Created configuration management with singleton pattern

Changes Made

  • New configuration system: Added utils/config.py with ConfigManager class
  • TOML support: Added config.toml.example template with comprehensive settings
  • Environment overrides: Environment variables take precedence over TOML values
  • Backward compatibility: Existing .env files continue to work
  • Updated dependencies: Added tomli for Python < 3.11 TOML support

Test Plan

  • Test TOML configuration loading
  • Test environment variable override functionality
  • Test bot initialization with new configuration system
  • Test fallback to .env when config.toml is missing
  • Verify all configuration sections work properly

🤖 Generated with Claude Code

cxyfer and others added 2 commits July 4, 2025 21:51
Migrate from .env to config.toml for better configuration management:
- Add config.toml.example with comprehensive settings
- Create utils/config.py for centralized config management
- Support environment variable overrides for backward compatibility
- Update bot.py to use new configuration system with .env fallback
- Add tomli dependency for Python < 3.11 compatibility
- Update .gitignore to ignore config.toml but not the example
- Update documentation to reflect new configuration approach

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
@cxyfer cxyfer requested a review from Copilot July 4, 2025 14:51
Copilot

This comment was marked as outdated.

- Add missing python-dotenv dependency to pyproject.toml
- Update README.md dependencies list to include python-dotenv
- Improve DummyConfig implementation with better compatibility
- Add proper documentation and property methods to DummyConfig

Fixes identified by Copilot review:
- Missing dependency for load_dotenv() function
- Documentation formatting consistency
- Code duplication reduction in fallback configuration

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
@cxyfer cxyfer requested a review from Copilot July 4, 2025 14:59
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR adds full TOML-based configuration support with environment variable overrides, preserves .env fallback, and centralizes settings access via a singleton ConfigManager.

  • Introduces a new ConfigManager for loading TOML, applying env overrides, and exposing typed getters
  • Updates bot.py to initialize via ConfigManager and provide a .env-based fallback
  • Adds tomli dependency, updates docs and examples for the new configuration methods

Reviewed Changes

Copilot reviewed 7 out of 9 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
utils/config.py New ConfigManager handling TOML parsing, env overrides, and getters
utils/init.py Exports get_config and ConfigManager
pyproject.toml Added python-dotenv and tomli dependencies
config.toml.example Full example of all supported config sections
bot.py Loads configuration via ConfigManager, sets up logging, and falls back to .env
README.md Documentation for TOML and env var configuration methods
.env.example Clarified backward-compatibility notes and optional Gemini API key
Comments suppressed due to low confidence (2)

README.md:64

  • [nitpick] The TOML example in the README omits the [bot] section for command_prefix. Add a snippet showing how to configure bot.command_prefix for completeness.
[schedule]

bot.py:50

  • The call to load_dotenv (and subsequent os.getenv usage) requires imports for both os and load_dotenv from dotenv. Without these imports, this will raise a NameError.
    load_dotenv(dotenv_path='.env', verbose=True, override=True)

from datetime import datetime, timedelta
from pathlib import Path
import logging
from utils.logger import setup_logging, get_logger, set_module_level
Copy link

Copilot AI Jul 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] The set_module_level import is unused in this file; consider removing it to keep imports clean.

Suggested change
from utils.logger import setup_logging, get_logger, set_module_level
from utils.logger import setup_logging, get_logger

Copilot uses AI. Check for mistakes.
Comment on lines +56 to +115
class DummyConfig:
"""Compatibility wrapper for .env configuration"""

def get(self, key, default=None):
"""Get configuration value with .env fallback"""
if key == "database.path":
return "data/data.db"
elif key == "schedule.post_time":
return POST_TIME
elif key == "schedule.timezone":
return TIMEZONE
return default

def get_section(self, section):
"""Get configuration section"""
if section == "logging":
return {
"level": "INFO",
"directory": "./logs",
"modules": {
"bot": "DEBUG",
"bot.discord": "DEBUG",
"bot.lcus": "DEBUG",
"bot.db": "DEBUG",
"discord": "WARNING",
"discord.gateway": "WARNING",
"discord.client": "WARNING",
"requests": "WARNING"
}
}
return {}

def get_llm_model_config(self, model_type):
"""Get LLM model configuration"""
if model_type == "standard":
return {"name": "gemini-2.5-flash", "temperature": 0.0}
else:
return {"name": "gemini-2.5-pro", "temperature": 0.0}

def get_cache_expire_seconds(self, cache_type):
"""Get cache expiration time"""
return 3600 if cache_type == "translation" else 86400

@property
def discord_token(self):
return DISCORD_TOKEN

@property
def gemini_api_key(self):
return os.getenv('GOOGLE_GEMINI_API_KEY')

@property
def post_time(self):
return POST_TIME

@property
def timezone(self):
return TIMEZONE

config = DummyConfig()
Copy link

Copilot AI Jul 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] The DummyConfig class duplicates logic and default values from ConfigManager. Consider refactoring to reuse common code or reduce duplication.

Suggested change
class DummyConfig:
"""Compatibility wrapper for .env configuration"""
def get(self, key, default=None):
"""Get configuration value with .env fallback"""
if key == "database.path":
return "data/data.db"
elif key == "schedule.post_time":
return POST_TIME
elif key == "schedule.timezone":
return TIMEZONE
return default
def get_section(self, section):
"""Get configuration section"""
if section == "logging":
return {
"level": "INFO",
"directory": "./logs",
"modules": {
"bot": "DEBUG",
"bot.discord": "DEBUG",
"bot.lcus": "DEBUG",
"bot.db": "DEBUG",
"discord": "WARNING",
"discord.gateway": "WARNING",
"discord.client": "WARNING",
"requests": "WARNING"
}
}
return {}
def get_llm_model_config(self, model_type):
"""Get LLM model configuration"""
if model_type == "standard":
return {"name": "gemini-2.5-flash", "temperature": 0.0}
else:
return {"name": "gemini-2.5-pro", "temperature": 0.0}
def get_cache_expire_seconds(self, cache_type):
"""Get cache expiration time"""
return 3600 if cache_type == "translation" else 86400
@property
def discord_token(self):
return DISCORD_TOKEN
@property
def gemini_api_key(self):
return os.getenv('GOOGLE_GEMINI_API_KEY')
@property
def post_time(self):
return POST_TIME
@property
def timezone(self):
return TIMEZONE
config = DummyConfig()
class DummyConfig(get_config().__class__):
"""Compatibility wrapper for .env configuration"""
def __init__(self):
super().__init__()
self.env_values = {
"discord_token": os.getenv('DISCORD_TOKEN'),
"post_time": os.getenv('POST_TIME', '00:00'),
"timezone": os.getenv('TIMEZONE', 'UTC'),
"gemini_api_key": os.getenv('GOOGLE_GEMINI_API_KEY'),
}
def get(self, key, default=None):
"""Get configuration value with .env fallback"""
if key in self.env_values:
return self.env_values[key]
return super().get(key, default)
@property
def discord_token(self):
return self.env_values["discord_token"]
@property
def gemini_api_key(self):
return self.env_values["gemini_api_key"]
@property
def post_time(self):
return self.env_values["post_time"]
@property
def timezone(self):
return self.env_values["timezone"]
config = DummyConfig()

Copilot uses AI. Check for mistakes.
@cxyfer cxyfer merged commit 5169be2 into main Jul 4, 2025
@cxyfer cxyfer deleted the dev branch July 4, 2025 15:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant