Source code for malva_client.config

import json
import os
from pathlib import Path
from typing import Optional, Dict, List, Any

[docs] class Config: """Configuration management for Malva client""" def __init__(self, config_path: Optional[str] = None): self.config_path = Path(config_path) if config_path else Path.home() / '.malva' / 'config.json' self.server_url = None self.api_token = None self.verify_ssl = True
[docs] @classmethod def load(cls, config_path: Optional[str] = None): """Load configuration from file or environment""" config = cls(config_path) if config.config_path.exists(): try: with open(config.config_path) as f: data = json.load(f) config.server_url = data.get('server_url') config.api_token = data.get('api_token') config.verify_ssl = data.get('verify_ssl', True) except Exception: pass config.server_url = os.environ.get('MALVA_API_URL', config.server_url) config.api_token = os.environ.get('MALVA_API_TOKEN', config.api_token) if 'MALVA_VERIFY_SSL' in os.environ: config.verify_ssl = os.environ.get('MALVA_VERIFY_SSL', 'true').lower() == 'true' return config
[docs] def save(self): """Save configuration to file""" self.config_path.parent.mkdir(parents=True, exist_ok=True) data = { 'server_url': self.server_url, 'api_token': self.api_token, 'verify_ssl': self.verify_ssl } with open(self.config_path, 'w') as f: json.dump(data, f, indent=2)
[docs] def set_value(self, key: str, value: str): """ Set configuration value Args: key: Configuration key value: Configuration value """ valid_keys = { 'server_url': 'server_url', 'server': 'server_url', 'url': 'server_url', 'api_token': 'api_token', 'token': 'api_token', 'verify_ssl': 'verify_ssl', 'ssl': 'verify_ssl' } if key not in valid_keys: raise ValueError(f"Invalid configuration key: {key}. Valid keys: {list(valid_keys.keys())}") attr_name = valid_keys[key] # Convert value types if attr_name == 'verify_ssl': value = value.lower() in ('true', '1', 'yes', 'on') setattr(self, attr_name, value)
[docs] def get_value(self, key: str) -> Optional[str]: """ Get configuration value Args: key: Configuration key Returns: Configuration value or None """ valid_keys = { 'server_url': 'server_url', 'server': 'server_url', 'url': 'server_url', 'api_token': 'api_token', 'token': 'api_token', 'verify_ssl': 'verify_ssl', 'ssl': 'verify_ssl' } if key not in valid_keys: return None attr_name = valid_keys[key] return getattr(self, attr_name)
[docs] def show(self) -> Dict[str, Any]: """ Show current configuration Returns: Dictionary with current configuration """ return { 'server_url': self.server_url, 'api_token': '***' if self.api_token else None, 'verify_ssl': self.verify_ssl, 'config_path': str(self.config_path) }
[docs] def validate(self) -> List[str]: """ Validate current configuration Returns: List of validation errors (empty if valid) """ errors = [] if not self.server_url: errors.append("server_url is required") elif not self.server_url.startswith(('http://', 'https://')): errors.append("server_url must start with http:// or https://") if not self.api_token: errors.append("api_token is required") return errors
[docs] def reset_to_defaults(self): """Reset configuration to defaults""" self.server_url = None self.api_token = None self.verify_ssl = True
[docs] def delete_config_file(self) -> bool: """ Delete configuration file Returns: True if file was deleted """ try: if self.config_path.exists(): self.config_path.unlink() return True return False except Exception: return False