Coverage for mcpgateway / plugins / framework / loader / config.py: 100%

19 statements  

« prev     ^ index     » next       coverage.py v7.13.4, created at 2026-03-09 03:05 +0000

1# -*- coding: utf-8 -*- 

2"""Location: ./mcpgateway/plugins/framework/loader/config.py 

3Copyright 2025 

4SPDX-License-Identifier: Apache-2.0 

5Authors: Teryl Taylor, Mihai Criveti 

6 

7Configuration loader implementation. 

8This module loads configurations for plugins. 

9""" 

10 

11# Standard 

12import os 

13 

14# Third-Party 

15import jinja2 

16from jinja2.sandbox import SandboxedEnvironment 

17import yaml 

18 

19# First-Party 

20from mcpgateway.plugins.framework.models import Config, PluginSettings 

21 

22 

23class ConfigLoader: 

24 """A configuration loader. 

25 

26 Examples: 

27 >>> import tempfile 

28 >>> import os 

29 >>> from mcpgateway.plugins.framework.models import PluginSettings 

30 >>> # Create a temporary config file 

31 >>> with tempfile.NamedTemporaryFile(mode='w', suffix='.yaml', delete=False) as f: 

32 ... _ = f.write(\"\"\" 

33 ... plugin_settings: 

34 ... enable_plugin_api: true 

35 ... plugin_timeout: 30 

36 ... plugin_dirs: ['/path/to/plugins'] 

37 ... \"\"\") 

38 ... temp_path = f.name 

39 >>> try: 

40 ... config = ConfigLoader.load_config(temp_path, use_jinja=False) 

41 ... config.plugin_settings.enable_plugin_api 

42 ... finally: 

43 ... os.unlink(temp_path) 

44 True 

45 """ 

46 

47 @staticmethod 

48 def load_config(config: str, use_jinja: bool = True) -> Config: 

49 """Load the plugin configuration from a file path. 

50 

51 Args: 

52 config: the configuration path. 

53 use_jinja: use jinja to replace env variables if true. 

54 

55 Returns: 

56 The plugin configuration object. 

57 

58 Examples: 

59 >>> import tempfile 

60 >>> import os 

61 >>> with tempfile.NamedTemporaryFile(mode='w', suffix='.yaml', delete=False) as f: 

62 ... _ = f.write(\"\"\" 

63 ... plugin_settings: 

64 ... plugin_timeout: 60 

65 ... enable_plugin_api: false 

66 ... plugin_dirs: [] 

67 ... \"\"\") 

68 ... temp_path = f.name 

69 >>> try: 

70 ... cfg = ConfigLoader.load_config(temp_path, use_jinja=False) 

71 ... cfg.plugin_settings.plugin_timeout 

72 ... finally: 

73 ... os.unlink(temp_path) 

74 60 

75 """ 

76 try: 

77 with open(os.path.normpath(config), "r", encoding="utf-8") as file: 

78 template = file.read() 

79 if use_jinja: 

80 jinja_env = SandboxedEnvironment(loader=jinja2.BaseLoader(), autoescape=True) 

81 rendered_template = jinja_env.from_string(template).render(env=os.environ) 

82 else: 

83 rendered_template = template 

84 config_data = yaml.safe_load(rendered_template) or {} 

85 return Config(**config_data) 

86 except FileNotFoundError: 

87 # Graceful fallback for tests and minimal environments without plugin config 

88 return Config(plugins=[], plugin_dirs=[], plugin_settings=PluginSettings())