refactor(tradein/scraper-kit): yandex providers on shared _base.py (#2363) #2384

Merged
lekss361 merged 1 commit from feat/tradein-scraper-kit-f4c-yandex-v2 into main 2026-07-04 06:43:18 +00:00
Owner

Summary

Group F4c (эпик #2277, Group F #2352). Миграция yandex/serp.py construction-сайтов BrowserFetcher на shared build_browser_fetcher() из _base.py (F4-Foundation #2358).

Замена PR #2373 — тот упёрся в rebase-конфликт (докстринг в test_kit_serp_proxy_pool.py, куда avito/cian/yandex каждый добавлял свою migration-заметку). Конфликт разрешён 3-way merge'ем (main-сессия), содержательно код-конфликта не было — только проза докстринга. Ветка пересоздана (не force-push).

  • yandex/serp.py::__aenter__BrowserFetcher(...)build_browser_fetcher(self._config, source="yandex", proxy_provider=self._proxy_provider, fetch_timeout_s=_YANDEX_BROWSER_FETCH_TIMEOUT_S) — кастомный fetch_timeout_s=30 проброшен, не потерян.
  • test_kit_serp_proxy_pool.py — yandex-тесты перепатчены с yandex_serp.BrowserFetcher на scraper_kit.providers._base.BrowserFetcher (реальная зависимость после миграции); assertions без изменений. Докстринг обновлён на пост-merge реальность (и yandex, и cian мигрированы → оба патчат _base).

Осознанно НЕ мигрированы (deviation, задокументировано):

  • yandex/detail.py — нет конструкции сессии (0 diff).
  • yandex/newbuilding.py — его config genuinely Optional (callers зовут без config: admin.py, sweep, тесты), а build_browser_fetcher() требует mandatory config → миграция сломала бы regression-тест + потребовала бы трогать out-of-scope callers. Нужен отдельный мини-рефактор (сделать config mandatory) — follow-up.
  • _rotate_ip's curl_cffi-сессия к changeip-API провайдера — намеренно исключена (как и зеркальная в avito), не в Foundation.
  • retry/tarpit-логика fetch_around — НЕ обобщается (решение F4-Foundation).

Review

code-reviewer APPROVE (проверил kwarg-by-kwarg сохранение поведения, fetch_timeout_s threading, scope; re-ran тесты).

Test plan

  • test_kit_serp_proxy_pool.py (yandex+cian) + pipeline_parity2 + newbuilding_endpoint: 19/19 passed после rebase
  • Full backend suite (поверх смерженных avito/cian/domclick F4): 3278 passed, 6 skipped, 1 pre-existing unrelated fail (test_search_cache_hit #2208)
  • ruff check/ruff format — clean

Closes #2363

## Summary Group F4c (эпик #2277, Group F #2352). Миграция `yandex/serp.py` construction-сайтов `BrowserFetcher` на shared `build_browser_fetcher()` из `_base.py` (F4-Foundation #2358). Замена PR #2373 — тот упёрся в rebase-конфликт (докстринг в `test_kit_serp_proxy_pool.py`, куда avito/cian/yandex каждый добавлял свою migration-заметку). Конфликт разрешён 3-way merge'ем (main-сессия), содержательно код-конфликта не было — только проза докстринга. Ветка пересоздана (не force-push). - `yandex/serp.py::__aenter__` — `BrowserFetcher(...)` → `build_browser_fetcher(self._config, source="yandex", proxy_provider=self._proxy_provider, fetch_timeout_s=_YANDEX_BROWSER_FETCH_TIMEOUT_S)` — кастомный `fetch_timeout_s=30` проброшен, не потерян. - `test_kit_serp_proxy_pool.py` — yandex-тесты перепатчены с `yandex_serp.BrowserFetcher` на `scraper_kit.providers._base.BrowserFetcher` (реальная зависимость после миграции); assertions без изменений. Докстринг обновлён на пост-merge реальность (и yandex, и cian мигрированы → оба патчат `_base`). **Осознанно НЕ мигрированы (deviation, задокументировано):** - `yandex/detail.py` — нет конструкции сессии (0 diff). - `yandex/newbuilding.py` — его `config` genuinely Optional (callers зовут без config: admin.py, sweep, тесты), а `build_browser_fetcher()` требует mandatory config → миграция сломала бы regression-тест + потребовала бы трогать out-of-scope callers. Нужен отдельный мини-рефактор (сделать config mandatory) — follow-up. - `_rotate_ip`'s curl_cffi-сессия к changeip-API провайдера — намеренно исключена (как и зеркальная в avito), не в Foundation. - retry/tarpit-логика `fetch_around` — НЕ обобщается (решение F4-Foundation). ## Review `code-reviewer` — ✅ APPROVE (проверил kwarg-by-kwarg сохранение поведения, fetch_timeout_s threading, scope; re-ran тесты). ## Test plan - [x] `test_kit_serp_proxy_pool.py` (yandex+cian) + pipeline_parity2 + newbuilding_endpoint: 19/19 passed после rebase - [x] Full backend suite (поверх смерженных avito/cian/domclick F4): 3278 passed, 6 skipped, 1 pre-existing unrelated fail (test_search_cache_hit #2208) - [x] `ruff check`/`ruff format` — clean Closes #2363
lekss361 added 1 commit 2026-07-04 06:40:53 +00:00
refactor(tradein/scraper-kit): yandex providers on shared _base.py (#2363)
All checks were successful
CI / changes (pull_request) Successful in 10s
CI Trade-In / changes (pull_request) Successful in 11s
CI Trade-In / frontend-checks (pull_request) Has been skipped
CI / backend-tests (pull_request) Has been skipped
CI / frontend-tests (pull_request) Has been skipped
CI / openapi-codegen-check (pull_request) Has been skipped
CI Trade-In / backend-tests (pull_request) Successful in 1m48s
7800f6014a
F4c-yandex (epic #2277 Group F, parent #2352): migrate the SERP scraper's
BrowserFetcher construction onto build_browser_fetcher() from the Foundation
module (#2358, providers/_base.py) instead of local ad-hoc construction.

- yandex/serp.py::__aenter__ now calls build_browser_fetcher(config, source=,
  proxy_provider=, fetch_timeout_s=) instead of constructing BrowserFetcher(...)
  directly. Preserves the existing fetch_timeout_s=30 (see caveat below),
  endpoint/proxy_provider/use_pool resolution byte-for-byte. The retry/tarpit
  logic in fetch_around() (rotate_ip + sleep on status==0/JSON-error) is
  untouched, per the Foundation module's documented exclusion.

Left unchanged (deliberate, not an oversight):
- yandex/serp.py::_rotate_ip's curl_cffi AsyncSession(timeout=30) — this hits
  the mobile-proxy provider's own changeip API, not Yandex; it intentionally
  carries no impersonate/headers/proxy (same as the mirrored avito/serp.py
  rotate-ip session). Not listed among the _base.py docstring's documented
  extraction sites -- consistent exclusion, not a new one.
- yandex/detail.py -- no BrowserFetcher/curl_cffi construction exists in this
  file (uses BaseScraper's httpx-based _http_get). Nothing to migrate.
- yandex/newbuilding.py -- both BrowserFetcher(...) call sites take an
  OPTIONAL `config: ScraperConfig | None`, a genuinely different contract from
  build_browser_fetcher's mandatory `config`. Migrating would require making
  config mandatory (breaking admin.py:1511, yandex_newbuilding_sweep.py:353,
  and several tests that call without config -- out of scope for a call-site
  swap) and breaks test_scraper_kit_newbuilding_endpoint.py's "without config,
  endpoint=None" regression case (its SimpleNamespace mock lacks
  use_proxy_pool_browser, and the mock config path can never satisfy a
  mandatory-config helper). Left untouched; the class-bug #2322/#2330 this
  file already fixed (config now threaded, just not via the shared helper)
  remains fixed.

Also updates test_kit_serp_proxy_pool.py's 3 yandex-specific tests: they
monkeypatched the module-local `yandex_serp.BrowserFetcher` name, which the
migrated call path no longer references directly (it now goes through
scraper_kit.providers._base.build_browser_fetcher -> _base's own BrowserFetcher
import). Patch target moved to scraper_kit.providers._base.BrowserFetcher;
every assertion is unchanged -- this adapts the mock to the new (intentional)
call path, it does not weaken what the test verifies. Cian's tests in the same
file are untouched (cian/serp.py is not migrated yet, separate F4b issue).
lekss361 merged commit 9b92b595db into main 2026-07-04 06:43:18 +00:00
lekss361 deleted branch feat/tradein-scraper-kit-f4c-yandex-v2 2026-07-04 06:43:18 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: lekss361/gendesign#2384
No description provided.