Skip to content

Commit ed46934

Browse files
authored
Merge pull request #7 from Robbings/Feature/config_check
添加配置检验功能
2 parents 171ff52 + 09ea1bb commit ed46934

File tree

7 files changed

+287
-15
lines changed

7 files changed

+287
-15
lines changed

README.md

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,11 @@
1212
<a href="https://tqz0rsrhsvf.feishu.cn/docx/FlgzdMrj0oYOg2xXY7EcrsZZnjb?from=from_copylink">📚 官方文档</a>
1313
</p>
1414
<p align="center">
15-
<a href="#项目描述">🔍 项目描述</a> •
16-
<a href="#功能预览">🍭 功能预览</a> •
17-
<a href="#部署">🔧 部署安装</a> •
18-
<a href="#待办清单">📌 待办清单</a>
19-
<a href="#联系我们">🚗 联系我们 </a>
15+
<a href="#项目描述-">🔍 项目描述</a> •
16+
<a href="#功能预览-">🍭 功能预览</a> •
17+
<a href="#部署-">🔧 部署安装</a> •
18+
<a href="#待办清单-">📌 待办清单</a>
19+
<a href="#交流-">🚗 联系我们 </a>
2020
</p>
2121

2222
# 项目描述 📚
@@ -159,6 +159,7 @@ vim config/config.py
159159
python3 app.py
160160
```
161161
5.**配置Gitlab webhook**
162+
> 填写```Webhook URL```时,请在域名后添加路径```/git/webhook```,例如:```http://example.com/git/webhook```
162163
<p align="center">
163164
<img src="doc/img/webhookconfig.png" style="width:300px;"/>
164165
</p>

README_EN.md

Lines changed: 83 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,88 @@
4444
<img src="doc/img/img.png" style="width:500px;"/>
4545
</p>
4646

47-
47+
### 3. Integration of More Large Models
48+
49+
1. Custom models can be quickly integrated by implementing the project interface.
50+
For specific configuration methods, refer to [config.md](doc/config.md).
51+
2. The project supports multiple models through [UnionLLM](https://github.com/EvalsOne/UnionLLM/),
52+
which is compatible with [LiteLLM](https://docs.litellm.ai/docs).
53+
The default supported models are listed in the table below.
54+
55+
<table style="width:100%; text-align:center; border-collapse:collapse;">
56+
<tr>
57+
<td>OpenAI</td>
58+
<td>Azure</td>
59+
<td>AWS - SageMaker</td>
60+
<td>AWS - Bedrock</td>
61+
</tr>
62+
<tr>
63+
<td>Google - Vertex_AI</td>
64+
<td>Google - Palm</td>
65+
<td>Google AI Studio - Gemini</td>
66+
<td>Mistral AI API</td>
67+
</tr>
68+
<tr>
69+
<td>Cloudflare AI Workers</td>
70+
<td>Cohere</td>
71+
<td>Anthropic</td>
72+
<td>Empower</td>
73+
</tr>
74+
<tr>
75+
<td>Huggingface</td>
76+
<td>Replicate</td>
77+
<td>Together_AI</td>
78+
<td>OpenRouter</td>
79+
</tr>
80+
<tr>
81+
<td>AI21</td>
82+
<td>Baseten</td>
83+
<td>Vllm</td>
84+
<td>NLP_Cloud</td>
85+
</tr>
86+
<tr>
87+
<td>Aleph Alpha</td>
88+
<td>Petals</td>
89+
<td>Ollama</td>
90+
<td>Deepinfra</td>
91+
</tr>
92+
<tr>
93+
<td>Perplexity-AI</td>
94+
<td>Groq AI</td>
95+
<td>DeepSeek</td>
96+
<td>Anyscale</td>
97+
</tr>
98+
<tr>
99+
<td>IBM - Watsonx.ai</td>
100+
<td>Voyage AI</td>
101+
<td>Xinference [Xorbits Inference]</td>
102+
<td>FriendliAI</td>
103+
</tr>
104+
<tr>
105+
<td>Galadriel</td>
106+
<td>智谱AI</td>
107+
<td>月之暗面 Moonshot</td>
108+
<td>百度文心一言</td>
109+
</tr>
110+
<tr>
111+
<td>阿里巴巴通义千问</td>
112+
<td>MiniMax</td>
113+
<td>讯飞星火</td>
114+
<td>百川智能</td>
115+
</tr>
116+
<tr>
117+
<td>昆仑天工</td>
118+
<td>零一万物</td>
119+
<td>阶跃星辰</td>
120+
<td>字节豆包</td>
121+
</tr>
122+
<tr>
123+
<td>DeepSeek</td>
124+
<td>More</td>
125+
<td></td>
126+
<td></td>
127+
</tr>
128+
</table>
48129
# Usage 📖
49130

50131
### install
@@ -66,6 +147,7 @@ vim config/config.py
66147
python3 app.py
67148
```
68149
5.**config gitlab webhook**
150+
> When filling in the ```Webhook URL```, please add ```/git/webhook``` after the domain name. For example: ```http://example.com/git/webhook```
69151
<p align="center">
70152
<img src="doc/img/webhookconfig.png" style="width:300px;"/>
71153
</p>

app.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import os
22
from flask import Flask, jsonify, make_response
33
from app.gitlab_webhook import git
4+
from utils.args_check import check_config
45
from utils.logger import log
56

67
app = Flask(__name__)
@@ -20,5 +21,7 @@ def handle_error(error):
2021
if __name__ == '__main__':
2122
os.environ['STABILITY_HOST'] = 'grpc.stability.ai:443'
2223
app.config['JSON_AS_ASCII'] = False
24+
log.info('Starting args check...')
25+
check_config()
2326
log.info('Starting the app...')
2427
app.run(debug=True, host="0.0.0.0", port=80, use_reloader=False)

llm_api/llm_api_default.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,10 @@ def set_config(self, api_config: dict) -> bool:
2727
return True
2828

2929
def generate_text(self, messages: list) -> bool:
30-
31-
self.response = unionchat(provider=self.provider, model=self.model_name,
32-
messages=messages)
33-
30+
try:
31+
self.response = unionchat(provider=self.provider, model=self.model_name, messages=messages)
32+
except Exception as e:
33+
raise e
3434
return True
3535

3636
def get_respond_content(self) -> str:

llm_api/load_api.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import importlib
2+
import warnings
23

34
from config.config import llm_api_impl
45

@@ -12,5 +13,7 @@ def get_llm_api_class():
1213

1314
# 使用工厂函数获取类实例
1415
def create_llm_api_instance():
15-
cls = get_llm_api_class()
16-
return cls()
16+
with warnings.catch_warnings():
17+
warnings.simplefilter("ignore", category=UserWarning)
18+
cls = get_llm_api_class()
19+
return cls()

utils/args_check.py

Lines changed: 185 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,185 @@
1+
import requests
2+
from tabulate import tabulate
3+
4+
def check_config():
5+
"""
6+
Check the configuration
7+
:return: bool
8+
"""
9+
results = []
10+
try:
11+
import config.config as config
12+
if check_exist(config, ["llm_api_impl", "api_config", "gpt_message",
13+
"gitlab_server_url", "gitlab_private_token", "dingding_bot_webhook", "dingding_secret"]):
14+
results.append(["Configuration parameter existence", "Passed", "", "✅ Required parameters are available."])
15+
else:
16+
results.append(["Configuration parameter existence", "Failed", "Required parameters are missing", "❌ Required parameters are missing"])
17+
return print_results(results)
18+
19+
api_check = check_api_config(config)
20+
if api_check['passed']:
21+
results.append(["API interface", "Passed", "", "✅ Model invocation can be used."])
22+
else:
23+
results.append(["API interface", "Failed", "\n".join(api_check['errors']), "❌ Model invocation cannot be used."])
24+
25+
gitlab_check = check_gitlab_config(config)
26+
if gitlab_check['passed']:
27+
results.append(["Gitlab configuration", "Passed", "", "✅ Code review function can be used.\n✅ Comment function can be used."])
28+
else:
29+
results.append(["Gitlab configuration", "Failed",
30+
"\n".join(gitlab_check['errors']),
31+
"❌ Code review function cannot be used.\n❌ Comment function cannot be used."])
32+
dingding_check = check_dingding_config(config)
33+
if dingding_check['passed']:
34+
results.append(["Dingding configuration", "Passed", "", "✅ Notification on Dingtalk function can be used."])
35+
else:
36+
results.append(["Dingding configuration", "Failed",
37+
"\n".join(dingding_check['errors']),
38+
"⚠️ Notification on Dingtalk function cannot be used."])
39+
except ImportError:
40+
results.append(["Configuration file", "Failed", "config.py not found",
41+
"❌ Cannot run any Service, please create a config.py file"])
42+
return print_results(results)
43+
except Exception as e:
44+
results.append(["Configuration file", "Failed", f"Error loading config.py: {e}",
45+
"❌ Cannot run any Service, please check config.py file"])
46+
return print_results(results)
47+
48+
return print_results(results)
49+
50+
def check_dingding_config(config):
51+
"""
52+
Check the dingding configuration
53+
:return: dict
54+
"""
55+
result = {'passed': True, 'errors': []}
56+
try:
57+
from utils.dingding import send_dingtalk_message_by_sign
58+
response = send_dingtalk_message_by_sign("连通性测试:测试消息,请勿回复。")
59+
if not response:
60+
error_msg = "Dingding configuration is invalid"
61+
result['errors'].append(error_msg)
62+
result['passed'] = False
63+
64+
except Exception as e:
65+
result['errors'].append(str(e))
66+
result['passed'] = False
67+
68+
return result
69+
70+
def check_gitlab_config(config):
71+
"""
72+
Check the gitlab configuration
73+
:return: dict
74+
"""
75+
result = {'passed': True, 'errors': []}
76+
try:
77+
response = requests.get(config.gitlab_server_url)
78+
if response.status_code != 200:
79+
error_msg = f"Gitlab server URL {config.gitlab_server_url} is not available"
80+
result['errors'].append(error_msg)
81+
result['passed'] = False
82+
83+
response = requests.get(f"{config.gitlab_server_url}/api/v4/projects",
84+
headers={"PRIVATE-TOKEN": config.gitlab_private_token})
85+
if response.status_code != 200:
86+
error_msg = "Gitlab private token is invalid"
87+
result['errors'].append(error_msg)
88+
result['passed'] = False
89+
90+
except Exception as e:
91+
result['errors'].append(str(e))
92+
result['passed'] = False
93+
94+
return result
95+
96+
def check_api_config(config):
97+
"""
98+
Check the API configuration
99+
:return: dict
100+
"""
101+
result = {'passed': True, 'errors': []}
102+
try:
103+
from llm_api.load_api import create_llm_api_instance
104+
api = create_llm_api_instance()
105+
api.set_config(config.api_config)
106+
api.generate_text([
107+
{"role": "system",
108+
"content": "你是一个有用的助手"
109+
},
110+
{"role": "user",
111+
"content": "请输出ok两个小写字母,不要输出其他任何内容",
112+
}
113+
])
114+
res_str = api.get_respond_content()
115+
if not res_str or res_str == "":
116+
error_msg = "Model interface check failed: Please check if the model call related configuration is correct"
117+
result['errors'].append(error_msg)
118+
result['passed'] = False
119+
elif "ok" not in res_str:
120+
warning_msg = "Model interface check failed: The model did not return the expected result, but may still be available"
121+
result['errors'].append(warning_msg)
122+
result['passed'] = False
123+
124+
except Exception as e:
125+
result['errors'].append(str(e))
126+
result['passed'] = False
127+
128+
return result
129+
130+
def check_exist(config, arg_names):
131+
"""
132+
Check if the variable is defined
133+
:param arg_names: variable name list
134+
:return: bool
135+
"""
136+
res = True
137+
errors = []
138+
for arg_name in arg_names:
139+
if not hasattr(config, arg_name):
140+
errors.append(f"{arg_name} not found in config.py")
141+
res = False
142+
if errors:
143+
print("\n".join(errors))
144+
return res
145+
146+
def wrap_text(text, width):
147+
"""
148+
Wrap text to a specified width.
149+
:param text: The text to wrap.
150+
:param width: The maximum width of each line.
151+
:return: The wrapped text.
152+
"""
153+
if not text:
154+
return ""
155+
lines = []
156+
while len(text) > width:
157+
# Find the last space within the width limit
158+
wrap_at = text.rfind(' ', 0, width)
159+
if wrap_at == -1:
160+
wrap_at = width
161+
lines.append(text[:wrap_at])
162+
text = text[wrap_at:].lstrip()
163+
lines.append(text)
164+
return "\n".join(lines)
165+
166+
def print_results(results):
167+
"""
168+
Print the results in a tabulated format
169+
:param results: list of lists containing the check results
170+
"""
171+
wrapped_results = []
172+
for result in results:
173+
wrapped_result = [wrap_text(result[0], 30), wrap_text(result[1], 10),
174+
wrap_text(result[2], 50), result[3]]
175+
wrapped_results.append(wrapped_result)
176+
table = tabulate(wrapped_results, headers=["Check", "Status", "Details", "Influence Service"], tablefmt="grid", stralign="left")
177+
print(table)
178+
return all(result[1] == "Passed" for result in results)
179+
180+
# 示例调用
181+
if __name__ == "__main__":
182+
if check_config():
183+
print("All configuration checks passed")
184+
else:
185+
print("Some configuration checks failed")

utils/dingding.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -97,11 +97,9 @@ def send_dingtalk_message_by_sign(message_text):
9797
)
9898

9999
# 检查响应
100-
if response.status_code == 200:
101-
print("消息已发送成功。")
100+
if response.status_code == 200 and response.json()["errcode"] == 0:
102101
return True
103102
else:
104-
print("消息发送失败,HTTP状态码:", response.status_code)
105103
return False
106104

107105
if __name__ == "__main__":

0 commit comments

Comments
 (0)