Skip to content

Commit 15c44ae

Browse files
authored
Update deploy.py
1 parent ae4cb0b commit 15c44ae

File tree

1 file changed

+63
-99
lines changed

1 file changed

+63
-99
lines changed

test/ce/deploy/deploy.py

Lines changed: 63 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,16 @@
1+
import ast
2+
import json
13
import os
2-
import subprocess
4+
import re
35
import signal
46
import socket
5-
import requests
7+
import subprocess
8+
import sys
69
import time
10+
11+
import requests
712
import yaml
8-
import ast
9-
import re
10-
import json
11-
import sys
12-
from flask import Flask, jsonify, request, Response
13+
from flask import Flask, Response, jsonify, request
1314

1415
app = Flask(__name__)
1516

@@ -20,7 +21,7 @@ def get_base_port():
2021
if not nv_visible_devices or nv_visible_devices.lower() == "all":
2122
return 8000
2223
# 提取第一个数字
23-
match = re.search(r'\d+', nv_visible_devices)
24+
match = re.search(r"\d+", nv_visible_devices)
2425
if match:
2526
return int(match.group(0)) * 100 + 8000
2627
return 8000
@@ -29,7 +30,7 @@ def get_base_port():
2930
def is_port_in_use(port):
3031
"""检查端口是否被占用"""
3132
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
32-
return s.connect_ex(('localhost', port)) == 0
33+
return s.connect_ex(("localhost", port)) == 0
3334

3435

3536
def get_available_port(env_key: str, default_start: int):
@@ -69,7 +70,9 @@ def build_command(config):
6970
"""根据配置构建启动命令"""
7071
# 基础命令
7172
cmd = [
72-
"python", "-m", "fastdeploy.entrypoints.openai.api_server",
73+
"python",
74+
"-m",
75+
"fastdeploy.entrypoints.openai.api_server",
7376
]
7477

7578
# 添加配置参数
@@ -97,7 +100,7 @@ def merge_configs(base_config, override_config):
97100
def get_server_pid():
98101
"""获取服务进程ID PORT"""
99102
if os.path.exists(PID_FILE):
100-
with open(PID_FILE, 'r') as f:
103+
with open(PID_FILE, "r") as f:
101104
data = yaml.safe_load(f)
102105
return data
103106
return None
@@ -109,21 +112,19 @@ def is_server_running():
109112
if pid_port is None:
110113
return False, {"status": "Server not running..."}
111114

112-
server_pid, port = pid_port["PID"], pid_port["PORT"]
115+
_, port = pid_port["PID"], pid_port["PORT"]
113116
health_check_endpoint = f"http://0.0.0.0:{port}/health"
114117

115118
if os.path.exists(LOG_FILE):
116-
with open(LOG_FILE, 'r') as f:
119+
with open(LOG_FILE, "r") as f:
117120
msg = f.readlines()
118121
result = parse_tqdm_progress(msg)
119122

120123
try:
121-
response = requests.get(
122-
health_check_endpoint,
123-
timeout=2
124-
)
124+
response = requests.get(health_check_endpoint, timeout=2)
125125
return response.status_code == 200, result
126126
except requests.exceptions.RequestException as e:
127+
print(f"Failed to check server health: {e}")
127128
return False, result
128129

129130

@@ -147,15 +148,11 @@ def parse_tqdm_progress(log_lines):
147148
"speed": data["speed"],
148149
"eta": data["eta"],
149150
"elapsed": data["elapsed"],
150-
"bar": data["bar"].strip()
151+
"bar": data["bar"].strip(),
151152
},
152-
"raw_line": line.strip()
153+
"raw_line": line.strip(),
153154
}
154-
return {
155-
"status": "服务启动中",
156-
"progress": {},
157-
"raw_line": log_lines[-1] if log_lines else "server.log为空"
158-
}
155+
return {"status": "服务启动中", "progress": {}, "raw_line": log_lines[-1] if log_lines else "server.log为空"}
159156

160157

161158
def stop_server(signum=None, frame=None):
@@ -189,8 +186,8 @@ def stop_server(signum=None, frame=None):
189186
except Exception as e:
190187
print(f"Failed to killed process on port: {e}")
191188
# 若log目录存在,则重命名为log_timestamp
192-
if os.path.isdir('./log'):
193-
os.rename('./log', './log_{}'.format(time.strftime("%Y%m%d%H%M%S")))
189+
if os.path.isdir("./log"):
190+
os.rename("./log", "./log_{}".format(time.strftime("%Y%m%d%H%M%S")))
194191

195192
if signum:
196193
sys.exit(0)
@@ -203,15 +200,15 @@ def stop_server(signum=None, frame=None):
203200
signal.signal(signal.SIGTERM, stop_server)
204201

205202

206-
@app.route('/start', methods=['POST'])
203+
@app.route("/start", methods=["POST"])
207204
def start_service():
208205
"""启动大模型推理服务"""
209206
# 检查服务是否已在运行
210207
if is_server_running()[0]:
211208
return Response(
212209
json.dumps({"status": "error", "message": "服务已启动,无需start"}, ensure_ascii=False),
213210
status=400,
214-
content_type='application/json'
211+
content_type="application/json",
215212
)
216213

217214
try:
@@ -235,7 +232,7 @@ def start_service():
235232
return Response(
236233
json.dumps({"status": "error", "message": str(e)}, ensure_ascii=False),
237234
status=500,
238-
content_type='application/json'
235+
content_type="application/json",
239236
)
240237

241238
print("cmd", cmd)
@@ -244,17 +241,11 @@ def start_service():
244241
# 设置环境变量并启动进程
245242
env = os.environ.copy()
246243

247-
with open(LOG_FILE, 'w') as log:
248-
process = subprocess.Popen(
249-
cmd,
250-
stdout=log,
251-
stderr=log,
252-
env=env,
253-
start_new_session=True
254-
)
244+
with open(LOG_FILE, "w") as log:
245+
process = subprocess.Popen(cmd, stdout=log, stderr=log, env=env, start_new_session=True)
255246

256247
# 保存进程ID,port到yaml文件
257-
with open(PID_FILE, 'w') as f:
248+
with open(PID_FILE, "w") as f:
258249
yaml.dump({"PID": process.pid, "PORT": final_config["--port"]}, f)
259250

260251
json_data = {
@@ -267,24 +258,20 @@ def start_service():
267258
"port_info": {
268259
"api_port": FD_API_PORT,
269260
"queue_port": FD_ENGINE_QUEUE_PORT,
270-
"metrics_port": FD_METRICS_PORT
271-
}
261+
"metrics_port": FD_METRICS_PORT,
262+
},
272263
}
273264

274-
return Response(
275-
json.dumps(json_data, ensure_ascii=False),
276-
status=200,
277-
content_type='application/json'
278-
)
265+
return Response(json.dumps(json_data, ensure_ascii=False), status=200, content_type="application/json")
279266
except Exception as e:
280267
return Response(
281268
json.dumps({"status": "error", "message": str(e)}, ensure_ascii=False),
282269
status=500,
283-
content_type='application/json'
270+
content_type="application/json",
284271
)
285272

286273

287-
@app.route('/switch', methods=['POST'])
274+
@app.route("/switch", methods=["POST"])
288275
def switch_service():
289276
"""切换模型服务"""
290277
# kill掉已有服务
@@ -311,7 +298,7 @@ def switch_service():
311298
return Response(
312299
json.dumps({"status": "error", "message": str(e)}, ensure_ascii=False),
313300
status=500,
314-
content_type='application/json'
301+
content_type="application/json",
315302
)
316303

317304
print("cmd", cmd)
@@ -320,17 +307,11 @@ def switch_service():
320307
# 设置环境变量并启动进程
321308
env = os.environ.copy()
322309

323-
with open(LOG_FILE, 'w') as log:
324-
process = subprocess.Popen(
325-
cmd,
326-
stdout=log,
327-
stderr=log,
328-
env=env,
329-
start_new_session=True
330-
)
310+
with open(LOG_FILE, "w") as log:
311+
process = subprocess.Popen(cmd, stdout=log, stderr=log, env=env, start_new_session=True)
331312

332313
# 保存进程ID,port到yaml文件
333-
with open(PID_FILE, 'w') as f:
314+
with open(PID_FILE, "w") as f:
334315
yaml.dump({"PID": process.pid, "PORT": final_config["--port"]}, f)
335316

336317
json_data = {
@@ -343,116 +324,98 @@ def switch_service():
343324
"port_info": {
344325
"api_port": FD_API_PORT,
345326
"queue_port": FD_ENGINE_QUEUE_PORT,
346-
"metrics_port": FD_METRICS_PORT
347-
}
327+
"metrics_port": FD_METRICS_PORT,
328+
},
348329
}
349330

350-
return Response(
351-
json.dumps(json_data, ensure_ascii=False),
352-
status=200,
353-
content_type='application/json'
354-
)
331+
return Response(json.dumps(json_data, ensure_ascii=False), status=200, content_type="application/json")
355332
except Exception as e:
356333
return Response(
357334
json.dumps({"status": "error", "message": str(e)}, ensure_ascii=False),
358335
status=500,
359-
content_type='application/json'
336+
content_type="application/json",
360337
)
361338

362339

363-
@app.route('/status', methods=['GET', 'POST'])
340+
@app.route("/status", methods=["GET", "POST"])
364341
def service_status():
365342
"""检查服务状态"""
366343
health, msg = is_server_running()
367344

368345
if not health:
369-
return Response(
370-
json.dumps(msg, ensure_ascii=False),
371-
status=500,
372-
content_type='application/json'
373-
)
346+
return Response(json.dumps(msg, ensure_ascii=False), status=500, content_type="application/json")
374347

375348
# 检查端口是否监听
376349
ports_status = {
377350
"api_port": FD_API_PORT if is_port_in_use(FD_API_PORT) else None,
378351
"queue_port": FD_ENGINE_QUEUE_PORT if is_port_in_use(FD_ENGINE_QUEUE_PORT) else None,
379-
"metrics_port": FD_METRICS_PORT if is_port_in_use(FD_METRICS_PORT) else None
352+
"metrics_port": FD_METRICS_PORT if is_port_in_use(FD_METRICS_PORT) else None,
380353
}
381354

382355
msg["status"] = "服务启动完成"
383356
msg["ports_status"] = ports_status
384357

385-
return Response(
386-
json.dumps(msg, ensure_ascii=False),
387-
status=200,
388-
content_type='application/json'
389-
)
358+
return Response(json.dumps(msg, ensure_ascii=False), status=200, content_type="application/json")
390359

391360

392-
@app.route('/stop', methods=['POST'])
361+
@app.route("/stop", methods=["POST"])
393362
def stop_service():
394363
"""停止大模型推理服务"""
395364
res, status_code = stop_server()
396365

397366
return res, status_code
398367

399368

400-
@app.route('/config', methods=['GET'])
369+
@app.route("/config", methods=["GET"])
401370
def get_config():
402371
"""获取当前server配置"""
403372
health, msg = is_server_running()
404373

405374
if not health:
406-
return Response(
407-
json.dumps(msg, ensure_ascii=False),
408-
status=500,
409-
content_type='application/json'
410-
)
375+
return Response(json.dumps(msg, ensure_ascii=False), status=500, content_type="application/json")
411376

412377
if not os.path.exists("log/api_server.log"):
413378
return Response(
414379
json.dumps({"message": "api_server.log不存在"}, ensure_ascii=False),
415380
status=500,
416-
content_type='application/json'
381+
content_type="application/json",
417382
)
418383

419384
try:
420385
# 筛选出包含"args:"的行
421-
with open("log/api_server.log", 'r') as f:
386+
with open("log/api_server.log", "r") as f:
422387
lines = [line for line in f.readlines() if "args:" in line]
423388

424389
last_line = lines[-1] if lines else ""
425390

426391
# 使用正则表达式提取JSON格式的配置
427-
match = re.search(r'args\s*[::]\s*(.*)', last_line)
392+
match = re.search(r"args\s*[::]\s*(.*)", last_line)
428393
if not match:
429394
return Response(
430395
json.dumps({"message": "api_server.log中没有args信息,请检查log"}, ensure_ascii=False),
431396
status=500,
432-
content_type='application/json'
397+
content_type="application/json",
433398
)
434399

435400
# 尝试解析JSON
436401
config_json = match.group(1).strip()
437402
config_data = ast.literal_eval(config_json)
438403
print("config_data", config_data, type(config_data))
439404
return Response(
440-
json.dumps({"server_config": config_data}, ensure_ascii=False),
441-
status=200,
442-
content_type='application/json'
405+
json.dumps({"server_config": config_data}, ensure_ascii=False), status=200, content_type="application/json"
443406
)
444407

445408
except Exception as e:
446409
return Response(
447410
json.dumps({"message": "api_server.log解析失败,请检查log", "error": str(e)}, ensure_ascii=False),
448411
status=500,
449-
content_type='application/json'
412+
content_type="application/json",
450413
)
451414

452415

453-
@app.route('/wait_for_infer', methods=['POST'])
416+
@app.route("/wait_for_infer", methods=["POST"])
454417
def wait_for_infer():
455-
timeout = int(request.args.get('timeout', 120)) # 可选超时时间,默认120秒
418+
timeout = int(request.args.get("timeout", 120)) # 可选超时时间,默认120秒
456419
interval = 2
457420
response_interval = 10
458421
start_time = time.time()
@@ -470,18 +433,19 @@ def generate():
470433
ports_status = {
471434
"api_port": FD_API_PORT if is_port_in_use(FD_API_PORT) else None,
472435
"queue_port": FD_ENGINE_QUEUE_PORT if is_port_in_use(FD_ENGINE_QUEUE_PORT) else None,
473-
"metrics_port": FD_METRICS_PORT if is_port_in_use(FD_METRICS_PORT) else None
436+
"metrics_port": FD_METRICS_PORT if is_port_in_use(FD_METRICS_PORT) else None,
474437
}
475438
msg["status"] = "服务启动完成"
476439
msg["ports_status"] = ports_status
477440
yield json.dumps(msg, ensure_ascii=False) + "\n"
478441
break
479442

480443
if elapsed >= timeout:
444+
481445
def tail_file(path, lines=50):
482446
try:
483447
with open(path, "r", encoding="utf-8", errors="ignore") as f:
484-
return ''.join(f.readlines()[-lines:])
448+
return "".join(f.readlines()[-lines:])
485449
except Exception as e:
486450
return f"[无法读取 {path}]: {e}\n"
487451

@@ -501,12 +465,12 @@ def tail_file(path, lines=50):
501465

502466
time.sleep(interval)
503467

504-
return Response(generate(), status=200, content_type='text/plain')
468+
return Response(generate(), status=200, content_type="text/plain")
505469

506470

507-
if __name__ == '__main__':
471+
if __name__ == "__main__":
508472
print(f"FLASK_PORT: {FLASK_PORT}")
509473
print(f"FD_API_PORT: {FD_API_PORT}")
510474
print(f"FD_ENGINE_QUEUE_PORT: {FD_ENGINE_QUEUE_PORT}")
511475
print(f"FD_METRICS_PORT: {FD_METRICS_PORT}")
512-
app.run(host='0.0.0.0', port=FLASK_PORT, debug=False)
476+
app.run(host="0.0.0.0", port=FLASK_PORT, debug=False)

0 commit comments

Comments
 (0)