saitejatirunagari Claude Opus 4.8 commited on
Commit
8970674
·
1 Parent(s): 349d7f0

test: deployment + API-route smoke scripts (deterministic PDF, two-parser)

Browse files
Files changed (1) hide show
  1. scripts/deploy_smoke.py +78 -0
scripts/deploy_smoke.py ADDED
@@ -0,0 +1,78 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Deployment smoke test against the LIVE HF endpoint (deterministic pipeline).
2
+
3
+ Waits for the Space to be up, POSTs a real JD + the default résumé to /api/generate
4
+ (v1), decodes the returned PDF, and parses it with BOTH pdftotext and pdfplumber.
5
+ No LLM dependency — the deterministic pipeline must return a real PDF.
6
+ """
7
+ import base64
8
+ import os
9
+ import re
10
+ import sys
11
+ import time
12
+
13
+ import requests
14
+
15
+ sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
16
+
17
+ BASE = "https://saitejatirunagari-jaa-ats-tool.hf.space"
18
+ OUT = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))),
19
+ "data", "acceptance", "out")
20
+ os.makedirs(OUT, exist_ok=True)
21
+
22
+
23
+ def _wait_up(tries=30, delay=15):
24
+ for i in range(tries):
25
+ try:
26
+ r = requests.get(f"{BASE}/api/health", timeout=20)
27
+ if r.status_code == 200:
28
+ print(f"[health] up after {i*delay}s: {r.text[:120]}")
29
+ return True
30
+ except Exception as e:
31
+ print(f"[health] try {i}: {str(e)[:60]}")
32
+ time.sleep(delay)
33
+ return False
34
+
35
+
36
+ def main():
37
+ print("Waiting for deployment (HF rebuild)…")
38
+ if not _wait_up():
39
+ print("DEPLOY SMOKE: endpoint never healthy"); return
40
+ jd = re.sub(r"SOURCE_URL:.*", "",
41
+ open(os.path.join(os.path.dirname(OUT), "jd1_stripe_payments.txt"),
42
+ encoding="utf-8").read(), count=1).strip()
43
+ data = {"jd_text": jd, "job_title": "Product Manager, Payments",
44
+ "company": "Stripe", "version": "v1"}
45
+ print("POST /api/generate …")
46
+ try:
47
+ r = requests.post(f"{BASE}/api/generate", data=data, timeout=180)
48
+ except Exception as e:
49
+ print("DEPLOY SMOKE: request failed:", str(e)[:200]); return
50
+ print("HTTP", r.status_code)
51
+ try:
52
+ j = r.json()
53
+ except Exception:
54
+ print("non-JSON response:", r.text[:300]); return
55
+ print("keys:", sorted(list(j.keys()))[:20])
56
+ print("status:", j.get("status"), "| source:", j.get("source"),
57
+ "| pct:", j.get("external_coverage_pct") or j.get("pct"))
58
+ pdfb = j.get("pdf_b64")
59
+ if not pdfb:
60
+ print("DEPLOY SMOKE: no pdf_b64. error:", j.get("error"), j.get("detail"))
61
+ return
62
+ path = os.path.join(OUT, "deploy_smoke.pdf")
63
+ with open(path, "wb") as f:
64
+ f.write(base64.b64decode(pdfb))
65
+ print("saved:", path, os.path.getsize(path), "bytes")
66
+ # two-parser parse of the DOWNLOADED PDF
67
+ from src.pdf_validate import _extract_pdf_text, _pdftotext_extract
68
+ a = _extract_pdf_text(path) or ""
69
+ b = _pdftotext_extract(path) or ""
70
+ print(f"two-parser: pdfplumber={len(a)}ch pdftotext={len(b)}ch")
71
+ for kw in ["stakeholder", "roadmap", "cross-functional", "product"]:
72
+ print(f" {kw}: pdfplumber={kw in a.lower()} pdftotext={kw in b.lower()}")
73
+ print("DEPLOY SMOKE: PASSED (endpoint returned a real, two-parser-readable PDF)"
74
+ if a and b else "DEPLOY SMOKE: PDF not parseable by both")
75
+
76
+
77
+ if __name__ == "__main__":
78
+ main()