Coverage for src/quickmcp/factory/config.py: 100%

39 statements  

« prev     ^ index     » next       coverage.py v7.10.4, created at 2025-08-20 20:56 +0200

1""" 

2Configuration system for MCP Factory. 

3""" 

4 

5from dataclasses import dataclass, field 

6from typing import Dict, Set, Optional 

7import logging 

8 

9logger = logging.getLogger(__name__) 

10 

11 

12@dataclass 

13class FactoryConfig: 

14 """Configuration for MCP Factory behavior.""" 

15 

16 # Dependency checking 

17 check_dependencies: bool = True 

18 warn_on_optional_missing: bool = True 

19 

20 # Safety settings 

21 allow_code_execution: bool = True 

22 warn_on_code_execution: bool = True 

23 max_file_size_mb: int = 10 

24 

25 # Type conversion 

26 strict_type_conversion: bool = False 

27 allow_type_coercion: bool = True 

28 

29 # Performance 

30 cache_dependency_analysis: bool = True 

31 cache_type_hints: bool = True 

32 

33 # Import analysis 

34 additional_stdlib_modules: Set[str] = field(default_factory=set) 

35 custom_pip_mappings: Dict[str, str] = field(default_factory=dict) 

36 

37 # Logging 

38 log_level: str = "INFO" 

39 verbose_errors: bool = True 

40 

41 def __post_init__(self): 

42 """Validate configuration after initialization.""" 

43 if self.max_file_size_mb <= 0: 

44 raise ValueError("max_file_size_mb must be positive") 

45 

46 if self.log_level not in {"DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"}: 

47 raise ValueError(f"Invalid log_level: {self.log_level}") 

48 

49 # Set up logging level for factory components 

50 factory_logger = logging.getLogger("quickmcp.factory") 

51 factory_logger.setLevel(getattr(logging, self.log_level)) 

52 

53 def merge_pip_mappings(self, base_mappings: Dict[str, str]) -> Dict[str, str]: 

54 """Merge custom pip mappings with base mappings.""" 

55 merged = base_mappings.copy() 

56 merged.update(self.custom_pip_mappings) 

57 return merged 

58 

59 def get_effective_stdlib_modules(self, base_modules: Set[str]) -> Set[str]: 

60 """Get effective set of stdlib modules.""" 

61 return base_modules | self.additional_stdlib_modules 

62 

63 

64# Default configuration instance 

65DEFAULT_CONFIG = FactoryConfig() 

66 

67 

68def create_safe_config() -> FactoryConfig: 

69 """Create a configuration optimized for safety.""" 

70 return FactoryConfig( 

71 allow_code_execution=False, 

72 warn_on_code_execution=True, 

73 strict_type_conversion=True, 

74 allow_type_coercion=False, 

75 verbose_errors=True, 

76 log_level="WARNING" 

77 ) 

78 

79 

80def create_permissive_config() -> FactoryConfig: 

81 """Create a configuration optimized for flexibility.""" 

82 return FactoryConfig( 

83 check_dependencies=False, 

84 allow_code_execution=True, 

85 warn_on_code_execution=False, 

86 strict_type_conversion=False, 

87 allow_type_coercion=True, 

88 verbose_errors=False, 

89 log_level="ERROR" 

90 ) 

91 

92 

93def create_development_config() -> FactoryConfig: 

94 """Create a configuration optimized for development.""" 

95 return FactoryConfig( 

96 check_dependencies=True, 

97 warn_on_optional_missing=True, 

98 allow_code_execution=True, 

99 warn_on_code_execution=True, 

100 strict_type_conversion=False, 

101 cache_dependency_analysis=False, # Always fresh analysis 

102 log_level="DEBUG", 

103 verbose_errors=True 

104 )