RandomZ / smoke_test.py
StormShadow308's picture
- Updated `.env.example` to include new settings for bulk upload limits and batch processing.
3c31a2a
Raw
History Blame Contribute Delete
4.49 kB
"""End-to-end smoke test: upload β†’ ingest β†’ create report β†’ generate β†’ read sections."""
import asyncio
import json
from io import BytesIO
import httpx
from docx import Document as DocxDoc
async def run() -> None:
headers = {"X-Tenant-ID": "demo_tenant"}
async with httpx.AsyncClient(
base_url="http://localhost:8000", headers=headers, timeout=60.0
) as c:
# ── Step 1: Upload a DOCX ─────────────────────────────────────────────
buf = BytesIO()
d = DocxDoc()
d.add_heading("SAMPLE: 12 High Street, London NW3", 1)
d.add_paragraph("SAMPLE: The property is a semi-detached house built circa 1978.")
d.add_paragraph("SAMPLE: Floor area approximately 95 sqm. Located in NW3 postcode.")
d.add_paragraph("SAMPLE: The roof is covered with concrete interlocking tiles in fair condition.")
d.add_paragraph("SAMPLE: External walls are cavity brick construction with UPVC double-glazed windows.")
d.save(buf)
buf.seek(0)
r = await c.post(
"/upload",
files={"file": ("sample.docx", buf, "application/vnd.openxmlformats-officedocument.wordprocessingml.document")},
data={"tenant_id": "demo_tenant"},
)
up = r.json()
print(f"1. Upload: {r.status_code} | doc_id: {up['document_id']}")
doc_id = up["document_id"]
# ── Step 2: Poll until ingested ───────────────────────────────────────
for _ in range(20):
await asyncio.sleep(2)
r = await c.get(f"/documents/{doc_id}/status")
st = r.json()["status"]
print(f" Ingest status: {st}")
if st in ("complete", "failed"):
break
# ── Step 3: Create a report ───────────────────────────────────────────
r = await c.post(f"/reports?document_id={doc_id}")
rep = r.json()
print(f"3. Create report: {r.status_code} | report_id: {rep.get('report_id')}")
report_id = rep.get("report_id")
# ── Step 4: Generate section E2 (Roof coverings) ─────────────────────
payload = {
"template_id": "E2",
"bullets": [
"Roof: concrete interlocking tiles, fair condition",
"Hip roof with valley gutter, no significant defects observed",
"One cracked tile to south slope, recommend monitor",
],
}
r = await c.post(f"/reports/{report_id}/generate", json=payload)
print(f"4. Generate: {r.status_code} | {r.json()}")
# ── Step 5: Poll until complete ───────────────────────────────────────
for _ in range(20):
await asyncio.sleep(2)
r = await c.get(f"/reports/{report_id}/status")
st = r.json()["status"]
print(f" Report status: {st}")
if st in ("complete", "failed"):
break
# ── Step 6: Get generated sections ────────────────────────────────────
r = await c.get(f"/reports/{report_id}/sections")
data = r.json()
print(f"6. Sections: {r.status_code}")
for code, sec in data.get("sections", {}).items():
print(f"\n [{code}] confidence={sec['confidence']:.2f} cached={sec['cached']}")
print(f" TEXT: {sec['text'][:300]}")
if sec.get("provenance"):
print(f" PROVENANCE: {json.dumps(sec['provenance'][:2], indent=2)}")
# ── Step 7: Generate the same section again β€” should be cached ─────────
print("\n7. Generating same section again (should use cache)…")
r = await c.post(f"/reports/{report_id}/generate", json=payload)
await asyncio.sleep(3)
r = await c.get(f"/reports/{report_id}/sections")
data2 = r.json()
for code, sec in data2.get("sections", {}).items():
print(f" [{code}] cached={sec['cached']} (should be True)")
if __name__ == "__main__":
asyncio.run(run())