feat: add ImageFind application and release pipelines
This commit is contained in:
@@ -0,0 +1,161 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Read-only live acceptance for audio search and transcript APIs."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import re
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
import httpx
|
||||
from zhconv import convert
|
||||
|
||||
|
||||
def main() -> None:
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("--base-url", required=True)
|
||||
auth = parser.add_mutually_exclusive_group(required=True)
|
||||
auth.add_argument("--password-stdin", action="store_true")
|
||||
auth.add_argument("--token-file", type=Path)
|
||||
args = parser.parse_args()
|
||||
password = sys.stdin.readline().rstrip("\r\n") if args.password_stdin else ""
|
||||
headers = {}
|
||||
if args.token_file is not None:
|
||||
headers["Authorization"] = f"Bearer {args.token_file.read_text().strip()}"
|
||||
client = httpx.Client(
|
||||
base_url=args.base_url.rstrip("/"), headers=headers, timeout=httpx.Timeout(30, connect=10)
|
||||
)
|
||||
try:
|
||||
if args.password_stdin:
|
||||
login = client.post(
|
||||
"/api/v1/auth/login", json={"password": password, "remember_device": False}
|
||||
)
|
||||
login.raise_for_status()
|
||||
csrf = str(login.json().get("csrf_token") or "")
|
||||
if not csrf:
|
||||
raise AssertionError("login response omitted CSRF token")
|
||||
client.headers["X-CSRF-Token"] = csrf
|
||||
password = ""
|
||||
|
||||
status = client.get("/api/v1/status")
|
||||
status.raise_for_status()
|
||||
if status.json().get("version") != "0.5.45":
|
||||
raise AssertionError(f"unexpected version: {status.json().get('version')}")
|
||||
|
||||
coverage_response = client.get("/api/v1/search/coverage")
|
||||
coverage_response.raise_for_status()
|
||||
coverage = coverage_response.json()
|
||||
required = {
|
||||
"total",
|
||||
"indexed",
|
||||
"searchable",
|
||||
"empty",
|
||||
"queued",
|
||||
"running",
|
||||
"failed",
|
||||
"percent",
|
||||
"current_model_percent",
|
||||
}
|
||||
if not required <= coverage.keys():
|
||||
raise AssertionError(f"coverage fields missing: {sorted(required - coverage.keys())}")
|
||||
|
||||
videos_response = client.get("/api/v1/videos?limit=200")
|
||||
videos_response.raise_for_status()
|
||||
videos = videos_response.json()
|
||||
selected = None
|
||||
transcript = None
|
||||
selected_item = None
|
||||
fallback = None
|
||||
for video in videos:
|
||||
response = client.get(f"/api/v1/videos/{video['id']}/transcript?page=1&page_size=30")
|
||||
response.raise_for_status()
|
||||
candidate = response.json()
|
||||
if candidate.get("items"):
|
||||
fallback = fallback or (video, candidate, candidate["items"][0])
|
||||
chinese_item = next(
|
||||
(
|
||||
item
|
||||
for item in candidate["items"]
|
||||
if re.search(r"[\u3400-\u9fff]{2,}", str(item.get("raw_text") or ""))
|
||||
),
|
||||
None,
|
||||
)
|
||||
if chinese_item:
|
||||
selected, transcript, selected_item = video, candidate, chinese_item
|
||||
break
|
||||
if selected is None and fallback:
|
||||
selected, transcript, selected_item = fallback
|
||||
|
||||
checks: dict[str, object] = {
|
||||
"version": status.json()["version"],
|
||||
"coverage": {key: coverage[key] for key in sorted(required)},
|
||||
"transcript_video_found": bool(selected),
|
||||
}
|
||||
resources_response = client.get("/api/v1/system/resources")
|
||||
resources_response.raise_for_status()
|
||||
resources = resources_response.json()
|
||||
diagnostics_response = client.get("/api/v1/system/diagnostics")
|
||||
diagnostics_response.raise_for_status()
|
||||
diagnostics = diagnostics_response.json()
|
||||
models_response = client.get("/api/v1/models")
|
||||
models_response.raise_for_status()
|
||||
models = models_response.json()
|
||||
checks["runtime"] = {
|
||||
"cpu_percent": resources.get("cpu_percent"),
|
||||
"memory_available_bytes": resources.get("memory_available_bytes"),
|
||||
"io": resources.get("io"),
|
||||
"ai_lane": (resources.get("lanes") or {}).get("ai"),
|
||||
"database": diagnostics.get("database"),
|
||||
"event_loop_lag_ms": diagnostics.get("event_loop_lag_ms"),
|
||||
"request_p95_ms": diagnostics.get("request_p95_ms"),
|
||||
"audio_accelerator": ((models.get("accelerator") or {}).get("components") or {}).get("audio"),
|
||||
"audio_health": (models.get("component_health") or {}).get("audio"),
|
||||
}
|
||||
if selected and transcript:
|
||||
first = selected_item or transcript["items"][0]
|
||||
cjk_runs = re.findall(r"[\u3400-\u9fff]{2,}", str(first.get("raw_text") or ""))
|
||||
if cjk_runs:
|
||||
query = cjk_runs[0][: min(6, len(cjk_runs[0]))]
|
||||
variants = list(dict.fromkeys((query, convert(query, "zh-cn"), convert(query, "zh-tw"))))
|
||||
results = []
|
||||
for variant in variants:
|
||||
audio = client.post(
|
||||
"/api/v1/search",
|
||||
json={"text": variant, "recognition_types": ["audio"], "limit": 50},
|
||||
)
|
||||
audio.raise_for_status()
|
||||
audio_ids = {item.get("video_id") for item in audio.json().get("items", [])}
|
||||
combined = client.post("/api/v1/search", json={"text": variant, "limit": 50})
|
||||
combined.raise_for_status()
|
||||
combined_ids = {item.get("video_id") for item in combined.json().get("items", [])}
|
||||
results.append(
|
||||
{
|
||||
"variant_changed": variant != query,
|
||||
"audio_match": selected["id"] in audio_ids,
|
||||
"combined_match": selected["id"] in combined_ids,
|
||||
}
|
||||
)
|
||||
if not all(item["audio_match"] and item["combined_match"] for item in results):
|
||||
raise AssertionError(f"live Chinese audio search mismatch: {results}")
|
||||
checks["chinese_query_length"] = len(query)
|
||||
checks["variant_checks"] = results
|
||||
checks["transcript"] = {
|
||||
"status": transcript.get("status"),
|
||||
"total": transcript.get("total"),
|
||||
"pages": transcript.get("pages"),
|
||||
"items_returned": len(transcript.get("items", [])),
|
||||
}
|
||||
print(json.dumps(checks, ensure_ascii=False, indent=2), flush=True)
|
||||
finally:
|
||||
password = ""
|
||||
try:
|
||||
if args.password_stdin:
|
||||
client.post("/api/v1/auth/logout")
|
||||
finally:
|
||||
client.close()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user