51 lines
2.4 KiB
Python
Executable File
51 lines
2.4 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
"""Acceptance probe: requires a local non-sensitive speech WAV argument."""
|
|
import argparse
|
|
import json
|
|
from pathlib import Path
|
|
import urllib.error
|
|
import urllib.request
|
|
import uuid
|
|
|
|
parser=argparse.ArgumentParser()
|
|
parser.add_argument('audio',type=Path,help='Non-sensitive public or synthetic speech WAV')
|
|
parser.add_argument('--base-url',default='http://127.0.0.1:8001')
|
|
args=parser.parse_args()
|
|
root=Path(__file__).resolve().parent
|
|
values=dict(line.strip().split('=',1) for line in (root/'.env').read_text().splitlines() if line and not line.startswith('#'))
|
|
secret=values['ASR_API_KEY']
|
|
base=args.base_url.rstrip('/')
|
|
assert base in ('http://127.0.0.1:8001','http://localhost:8001'), 'Probe only supports loopback'
|
|
|
|
def request(path,data=None,headers=None):
|
|
req=urllib.request.Request(base+path,data=data,headers=headers or {})
|
|
with urllib.request.urlopen(req,timeout=180) as response:
|
|
return response.status,response.read()
|
|
|
|
status,body=request('/health')
|
|
assert status==200
|
|
print(json.dumps({'event':'health_pass','http_status':status,'body':body.decode()}))
|
|
try:
|
|
status,body=request('/v1/models')
|
|
except urllib.error.HTTPError as error:
|
|
assert error.code==401,error.code
|
|
print(json.dumps({'event':'unauthenticated_denied','http_status':error.code}))
|
|
else:
|
|
raise AssertionError('Unauthenticated model request was not denied')
|
|
headers={'Authorization':'Bearer '+secret}
|
|
status,body=request('/v1/models',headers=headers)
|
|
models=json.loads(body)
|
|
assert any(row['id']=='Qwen/Qwen3-ASR-1.7B' for row in models['data']),models
|
|
print(json.dumps({'event':'models_pass','http_status':status,'body':models}))
|
|
audio=args.audio.read_bytes()
|
|
assert 44<len(audio)<=25*1024*1024, 'Speech fixture must be 44 bytes..25MiB'
|
|
boundary='asr-probe-'+uuid.uuid4().hex
|
|
prefix=(f'--{boundary}\r\nContent-Disposition: form-data; name="model"\r\n\r\nQwen/Qwen3-ASR-1.7B\r\n'
|
|
f'--{boundary}\r\nContent-Disposition: form-data; name="file"; filename="fixture.wav"\r\nContent-Type: audio/wav\r\n\r\n').encode()
|
|
payload=prefix+audio+f'\r\n--{boundary}--\r\n'.encode()
|
|
headers['Content-Type']='multipart/form-data; boundary='+boundary
|
|
status,body=request('/v1/audio/transcriptions',data=payload,headers=headers)
|
|
transcript=json.loads(body)
|
|
assert status==200 and isinstance(transcript.get('text'),str) and transcript['text'].strip(),transcript
|
|
print(json.dumps({'event':'transcription_pass','http_status':status,'body':transcript},ensure_ascii=False))
|