Spaces:
Running
Running
Upload 4 files
Browse files
app.py
CHANGED
@@ -21,6 +21,8 @@ API_ENDPOINT_URL = "https://abacus.ai/api/v0/describeDeployment"
|
|
21 |
MODEL_LIST_URL = "https://abacus.ai/api/v0/listExternalApplications"
|
22 |
CHAT_URL = "https://apps.abacus.ai/api/_chatLLMSendMessageSSE"
|
23 |
USER_INFO_URL = "https://abacus.ai/api/v0/_getUserInfo"
|
|
|
|
|
24 |
|
25 |
|
26 |
USER_AGENTS = [
|
@@ -51,6 +53,21 @@ total_tokens = {
|
|
51 |
"total": 0 # 总token统计
|
52 |
}
|
53 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
54 |
|
55 |
# HTML模板
|
56 |
INDEX_HTML = """
|
@@ -123,6 +140,9 @@ INDEX_HTML = """
|
|
123 |
.status-value.warning {
|
124 |
color: #ffc107;
|
125 |
}
|
|
|
|
|
|
|
126 |
.footer {
|
127 |
margin-top: 2rem;
|
128 |
text-align: center;
|
@@ -183,6 +203,30 @@ INDEX_HTML = """
|
|
183 |
font-family: monospace;
|
184 |
color: #28a745;
|
185 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
186 |
@media (max-width: 768px) {
|
187 |
.container {
|
188 |
padding: 1rem;
|
@@ -224,6 +268,61 @@ INDEX_HTML = """
|
|
224 |
</div>
|
225 |
</div>
|
226 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
227 |
<h2>🔍 模型使用统计</h2>
|
228 |
<div class="status-card">
|
229 |
<div class="status-item">
|
@@ -983,6 +1082,9 @@ def keep_alive():
|
|
983 |
|
984 |
@app.route("/", methods=["GET"])
|
985 |
def index():
|
|
|
|
|
|
|
986 |
uptime = datetime.now() - START_TIME
|
987 |
days = uptime.days
|
988 |
hours, remainder = divmod(uptime.seconds, 3600)
|
@@ -1003,7 +1105,9 @@ def index():
|
|
1003 |
models=sorted(list(MODELS)),
|
1004 |
year=datetime.now().year,
|
1005 |
model_stats=model_usage_stats,
|
1006 |
-
total_tokens=total_tokens
|
|
|
|
|
1007 |
)
|
1008 |
|
1009 |
|
@@ -1042,8 +1146,115 @@ def update_model_stats(model, prompt_tokens, completion_tokens):
|
|
1042 |
total_tokens["total"] += (prompt_tokens + completion_tokens)
|
1043 |
|
1044 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1045 |
if __name__ == "__main__":
|
1046 |
# 启动保活线程
|
1047 |
threading.Thread(target=keep_alive, daemon=True).start()
|
|
|
|
|
|
|
|
|
1048 |
port = int(os.environ.get("PORT", 9876))
|
1049 |
app.run(port=port, host="0.0.0.0")
|
|
|
21 |
MODEL_LIST_URL = "https://abacus.ai/api/v0/listExternalApplications"
|
22 |
CHAT_URL = "https://apps.abacus.ai/api/_chatLLMSendMessageSSE"
|
23 |
USER_INFO_URL = "https://abacus.ai/api/v0/_getUserInfo"
|
24 |
+
COMPUTE_POINTS_URL = "https://apps.abacus.ai/api/_getOrganizationComputePoints"
|
25 |
+
COMPUTE_POINTS_LOG_URL = "https://abacus.ai/api/v0/_getOrganizationComputePointLog"
|
26 |
|
27 |
|
28 |
USER_AGENTS = [
|
|
|
53 |
"total": 0 # 总token统计
|
54 |
}
|
55 |
|
56 |
+
# 计算点信息
|
57 |
+
compute_points = {
|
58 |
+
"left": 0, # 剩余计算点
|
59 |
+
"total": 0, # 总计算点
|
60 |
+
"used": 0, # 已使用计算点
|
61 |
+
"percentage": 0, # 使用百分比
|
62 |
+
"last_update": None # 最后更新时间
|
63 |
+
}
|
64 |
+
|
65 |
+
# 计算点使用日志
|
66 |
+
compute_points_log = {
|
67 |
+
"columns": {}, # 列名
|
68 |
+
"log": [] # 日志数据
|
69 |
+
}
|
70 |
+
|
71 |
|
72 |
# HTML模板
|
73 |
INDEX_HTML = """
|
|
|
140 |
.status-value.warning {
|
141 |
color: #ffc107;
|
142 |
}
|
143 |
+
.status-value.danger {
|
144 |
+
color: #dc3545;
|
145 |
+
}
|
146 |
.footer {
|
147 |
margin-top: 2rem;
|
148 |
text-align: center;
|
|
|
203 |
font-family: monospace;
|
204 |
color: #28a745;
|
205 |
}
|
206 |
+
.compute-points {
|
207 |
+
font-family: monospace;
|
208 |
+
color: #6f42c1;
|
209 |
+
font-weight: bold;
|
210 |
+
}
|
211 |
+
.progress-container {
|
212 |
+
width: 100%;
|
213 |
+
height: 10px;
|
214 |
+
background-color: #e9ecef;
|
215 |
+
border-radius: 5px;
|
216 |
+
margin-top: 0.5rem;
|
217 |
+
overflow: hidden;
|
218 |
+
}
|
219 |
+
.progress-bar {
|
220 |
+
height: 100%;
|
221 |
+
border-radius: 5px;
|
222 |
+
background-color: #28a745;
|
223 |
+
}
|
224 |
+
.progress-bar.warning {
|
225 |
+
background-color: #ffc107;
|
226 |
+
}
|
227 |
+
.progress-bar.danger {
|
228 |
+
background-color: #dc3545;
|
229 |
+
}
|
230 |
@media (max-width: 768px) {
|
231 |
.container {
|
232 |
padding: 1rem;
|
|
|
268 |
</div>
|
269 |
</div>
|
270 |
|
271 |
+
<h2>💰 计算点信息</h2>
|
272 |
+
<div class="status-card">
|
273 |
+
<div class="status-item">
|
274 |
+
<span class="status-label">总计算点</span>
|
275 |
+
<span class="status-value compute-points">{{ compute_points.total|int }}</span>
|
276 |
+
</div>
|
277 |
+
<div class="status-item">
|
278 |
+
<span class="status-label">已使用</span>
|
279 |
+
<span class="status-value compute-points">{{ compute_points.used|int }}</span>
|
280 |
+
</div>
|
281 |
+
<div class="status-item">
|
282 |
+
<span class="status-label">剩余</span>
|
283 |
+
<span class="status-value compute-points">{{ compute_points.left|int }}</span>
|
284 |
+
</div>
|
285 |
+
<div class="status-item">
|
286 |
+
<span class="status-label">使用比例</span>
|
287 |
+
<div style="width: 100%; text-align: right;">
|
288 |
+
<span class="status-value compute-points {% if compute_points.percentage > 80 %}danger{% elif compute_points.percentage > 50 %}warning{% endif %}">
|
289 |
+
{{ compute_points.percentage }}%
|
290 |
+
</span>
|
291 |
+
<div class="progress-container">
|
292 |
+
<div class="progress-bar {% if compute_points.percentage > 80 %}danger{% elif compute_points.percentage > 50 %}warning{% endif %}" style="width: {{ compute_points.percentage }}%"></div>
|
293 |
+
</div>
|
294 |
+
</div>
|
295 |
+
</div>
|
296 |
+
{% if compute_points.last_update %}
|
297 |
+
<div class="status-item">
|
298 |
+
<span class="status-label">最后更新时间</span>
|
299 |
+
<span class="status-value">{{ compute_points.last_update.strftime('%Y-%m-%d %H:%M:%S') }}</span>
|
300 |
+
</div>
|
301 |
+
{% endif %}
|
302 |
+
</div>
|
303 |
+
|
304 |
+
<h2>📊 计算点使用日志</h2>
|
305 |
+
<div class="status-card">
|
306 |
+
<table class="usage-table">
|
307 |
+
<thead>
|
308 |
+
<tr>
|
309 |
+
{% for key, value in compute_points_log.columns.items() %}
|
310 |
+
<th>{{ value }}</th>
|
311 |
+
{% endfor %}
|
312 |
+
</tr>
|
313 |
+
</thead>
|
314 |
+
<tbody>
|
315 |
+
{% for entry in compute_points_log.log %}
|
316 |
+
<tr>
|
317 |
+
{% for key, value in compute_points_log.columns.items() %}
|
318 |
+
<td class="compute-points">{{ entry.get(key, 0) }}</td>
|
319 |
+
{% endfor %}
|
320 |
+
</tr>
|
321 |
+
{% endfor %}
|
322 |
+
</tbody>
|
323 |
+
</table>
|
324 |
+
</div>
|
325 |
+
|
326 |
<h2>🔍 模型使用统计</h2>
|
327 |
<div class="status-card">
|
328 |
<div class="status-item">
|
|
|
1082 |
|
1083 |
@app.route("/", methods=["GET"])
|
1084 |
def index():
|
1085 |
+
# 在每次访问首页时更新计算点信息
|
1086 |
+
get_compute_points()
|
1087 |
+
|
1088 |
uptime = datetime.now() - START_TIME
|
1089 |
days = uptime.days
|
1090 |
hours, remainder = divmod(uptime.seconds, 3600)
|
|
|
1105 |
models=sorted(list(MODELS)),
|
1106 |
year=datetime.now().year,
|
1107 |
model_stats=model_usage_stats,
|
1108 |
+
total_tokens=total_tokens,
|
1109 |
+
compute_points=compute_points,
|
1110 |
+
compute_points_log=compute_points_log
|
1111 |
)
|
1112 |
|
1113 |
|
|
|
1146 |
total_tokens["total"] += (prompt_tokens + completion_tokens)
|
1147 |
|
1148 |
|
1149 |
+
# 获取计算点信息
|
1150 |
+
def get_compute_points():
|
1151 |
+
global compute_points, USER_DATA
|
1152 |
+
|
1153 |
+
if USER_NUM == 0:
|
1154 |
+
return
|
1155 |
+
|
1156 |
+
try:
|
1157 |
+
# 使用第一个用户的会话和凭据
|
1158 |
+
session, cookies, session_token, _, _ = USER_DATA[0]
|
1159 |
+
|
1160 |
+
# 检查token是否有效
|
1161 |
+
if is_token_expired(session_token):
|
1162 |
+
session_token = refresh_token(session, cookies)
|
1163 |
+
if not session_token:
|
1164 |
+
print("刷新token失败,无法获取计算点信息")
|
1165 |
+
return
|
1166 |
+
USER_DATA[0] = (session, cookies, session_token, USER_DATA[0][3], USER_DATA[0][4])
|
1167 |
+
|
1168 |
+
headers = {
|
1169 |
+
"accept": "application/json, text/plain, */*",
|
1170 |
+
"accept-language": "zh-CN,zh;q=0.9",
|
1171 |
+
"baggage": f"sentry-environment=production,sentry-release=93da8385541a6ce339b1f41b0c94428c70657e22,sentry-public_key=3476ea6df1585dd10e92cdae3a66ff49,sentry-trace_id={TRACE_ID}",
|
1172 |
+
"reai-ui": "1",
|
1173 |
+
"sec-ch-ua": "\"Chromium\";v=\"116\", \"Not)A;Brand\";v=\"24\", \"Google Chrome\";v=\"116\"",
|
1174 |
+
"sec-ch-ua-mobile": "?0",
|
1175 |
+
"sec-ch-ua-platform": "\"Windows\"",
|
1176 |
+
"sec-fetch-dest": "empty",
|
1177 |
+
"sec-fetch-mode": "cors",
|
1178 |
+
"sec-fetch-site": "same-origin",
|
1179 |
+
"sentry-trace": SENTRY_TRACE,
|
1180 |
+
"session-token": session_token,
|
1181 |
+
"x-abacus-org-host": "apps",
|
1182 |
+
"cookie": cookies
|
1183 |
+
}
|
1184 |
+
|
1185 |
+
response = session.get(
|
1186 |
+
COMPUTE_POINTS_URL,
|
1187 |
+
headers=headers
|
1188 |
+
)
|
1189 |
+
|
1190 |
+
if response.status_code == 200:
|
1191 |
+
result = response.json()
|
1192 |
+
if result.get("success") and "result" in result:
|
1193 |
+
data = result["result"]
|
1194 |
+
compute_points["left"] = data.get("computePointsLeft", 0)
|
1195 |
+
compute_points["total"] = data.get("totalComputePoints", 0)
|
1196 |
+
compute_points["used"] = compute_points["total"] - compute_points["left"]
|
1197 |
+
compute_points["percentage"] = round((compute_points["used"] / compute_points["total"]) * 100, 2) if compute_points["total"] > 0 else 0
|
1198 |
+
compute_points["last_update"] = datetime.now()
|
1199 |
+
print(f"计算点信息更新成功: 剩余 {compute_points['left']}, 总计 {compute_points['total']}")
|
1200 |
+
|
1201 |
+
# 获取计算点使用日志
|
1202 |
+
get_compute_points_log(session, cookies, session_token)
|
1203 |
+
else:
|
1204 |
+
print(f"获取计算点信息失败: {result.get('error', '未知错误')}")
|
1205 |
+
else:
|
1206 |
+
print(f"获取计算点信息失败,状态码: {response.status_code}")
|
1207 |
+
except Exception as e:
|
1208 |
+
print(f"获取计算点信息异常: {e}")
|
1209 |
+
|
1210 |
+
# 获取计算点使用日志
|
1211 |
+
def get_compute_points_log(session, cookies, session_token):
|
1212 |
+
global compute_points_log
|
1213 |
+
|
1214 |
+
try:
|
1215 |
+
headers = {
|
1216 |
+
"accept": "application/json, text/plain, */*",
|
1217 |
+
"accept-language": "zh-CN,zh;q=0.9",
|
1218 |
+
"content-type": "application/json",
|
1219 |
+
"reai-ui": "1",
|
1220 |
+
"sec-ch-ua": "\"Chromium\";v=\"116\", \"Not)A;Brand\";v=\"24\", \"Google Chrome\";v=\"116\"",
|
1221 |
+
"sec-ch-ua-mobile": "?0",
|
1222 |
+
"sec-ch-ua-platform": "\"Windows\"",
|
1223 |
+
"sec-fetch-dest": "empty",
|
1224 |
+
"sec-fetch-mode": "cors",
|
1225 |
+
"sec-fetch-site": "same-site",
|
1226 |
+
"session-token": session_token,
|
1227 |
+
"x-abacus-org-host": "apps",
|
1228 |
+
"cookie": cookies
|
1229 |
+
}
|
1230 |
+
|
1231 |
+
response = session.post(
|
1232 |
+
COMPUTE_POINTS_LOG_URL,
|
1233 |
+
headers=headers,
|
1234 |
+
json={"byLlm": True}
|
1235 |
+
)
|
1236 |
+
|
1237 |
+
if response.status_code == 200:
|
1238 |
+
result = response.json()
|
1239 |
+
if result.get("success") and "result" in result:
|
1240 |
+
data = result["result"]
|
1241 |
+
compute_points_log["columns"] = data.get("columns", {})
|
1242 |
+
compute_points_log["log"] = data.get("log", [])
|
1243 |
+
print(f"计算点使用日志更新成功,获取到 {len(compute_points_log['log'])} 条记录")
|
1244 |
+
else:
|
1245 |
+
print(f"获取计算点使用日志失败: {result.get('error', '未知错误')}")
|
1246 |
+
else:
|
1247 |
+
print(f"获取计算点使用日志失败,状态码: {response.status_code}")
|
1248 |
+
except Exception as e:
|
1249 |
+
print(f"获取计算点��用日志异常: {e}")
|
1250 |
+
|
1251 |
+
|
1252 |
if __name__ == "__main__":
|
1253 |
# 启动保活线程
|
1254 |
threading.Thread(target=keep_alive, daemon=True).start()
|
1255 |
+
|
1256 |
+
# 获取初始计算点信息
|
1257 |
+
get_compute_points()
|
1258 |
+
|
1259 |
port = int(os.environ.get("PORT", 9876))
|
1260 |
app.run(port=port, host="0.0.0.0")
|