feat: AR-VINchecker v1.0 — VIN report generator with AI analysis

FastAPI server querying NHTSA/EPA APIs, generating PDF reports
with risk scoring, and local Ollama AI analysis via DealAnalyzer.
Security hardened: XSS fix, SSRF protection, CORS restricted.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-07-03 11:40:35 -04:00
commit dc3ec90109
18 changed files with 1970 additions and 0 deletions
+83
View File
@@ -0,0 +1,83 @@
import httpx
_VPIC_BASE = "https://vpic.nhtsa.dot.gov/api/vehicles"
_NHTSA_BASE = "https://api.nhtsa.gov"
_VPIC_FIELDS = {
"Make", "Model", "Model Year", "Trim", "Body Class",
"Displacement (L)", "Engine Number of Cylinders", "Fuel Type - Primary",
"Drive Type", "Transmission Style", "Plant Country",
"Electrification Level", "Engine Model",
}
_FIELD_MAP = {
"Make": "Make",
"Model": "Model",
"Model Year": "ModelYear",
"Trim": "Trim",
"Body Class": "BodyClass",
"Displacement (L)": "DisplacementL",
"Engine Number of Cylinders": "Cylinders",
"Fuel Type - Primary": "FuelType",
"Drive Type": "DriveType",
"Transmission Style": "Transmission",
"Plant Country": "PlantCountry",
"Electrification Level": "EVLevel",
"Engine Model": "EngineModel",
}
async def decode_vin(vin: str) -> dict:
url = f"{_VPIC_BASE}/decodevin/{vin}?format=json"
try:
async with httpx.AsyncClient(timeout=15) as client:
resp = await client.get(url)
resp.raise_for_status()
data = resp.json()
except Exception:
return {}
result: dict = {}
for item in data.get("Results", []):
var = item.get("Variable", "")
val = (item.get("Value") or "").strip()
if var in _FIELD_MAP and val and val not in ("Not Applicable", "null", "None"):
result[_FIELD_MAP[var]] = val
return result
async def fetch_recalls(make: str, model: str, year: str) -> list:
url = f"{_NHTSA_BASE}/recalls/recallsByVehicle"
params = {"make": make, "model": model, "modelYear": year}
try:
async with httpx.AsyncClient(timeout=15) as client:
resp = await client.get(url, params=params)
resp.raise_for_status()
return resp.json().get("results", [])
except Exception:
return []
async def fetch_complaints(make: str, model: str, year: str) -> list:
url = f"{_NHTSA_BASE}/complaints/complaintsByVehicle"
params = {"make": make, "model": model, "modelYear": year}
try:
async with httpx.AsyncClient(timeout=15) as client:
resp = await client.get(url, params=params)
resp.raise_for_status()
return resp.json().get("results", [])
except Exception:
return []
async def fetch_investigations(make: str, model: str, year: str) -> list:
url = f"{_NHTSA_BASE}/investigations/investigationsByVehicle"
params = {"make": make, "model": model, "modelYear": year}
try:
async with httpx.AsyncClient(timeout=15) as client:
resp = await client.get(url, params=params)
resp.raise_for_status()
return resp.json().get("results", [])
except Exception:
return []