Edge /api/vehicles (RDW NL, live now) + /api/screen (OpenSanctions, live now), both defer to engine when ENGINE_URL set. Engine: /vehicles/{plate} + /screen endpoints; workers/resolve (blocking+fuzzy entity resolution, now used by pipeline); workers/queue (in-process job queue); sources/financials (Companies House accounts + XBRL path). py_compile + tsc + next build green.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
35 lines
1.4 KiB
Python
35 lines
1.4 KiB
Python
"""
|
|
Structured financials (docs/06). XBRL/iXBRL is the fast, exact lane (not OCR).
|
|
Companies House publishes accounts as iXBRL; this fetches the accounts filing
|
|
history (real, key-gated) and documents the XBRL extraction step.
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
import os
|
|
from typing import Any
|
|
|
|
import httpx
|
|
|
|
USER_AGENT = "0pt-data-engine/0.1 (+https://0pt.app; SIAX)"
|
|
|
|
|
|
async def companies_house_filings(number: str) -> dict[str, Any]:
|
|
key = os.getenv("COMPANIES_HOUSE_API_KEY")
|
|
if not key:
|
|
return {"company": number, "filings": [], "note": "level0: kräver COMPANIES_HOUSE_API_KEY"}
|
|
url = f"https://api.company-information.service.gov.uk/company/{number}/filing-history?category=accounts"
|
|
async with httpx.AsyncClient(headers={"User-Agent": USER_AGENT}, timeout=15) as c:
|
|
r = await c.get(url, auth=(key, ""))
|
|
if r.status_code != 200:
|
|
return {"company": number, "filings": []}
|
|
items = r.json().get("items", [])
|
|
return {
|
|
"company": number,
|
|
"source": "companies_house",
|
|
"filings": [{"date": i.get("date"), "type": i.get("type"), "description": i.get("description")} for i in items[:10]],
|
|
}
|
|
|
|
# XBRL extraction (extension): with `arelle` installed, download each accounts
|
|
# filing's iXBRL document and pull tagged facts (turnover, profit, employees)
|
|
# into fact_financials with provenance. Structured, exact — never OCR for XBRL.
|