[tradein] scraper_kit Group F4-Foundation: shared base/utils для providers/* #2358

Closed
opened 2026-07-04 00:18:25 +00:00 by lekss361 · 1 comment
Owner

Родительский: #2352 (F4). Первый шаг структурного рефактора — аддитивный, НЕ трогает существующие provider-файлы.

Контекст

providers/* = 13 201 строк (avito 5462, cian 3222, yandex 2854, domclick 1312). Retry/backoff паттерн повторяется ~30 раз по кодовой базе, BrowserFetcher(...) конструируется независимо в 11 местах — с разной степенью аккуратности (см. недавние баги #2322/#2330 — оба про непрокинутый config/endpoint в одном из этих construction sites).

Scope

  1. Прочитать все 4 provider submodule (avito/cian/yandex/domclick — НЕ ekb_geoportal, он мал и уже clean), найти реально повторяющиеся паттерны:
    • Retry/backoff loop (see ~30 occurrences)
    • BrowserFetcher construction boilerplate (endpoint/config threading — тот самый footgun-класс из #2322/#2330)
    • Session-management (curl_cffi AsyncSession setup)
  2. Спроектировать и реализовать shared base/utils модуль (например scraper_kit/providers/_base.py или common.py) — функции/mixins для найденных повторяющихся паттернов. НЕ трогать существующие provider-файлы в этом issue — это только Foundation, миграция providers на неё — отдельные F4a-d (создаются после этого issue).
  3. Юнит-тесты для новой shared-логики (изолированно, без интеграции с providers).
  4. Заодно поправить устаревший docstring scraper_adapters.py ("никто не использует" — на деле wired в _run_kit_scheduler) — тривиальный однострочный фикс, не связан с остальным scope, но мелкий и логично влезает сюда.

Почему это снижает риск footgun-класса структурно

Если retry/BrowserFetcher-construction вынесены в одну shared-функцию с mandatory config параметром (не optional) — новый provider или новый call site физически не сможет забыть его передать (в отличие от текущего паттерна, где каждый provider реализует это заново и optional-параметр иногда теряется). Явно отметить в реализации: shared-функция должна делать config mandatory, если технически возможно (см. #2352 доп. комментарий от F3-аудита).

DoD

  • Shared base/utils модуль создан, юнит-тесты проходят
  • Существующие provider-файлы НЕ изменены (diff только новые файлы + docstring fix)
  • Полный existing test suite всё ещё зелёный (ничего не должно сломаться — чисто аддитивно)
  • scraper_adapters.py docstring исправлен

Refs #2352, #2309

Родительский: #2352 (F4). Первый шаг структурного рефактора — аддитивный, НЕ трогает существующие provider-файлы. ## Контекст `providers/*` = 13 201 строк (avito 5462, cian 3222, yandex 2854, domclick 1312). Retry/backoff паттерн повторяется ~30 раз по кодовой базе, `BrowserFetcher(...)` конструируется независимо в 11 местах — с разной степенью аккуратности (см. недавние баги #2322/#2330 — оба про непрокинутый `config`/`endpoint` в одном из этих construction sites). ## Scope 1. Прочитать все 4 provider submodule (avito/cian/yandex/domclick — НЕ ekb_geoportal, он мал и уже clean), найти реально повторяющиеся паттерны: - Retry/backoff loop (see ~30 occurrences) - `BrowserFetcher` construction boilerplate (endpoint/config threading — тот самый footgun-класс из #2322/#2330) - Session-management (curl_cffi AsyncSession setup) 2. Спроектировать и реализовать shared base/utils модуль (например `scraper_kit/providers/_base.py` или `common.py`) — функции/mixins для найденных повторяющихся паттернов. **НЕ трогать существующие provider-файлы в этом issue** — это только Foundation, миграция providers на неё — отдельные F4a-d (создаются после этого issue). 3. Юнит-тесты для новой shared-логики (изолированно, без интеграции с providers). 4. Заодно поправить устаревший docstring `scraper_adapters.py` ("никто не использует" — на деле wired в `_run_kit_scheduler`) — тривиальный однострочный фикс, не связан с остальным scope, но мелкий и логично влезает сюда. ## Почему это снижает риск footgun-класса структурно Если retry/BrowserFetcher-construction вынесены в одну shared-функцию с **mandatory** `config` параметром (не optional) — новый provider или новый call site физически не сможет забыть его передать (в отличие от текущего паттерна, где каждый provider реализует это заново и optional-параметр иногда теряется). Явно отметить в реализации: shared-функция должна делать `config` mandatory, если технически возможно (см. #2352 доп. комментарий от F3-аудита). ## DoD - [ ] Shared base/utils модуль создан, юнит-тесты проходят - [ ] Существующие provider-файлы НЕ изменены (diff только новые файлы + docstring fix) - [ ] Полный existing test suite всё ещё зелёный (ничего не должно сломаться — чисто аддитивно) - [ ] `scraper_adapters.py` docstring исправлен Refs #2352, #2309
Author
Owner

Note для F4a/F4d (avito/domclick migration): avito/serp.py и domclick/serp.py сейчас конструируют BrowserFetcher только с source+endpoint (implicitly proxy_provider=None, use_pool=False через class defaults). Если эти call sites переключат на build_browser_fetcher(config, source)use_pool начнёт читать config.use_proxy_pool_browser вместо hardcoded False. Это реальное изменение поведения, ЕСЛИ этот флаг когда-либо True в их окружении — не баг в F4-Foundation (модуль пока не используется реальным кодом), но проверить явно при миграции этих двух провайдеров, не обнаруживать по факту регрессии.

(из code-review #2358, зафиксировано чтобы не потерялось)

Note для F4a/F4d (avito/domclick migration): `avito/serp.py` и `domclick/serp.py` сейчас конструируют `BrowserFetcher` только с `source`+`endpoint` (implicitly `proxy_provider=None, use_pool=False` через class defaults). Если эти call sites переключат на `build_browser_fetcher(config, source)` — `use_pool` начнёт читать `config.use_proxy_pool_browser` вместо hardcoded `False`. Это реальное изменение поведения, ЕСЛИ этот флаг когда-либо `True` в их окружении — не баг в F4-Foundation (модуль пока не используется реальным кодом), но проверить явно при миграции этих двух провайдеров, не обнаруживать по факту регрессии. (из code-review #2358, зафиксировано чтобы не потерялось)
Sign in to join this conversation.
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#2358
No description provided.