b3c3e2a3b2
- backend/app: FastAPI API wrapping the CAD skill modules - upload -> job -> poll -> model / BOM / artifacts -> geometry query - SQLite via SQLModel (Model, Job, BomRow, QueryLog) - ThreadPoolExecutor worker, serialized, with live stage updates - docker-compose.yml: dev server (mounts source, --reload) on :8000 - api-test.sh: end-to-end live validation script - requirements.txt: add fastapi, uvicorn, python-multipart, sqlmodel - external_diagram.py: port active-area detection OCC.Core -> OCP - .gitignore, PHASE1.md Validated live: MR16 round-trip passes (28 BOM rows, 12 artifacts, bounding-box query, xlsx download; active-area detection working). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
62 lines
2.3 KiB
Bash
Executable File
62 lines
2.3 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Phase 1 live validation — exercises the API end to end against a running server
|
|
# (docker compose up). Upload a sample, poll the job, read model detail, download
|
|
# an artifact, run a geometry query.
|
|
#
|
|
# docker compose up -d && ./api-test.sh
|
|
set -uo pipefail
|
|
cd "$(dirname "$0")"
|
|
|
|
BASE="${BASE:-http://localhost:8000}"
|
|
SAMPLE="${SAMPLE:-skill.src/MR16s Gen1_EN.step}"
|
|
PYJ() { python3 -c "import sys,json$1"; } # tiny JSON helper
|
|
|
|
echo "== health =="
|
|
curl -fsS "$BASE/api/health"; echo
|
|
|
|
echo "== upload ($SAMPLE) =="
|
|
resp=$(curl -fsS -F "file=@${SAMPLE}" -F "diagram=true" "$BASE/api/upload")
|
|
echo "$resp"
|
|
job_id=$(PYJ ";print(json.load(sys.stdin)['job_id'])" <<<"$resp")
|
|
model_id=$(PYJ ";print(json.load(sys.stdin)['model_id'])" <<<"$resp")
|
|
|
|
echo "== poll job $job_id =="
|
|
status=""
|
|
for i in $(seq 1 200); do
|
|
j=$(curl -fsS "$BASE/api/jobs/$job_id")
|
|
status=$(PYJ ";print(json.load(sys.stdin)['status'])" <<<"$j")
|
|
stage=$(PYJ ";print(json.load(sys.stdin).get('stage'))" <<<"$j")
|
|
echo " [$i] status=$status stage=$stage"
|
|
[ "$status" = "done" ] && break
|
|
[ "$status" = "error" ] && { echo "$j"; exit 1; }
|
|
sleep 3
|
|
done
|
|
[ "$status" = "done" ] || { echo "TIMEOUT waiting for job"; exit 1; }
|
|
|
|
echo "== model $model_id detail =="
|
|
detail=$(curl -fsS "$BASE/api/models/$model_id")
|
|
echo "$detail" | PYJ "
|
|
d=json.load(sys.stdin); m=d['model']
|
|
print(' backend:', m['backend'], '| faces:', m['face_count'], '| parts:', m['part_count'])
|
|
print(' bbox(mm):', m['bbox_x_mm'], m['bbox_y_mm'], m['bbox_z_mm'], '| chinese:', m['has_chinese'])
|
|
print(' bom rows:', len(d['bom']))
|
|
print(' artifacts:', d['artifacts'])
|
|
"
|
|
|
|
echo "== download .xlsx artifact =="
|
|
art=$(echo "$detail" | PYJ ";print(next((a for a in json.load(sys.stdin)['artifacts'] if a.endswith('.xlsx')),''))")
|
|
if [ -n "$art" ]; then
|
|
enc=$(python3 -c "import urllib.parse,sys;print(urllib.parse.quote(sys.argv[1]))" "$art")
|
|
curl -fsS -o /tmp/api_test_bom.xlsx "$BASE/api/models/$model_id/artifacts/$enc"
|
|
echo " downloaded '$art' -> $(wc -c < /tmp/api_test_bom.xlsx) bytes"
|
|
else
|
|
echo " no .xlsx artifact found"; exit 1
|
|
fi
|
|
|
|
echo "== geometry query =="
|
|
curl -fsS -X POST -H 'Content-Type: application/json' \
|
|
-d '{"query":"bounding box"}' "$BASE/api/models/$model_id/query" \
|
|
| PYJ ";print(json.load(sys.stdin)['result'][:500])"
|
|
|
|
echo "== API TEST PASSED =="
|