lazyflat/web/apply_client.py
EiSiMo cb617dd38a perf + simpler: composite index, range-filtered protokoll, simpler profile
- Migration v9 adds idx_applications_user_flat_started on
  (user_id, flat_id, started_at DESC). Covers latest_applications_by_flat
  inner GROUP BY and the outer JOIN without a table scan.
- Push the protokoll date range into SQL instead of pulling 5000 rows
  into Python and filtering there: new audit_in_range / errors_in_range
  helpers with a shared _range_filter_rows impl. Protokoll page limits
  500, CSV export 5000.
- _row_to_profile collapses to `dict(profile_row)`. ProfileModel (Pydantic)
  already validates and coerces types on the apply side, extras ignored.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-21 19:16:45 +02:00

53 lines
1.7 KiB
Python

import logging
import requests
from settings import APPLY_TIMEOUT, APPLY_URL, INTERNAL_API_KEY
logger = logging.getLogger("web.apply_client")
def _row_to_profile(profile_row) -> dict:
"""Convert a user_profiles row into the payload dict for /apply.
Apply-side ProfileModel (Pydantic) validates + coerces types; we just
hand over whatever the row has. `updated_at` and any other extra keys
are ignored by the model."""
if profile_row is None:
return {}
return dict(profile_row)
class ApplyClient:
def __init__(self):
self.base = APPLY_URL.rstrip("/")
self.timeout = APPLY_TIMEOUT
self.headers = {"X-Internal-Api-Key": INTERNAL_API_KEY}
def health(self) -> bool:
try:
r = requests.get(f"{self.base}/health", timeout=5)
return r.ok
except requests.RequestException:
return False
def apply(self, url: str, profile: dict, submit_forms: bool,
application_id: int | None = None) -> dict:
body = {
"url": url,
"profile": profile,
"submit_forms": bool(submit_forms),
"application_id": application_id,
}
try:
r = requests.post(
f"{self.base}/apply", json=body,
headers=self.headers, timeout=self.timeout,
)
if r.status_code >= 400:
return {"success": False,
"message": f"apply HTTP {r.status_code}: {r.text[:300]}",
"provider": "", "forensics": {}}
return r.json()
except requests.RequestException as e:
return {"success": False, "message": f"apply unreachable: {e}",
"provider": "", "forensics": {}}