Decoder2704/python-chatbot-jay
0
1#!/usr/bin/env python32"""3Standalone HTTP checks against the local FastAPI backend.4 5Assumes the server is running at http://127.0.0.1:8000 (e.g. uvicorn app.main:app).6 7Usage:8 cd backend && uvicorn app.main:app --host 127.0.0.1 --port 80009 python test_api.py10"""11 12from __future__ import annotations13 14import json15import sys16import urllib.error17import urllib.request18from typing import Any19 20BASE_URL = "http://127.0.0.1:8000"21REQUEST_TIMEOUT_S = 12022 23SAMPLE_PYTHON_QUESTIONS = [24 "How do I read a file in Python?",25 "What is a list comprehension?",26 "How do I install packages with pip?",27 "How do I parse JSON in Python?",28 "What is a virtual environment?",29 "What is the difference between == and is?",30]31 32 33def _request_json(34 method: str,35 path: str,36 body: dict[str, Any] | None = None,37) -> tuple[int, Any | str]:38 """Return (status_code, parsed_json) or (status_code, raw_body_str) if JSON decode fails."""39 url = f"{BASE_URL.rstrip('/')}{path}"40 data: bytes | None = None41 headers = {"Accept": "application/json"}42 if body is not None:43 data = json.dumps(body).encode("utf-8")44 headers["Content-Type"] = "application/json"45 46 req = urllib.request.Request(url, data=data, method=method, headers=headers)47 48 try:49 with urllib.request.urlopen(req, timeout=REQUEST_TIMEOUT_S) as resp:50 raw = resp.read().decode("utf-8")51 status = resp.status52 except urllib.error.HTTPError as exc:53 status = exc.code54 raw = exc.read().decode("utf-8", errors="replace")55 except urllib.error.URLError as exc:56 raise ConnectionError(f"Cannot reach {url}: {exc.reason}") from exc57 except TimeoutError as exc:58 raise ConnectionError(f"Request timed out: {url}") from exc59 60 if not raw.strip():61 return status, None62 try:63 return status, json.loads(raw)64 except json.JSONDecodeError:65 return status, raw66 67 68def _print_response(label: str, status: int, payload: Any) -> None:69 print(f"{label}")70 print(f" Status: {status}")71 print(f" JSON: {json.dumps(payload, indent=2) if isinstance(payload, (dict, list)) else payload!r}")72 print()73 74 75def main() -> int:76 print(f"Testing backend at {BASE_URL}\n")77 78 try:79 status, payload = _request_json("GET", "/health")80 except ConnectionError as exc:81 print(f"ERROR: {exc}", file=sys.stderr)82 print("Is the server running? Example: cd backend && uvicorn app.main:app --host 127.0.0.1 --port 8000", file=sys.stderr)83 return 184 85 _print_response("GET /health", status, payload)86 if status != 200:87 print("ERROR: /health did not return 200", file=sys.stderr)88 return 189 90 for i, question in enumerate(SAMPLE_PYTHON_QUESTIONS, start=1):91 print(f"POST /chat - sample {i}/{len(SAMPLE_PYTHON_QUESTIONS)}")92 print(f" Question: {question}")93 try:94 status, payload = _request_json(95 "POST",96 "/chat",97 body={"message": question},98 )99 except ConnectionError as exc:100 print(f"ERROR: {exc}", file=sys.stderr)101 return 1102 103 _print_response(" Response", status, payload)104 if status != 200:105 print(f"ERROR: /chat returned {status} for sample {i}", file=sys.stderr)106 return 1107 108 print("All checks passed.")109 return 0110 111 112if __name__ == "__main__":113 raise SystemExit(main())114 