Files
xas-test-library/console/model_preflight.py
T

55 lines
2.7 KiB
Python

"""One bounded, read-only metadata request to a registered loopback model service."""
import ipaddress
import json
from pathlib import Path
import re
import shlex
import urllib.error
import urllib.request
from urllib.parse import urlsplit
class NoRedirect(urllib.request.HTTPRedirectHandler):
def redirect_request(self, *args):
return None
def check_model(target, credential_files):
result = {'name': '模型身份', 'ok': False, 'message': '模型目录检查未完成'}
try:
url = urlsplit(target['url'])
if (url.scheme != 'http' or not ipaddress.ip_address(url.hostname).is_loopback
or url.username or url.password or url.query or url.fragment or url.path not in ('', '/')):
raise ValueError('仅允许登记的本机模型服务')
key = ''
for filename in credential_files:
path = Path(filename)
if path.stat().st_size > 262144:
raise ValueError('认证引用文件过大')
for line in path.read_text().splitlines():
match = re.match(r'^(?:export\s+)?VLLM_API_KEY=(.*)$', line.strip())
if not match:
continue
values = shlex.split(match[1], comments=True)
if len(values) > 1:
raise ValueError('认证引用格式不支持')
key = values[0] if values else ''
headers = {'Authorization': 'Bearer ' + key} if key else {}
request = urllib.request.Request(target['url'].rstrip('/') + '/v1/models', headers=headers)
opener = urllib.request.build_opener(urllib.request.ProxyHandler({}), NoRedirect())
with opener.open(request, timeout=3) as response:
data = response.read(262145)
if len(data) > 262144:
raise ValueError('模型目录超过检查上限')
payload = json.loads(data)
models = payload.get('data') if isinstance(payload, dict) else None
if not isinstance(models, list) or any(not isinstance(m, dict) or not isinstance(m.get('id'), str) for m in models):
raise ValueError('模型目录格式不支持')
result['ok'] = any(m['id'] == target['model'] for m in models)
result['message'] = ('已核对模型名称:' if result['ok'] else '当前服务未提供登记的模型名称:') + target['model']
except urllib.error.HTTPError as exc:
result['message'] = f'模型目录校验失败(HTTP {exc.code}),请核对服务与认证配置;未发送推理'
except (OSError, ValueError, TypeError, KeyError):
result['message'] = '模型目录或认证引用不可用,未发送推理;请核对原服务配置'
return result