config.py 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. # encoding:utf-8
  2. import argparse
  3. import json
  4. import logging
  5. import os
  6. import pickle
  7. from common.log import logger
  8. # 将所有可用的配置项写在字典里, 请使用小写字母
  9. # 此处的配置值无实际意义,程序不会读取此处的配置,仅用于提示格式,请将配置加入到config.json中
  10. available_setting = {
  11. "debug": False,
  12. "api_base": "http://fastgpt.ascrm.cn/api/v1",
  13. "api_key": "fastgpt-sKABkv3PTHxlFZYPn9Mo35HHsZSdzdFNBH4XeWIRn5CwdkG7aXqEDmXwDwK",
  14. "token": "bowen-test",
  15. "open_ai_model": "gpt-4o",
  16. "open_ai_temperature": 0.7,
  17. "open_ai_max_tokens": 1024,
  18. "open_ai_top_p": 1,
  19. "open_ai_frequency_penalty": 0,
  20. "open_ai_presence_penalty": 0,
  21. "open_ai_stop": ["<|im_end|>"],
  22. "open_ai_stream": True,
  23. "contacts_white_list": [],
  24. "appdata_dir": ".",
  25. "agent_id": 0,
  26. "role": "",
  27. "background": "",
  28. "examples": "",
  29. "dataset_id": "",
  30. "collection_id": "",
  31. "custom_agent_base": "",
  32. "custom_agent_key": "",
  33. "openai_base": "",
  34. "openai_key": "",
  35. "dataset_base": "",
  36. "dataset_key": "",
  37. }
  38. class Config(dict):
  39. def __init__(self, d=None):
  40. super().__init__()
  41. if d is None:
  42. d = {}
  43. for k, v in d.items():
  44. self[k] = v
  45. # user_datas: 用户数据,key为用户名,value为用户数据,也是dict
  46. self.user_datas = {}
  47. def __getitem__(self, key):
  48. if key not in available_setting:
  49. raise Exception("key {} not in available_setting".format(key))
  50. return super().__getitem__(key)
  51. def __setitem__(self, key, value):
  52. if key not in available_setting:
  53. raise Exception("key {} not in available_setting".format(key))
  54. return super().__setitem__(key, value)
  55. def get(self, key, default=None):
  56. try:
  57. return self[key]
  58. except KeyError as e:
  59. return default
  60. except Exception as e:
  61. raise e
  62. # Make sure to return a dictionary to ensure atomic
  63. def get_user_data(self, user) -> dict:
  64. if self.user_datas.get(user) is None:
  65. self.user_datas[user] = {}
  66. return self.user_datas[user]
  67. def load_user_datas(self):
  68. try:
  69. with open(os.path.join(get_appdata_dir(), "user_datas.pkl"), "rb") as f:
  70. self.user_datas = pickle.load(f)
  71. logger.info("[Config] User datas loaded.")
  72. except FileNotFoundError as e:
  73. logger.info("[Config] User datas file not found, ignore.")
  74. except Exception as e:
  75. logger.info("[Config] User datas error: {}".format(e))
  76. self.user_datas = {}
  77. def save_user_datas(self):
  78. try:
  79. with open(os.path.join(get_appdata_dir(), "user_datas.pkl"), "wb") as f:
  80. pickle.dump(self.user_datas, f)
  81. logger.info("[Config] User datas saved.")
  82. except Exception as e:
  83. logger.info("[Config] User datas error: {}".format(e))
  84. config = Config()
  85. # parser = argparse.ArgumentParser(description='消息中间处理程序')
  86. # parser.add_argument('-c', '--config', help='设置配置文件,默认值是 ./config.json')
  87. def load_config():
  88. global config, parser
  89. # args = parser.parse_args()
  90. # parser.print_help()
  91. # if args.config:
  92. # config_path = args.config
  93. # else:
  94. config_path = "./config.json"
  95. if not os.path.exists(config_path):
  96. logger.info("配置文件不存在,将使用config-template.json模板")
  97. config_path = "./config-template.json"
  98. config_str = read_file(config_path)
  99. logger.debug("[INIT] config str: {}".format(config_str))
  100. # 将json字符串反序列化为dict类型
  101. config = Config(json.loads(config_str))
  102. # override config with environment variables.
  103. # Some online deployment platforms (e.g. Railway) deploy project from github directly. So you shouldn't put your secrets like api key in a config file, instead use environment variables to override the default config.
  104. for name, value in os.environ.items():
  105. name = name.lower()
  106. if name in available_setting:
  107. logger.info("[INIT] override config by environ args: {}={}".format(name, value))
  108. try:
  109. config[name] = eval(value)
  110. except:
  111. if value == "false":
  112. config[name] = False
  113. elif value == "true":
  114. config[name] = True
  115. else:
  116. config[name] = value
  117. if config.get("debug", False):
  118. logger.setLevel(logging.DEBUG)
  119. logger.debug("[INIT] set log level to DEBUG")
  120. logger.info("[INIT] load config: {}".format(config))
  121. # config.load_user_datas()
  122. #
  123. # logger.info("[INIT] load user datas: {}".format(config.get_user_data("api_base")))
  124. def set_config(name, value):
  125. global config
  126. name = name.lower()
  127. if name in available_setting:
  128. logger.info("[INIT] override config by environ args: {}={}".format(name, value))
  129. try:
  130. config[name] = eval(value)
  131. except:
  132. if value == "false":
  133. config[name] = False
  134. elif value == "true":
  135. config[name] = True
  136. else:
  137. config[name] = value
  138. def get_root():
  139. return os.path.dirname(os.path.abspath(__file__))
  140. def read_file(path):
  141. with open(path, mode="r", encoding="utf-8") as f:
  142. return f.read()
  143. def conf():
  144. return config
  145. def get_appdata_dir():
  146. data_path = os.path.join(get_root(), conf().get("appdata_dir", ""))
  147. if not os.path.exists(data_path):
  148. logger.info("[INIT] data path not exists, create it: {}".format(data_path))
  149. os.makedirs(data_path)
  150. return data_path
  151. def subscribe_msg():
  152. trigger_prefix = conf().get("single_chat_prefix", [""])[0]
  153. msg = conf().get("subscribe_msg", "")
  154. return msg.format(trigger_prefix=trigger_prefix)
  155. # global plugin config
  156. plugin_config = {}
  157. def write_plugin_config(pconf: dict):
  158. """
  159. 写入插件全局配置
  160. :param pconf: 全量插件配置
  161. """
  162. global plugin_config
  163. for k in pconf:
  164. plugin_config[k.lower()] = pconf[k]
  165. def pconf(plugin_name: str) -> dict:
  166. """
  167. 根据插件名称获取配置
  168. :param plugin_name: 插件名称
  169. :return: 该插件的配置项
  170. """
  171. return plugin_config.get(plugin_name.lower())
  172. # 全局配置,用于存放全局生效的状态
  173. global_config = {
  174. "admin_users": []
  175. }