fix(tradein-phase-c): map house_type 'monolith'→'monolithic' + log 400 body

Avito IMV API rejects raw listings.house_type values 'monolith' and
'monolith_brick' with HTTP 400 silent body. Verified live: panel/brick/
monolithic/block/wood are valid; monolith/monolith_brick fail.

- backfill-house-imv.py: _HOUSE_TYPE_TO_IMV dict + _map_house_type() helper
  applied to median house_type from linked listings
- avito_imv.py: log response.text snippet on >=400 status before raising
  for future contract drift visibility
This commit is contained in:
lekss361 2026-05-24 17:58:52 +03:00
parent bc594e3f79
commit c533d3affd
2 changed files with 23 additions and 6 deletions

View file

@ -334,6 +334,8 @@ def _raise_for_status_categorized(resp: Any, context: str) -> None:
if status >= 500:
raise IMVTransientError(f"Avito {context}: HTTP {status} — transient server error")
if status >= 400:
body_preview = (resp.text or "")[:200]
logger.warning("Avito %s HTTP %d: body=%r", context, status, body_preview)
resp.raise_for_status() # other 4xx → standard HTTPStatusError

View file

@ -51,6 +51,25 @@ logging.basicConfig(
)
logger = logging.getLogger("phase-c")
# Avito IMV API accepts only these house_type values (verified 2026-05-24).
# Our `listings.house_type` may contain pre-2026 values like 'monolith' / 'monolith_brick'.
_HOUSE_TYPE_TO_IMV = {
"panel": "panel",
"brick": "brick",
"monolith": "monolithic", # API renamed; raw value rejected with 400
"monolithic": "monolithic",
"monolith_brick": "monolithic", # API doesn't accept hybrid → fall back to monolithic
"block": "block",
"wood": "wood",
}
_HOUSE_TYPE_DEFAULT = "panel" # most common in EKB; safe default for unknown
def _map_house_type(raw: str | None) -> str:
if not raw:
return _HOUSE_TYPE_DEFAULT
return _HOUSE_TYPE_TO_IMV.get(raw.lower().strip(), _HOUSE_TYPE_DEFAULT)
DATABASE_URL = os.environ.get("DATABASE_URL")
if not DATABASE_URL:
raise SystemExit(
@ -92,12 +111,8 @@ def pick_lot_params(db: Session, house_id: int) -> dict:
"rooms": int(row["rooms"]),
"area_m2": float(row["area_m2"]),
"floor": int(row["floor"] or 1),
"floor_at_home": int(
row["total_floors"] or (house and house["total_floors"]) or 9
),
"house_type": (
row["house_type"] or (house and house["house_type"]) or "panel"
),
"floor_at_home": int(row["total_floors"] or (house and house["total_floors"]) or 9),
"house_type": _map_house_type(row["house_type"] or (house and house["house_type"])),
"renovation_type": "cosmetic",
"has_balcony": True,
"has_loggia": False,