96 lines
3.3 KiB
Python
96 lines
3.3 KiB
Python
import json
|
|
import os
|
|
import secrets
|
|
import logging
|
|
|
|
class Settings:
|
|
_instance = None
|
|
|
|
def __new__(cls, config_file=None):
|
|
if cls._instance is None:
|
|
cls._instance = super(Settings, cls).__new__(cls)
|
|
if config_file is None:
|
|
config_file = os.path.join(os.path.dirname(__file__), '..', 'appsettings.json')
|
|
cls._instance.config_file = config_file
|
|
cls._instance.load_settings()
|
|
return cls._instance
|
|
|
|
def load_settings(self):
|
|
"""Load settings from the JSON file, providing defaults if necessary, and save them."""
|
|
try:
|
|
if os.path.exists(self.config_file):
|
|
with open(self.config_file, 'r') as file:
|
|
self.settings = json.load(file)
|
|
else:
|
|
self.settings = {}
|
|
self.validate_settings()
|
|
self.save_settings()
|
|
except Exception as e:
|
|
logging.error(f"Failed to load settings: {e}")
|
|
self.settings = {}
|
|
self.validate_settings()
|
|
self.save_settings()
|
|
|
|
def validate_settings(self):
|
|
"""Ensure all necessary settings are present, set defaults if not."""
|
|
default_values = {
|
|
'host': 'localhost',
|
|
'port': 8000,
|
|
'reload': False,
|
|
'api_key': None # Default API key is None which will trigger generation
|
|
}
|
|
|
|
# Check for presence and validity of each setting
|
|
for key, default in default_values.items():
|
|
if key == 'api_key': # Special handling for API key
|
|
if key not in self.settings or not self.is_valid_api_key(self.settings[key]):
|
|
self.settings[key] = self.generate_api_key()
|
|
else:
|
|
if key not in self.settings:
|
|
logging.info(key)
|
|
self.settings[key] = default
|
|
self.save_settings()
|
|
|
|
def is_valid_api_key(self, api_key):
|
|
"""Check if the API key is valid."""
|
|
if api_key is None or not isinstance(api_key, str) or len(api_key) < 20:
|
|
return False
|
|
return True
|
|
|
|
def generate_api_key(self):
|
|
"""Generate a new API key."""
|
|
return secrets.token_urlsafe(32)
|
|
|
|
def save_settings(self):
|
|
"""Save the current settings back to the JSON file."""
|
|
try:
|
|
with open(self.config_file, 'w') as file:
|
|
json.dump(self.settings, file, indent=4)
|
|
logging.info("Settings saved successfully.")
|
|
except Exception as e:
|
|
logging.error(f"Failed to save settings: {e}")
|
|
|
|
def get_api_key(self):
|
|
"""Retrieve or generate an API key."""
|
|
api_key = self.settings.get('api_key')
|
|
if not self.is_valid_api_key(api_key):
|
|
logging.error("Invalid API key found, generating a new one.")
|
|
api_key = self.generate_api_key()
|
|
self.settings['api_key'] = api_key
|
|
self.save_settings()
|
|
return api_key
|
|
|
|
def generate_api_key(self):
|
|
"""Generate a new API key."""
|
|
return secrets.token_urlsafe(32)
|
|
|
|
def is_valid_api_key(self, api_key):
|
|
"""Check if the API key is valid."""
|
|
if not api_key or not isinstance(api_key, str) or len(api_key) < 20:
|
|
return False
|
|
return True
|
|
|
|
# Initialize logging
|
|
logging.basicConfig(level=logging.INFO)
|
|
settings = Settings()
|