import os import json from typing import Dict, Any, Optional from pathlib import Path from sigma_api_client import SigmaConfig class ConfigManager: """ Manages configuration for Sigma API scripts """ def __init__(self, config_file: str = "sigma_config.json"): self.config_file = Path(config_file) self.config_data: Dict[str, Any] = {} self.load_config() def load_config(self) -> None: """ Load configuration from file or environment variables """ # Try to load from file first if self.config_file.exists(): try: with open(self.config_file, 'r') as f: self.config_data = json.load(f) except Exception as e: print(f"Error loading config file: {e}") self.config_data = {} # Override with environment variables if they exist env_config = self._load_from_env() self.config_data.update(env_config) def _load_from_env(self) -> Dict[str, Any]: """ Load configuration from environment variables """ env_config = {} # Sigma API credentials if os.getenv('SIGMA_CLIENT_ID'): env_config['client_id'] = os.getenv('SIGMA_CLIENT_ID') if os.getenv('SIGMA_CLIENT_SECRET'): env_config['client_secret'] = os.getenv('SIGMA_CLIENT_SECRET') if os.getenv('SIGMA_BASE_URL'): env_config['base_url'] = os.getenv('SIGMA_BASE_URL') # Optional connection name if os.getenv('SIGMA_SNOWFLAKE_CONNECTION'): env_config['snowflake_connection_name'] = os.getenv('SIGMA_SNOWFLAKE_CONNECTION') return env_config def save_config(self, config_data: Dict[str, Any]) -> None: """ Save configuration to file (excluding sensitive data) """ # Don't save sensitive credentials to file safe_config = {k: v for k, v in config_data.items() if k not in ['client_secret']} try: with open(self.config_file, 'w') as f: json.dump(safe_config, f, indent=2) except Exception as e: print(f"Error saving config file: {e}") def get_sigma_config(self) -> SigmaConfig: """ Get Sigma API configuration """ required_fields = ['client_id', 'client_secret', 'base_url'] missing_fields = [field for field in required_fields if field not in self.config_data or not self.config_data[field]] if missing_fields: raise ValueError(f"Missing required configuration fields: {missing_fields}") return SigmaConfig( client_id=self.config_data['client_id'], client_secret=self.config_data['client_secret'], base_url=self.config_data['base_url'] ) def get_snowflake_connection_name(self) -> Optional[str]: """ Get Snowflake connection name """ return self.config_data.get('snowflake_connection_name') def set_config(self, **kwargs) -> None: """ Set configuration values """ self.config_data.update(kwargs) def get_base_urls(self) -> Dict[str, str]: """ Get common Sigma base URLs by region """ return { 'us': 'https://api.sigmacomputing.com', 'eu': 'https://api.eu.sigmacomputing.com', 'ca': 'https://api.ca.sigmacomputing.com', 'uk': 'https://api.uk.sigmacomputing.com', 'au': 'https://api.au.sigmacomputing.com' } def setup_interactive(self) -> None: """ Interactive setup for configuration """ print("Sigma API Configuration Setup") print("=" * 40) # Get base URL print("\nAvailable regions:") base_urls = self.get_base_urls() for region, url in base_urls.items(): print(f" {region.upper()}: {url}") region = input("\nSelect region (us/eu/ca/uk/au) [us]: ").strip().lower() or 'us' if region in base_urls: base_url = base_urls[region] else: base_url = input("Enter custom base URL: ").strip() # Get credentials client_id = input("Enter Sigma Client ID: ").strip() client_secret = input("Enter Sigma Client Secret: ").strip() # Optional Snowflake connection name snowflake_conn = input("Enter Snowflake connection name (optional): ").strip() # Update configuration config_updates = { 'base_url': base_url, 'client_id': client_id, 'client_secret': client_secret } if snowflake_conn: config_updates['snowflake_connection_name'] = snowflake_conn self.set_config(**config_updates) # Save non-sensitive config to file self.save_config(self.config_data) print(f"\nConfiguration saved to {self.config_file}") print("Note: Client secret is not saved to file for security.") print("Set SIGMA_CLIENT_SECRET environment variable or provide it each time.") def create_example_config() -> None: """ Create an example configuration file """ example_config = { "base_url": "https://api.sigmacomputing.com", "client_id": "your_client_id_here", "snowflake_connection_name": "PROD_SIGMA_ORCHARD_SNOWFLAKE" } with open("sigma_config.example.json", "w") as f: json.dump(example_config, f, indent=2) print("Created sigma_config.example.json") if __name__ == "__main__": # Interactive setup config_manager = ConfigManager() config_manager.setup_interactive()