fix(dispatch): resolve native ingester class at call time (test monkeypatch)
The _NATIVE_INGESTERS dict captured PatreonIngester/SubscribeStarIngester at import, so test_download_service's monkeypatch.setattr(db_mod, "PatreonIngester", _FakeIngester) no longer affected dispatch → the fake's run() never ran → KeyError 'campaign_id' on empty run_kwargs (integration run 1215). Replace the dict with a _native_ingester_cls() call-time lookup that reads the module globals, so monkeypatching the class names works again. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -34,18 +34,22 @@ from .subscribestar_ingester import SubscribeStarIngester
|
|||||||
# deviantart) until they migrate too.
|
# deviantart) until they migrate too.
|
||||||
NATIVE_INGESTER_PLATFORMS = frozenset({"patreon", "subscribestar"})
|
NATIVE_INGESTER_PLATFORMS = frozenset({"patreon", "subscribestar"})
|
||||||
|
|
||||||
# Native ingester classes keyed by platform (uniform constructor signature, so
|
|
||||||
# _run_native_ingester / preview build whichever the source needs).
|
|
||||||
_NATIVE_INGESTERS = {
|
|
||||||
"patreon": PatreonIngester,
|
|
||||||
"subscribestar": SubscribeStarIngester,
|
|
||||||
}
|
|
||||||
|
|
||||||
# Mirrors patreon_resolver._CAMPAIGNS_URL — surfaced in resolution-failure
|
# Mirrors patreon_resolver._CAMPAIGNS_URL — surfaced in resolution-failure
|
||||||
# messages so the operator sees the exact lookup endpoint that was hit.
|
# messages so the operator sees the exact lookup endpoint that was hit.
|
||||||
_CAMPAIGNS_API = "https://www.patreon.com/api/campaigns"
|
_CAMPAIGNS_API = "https://www.patreon.com/api/campaigns"
|
||||||
|
|
||||||
|
|
||||||
|
def _native_ingester_cls(platform: str):
|
||||||
|
"""The native ingester class for `platform` (uniform constructor signature).
|
||||||
|
A call-time lookup (not a module-level dict captured at import) so tests can
|
||||||
|
monkeypatch db_mod.PatreonIngester / SubscribeStarIngester and have the
|
||||||
|
dispatch pick up the replacement."""
|
||||||
|
return {
|
||||||
|
"patreon": PatreonIngester,
|
||||||
|
"subscribestar": SubscribeStarIngester,
|
||||||
|
}[platform]
|
||||||
|
|
||||||
|
|
||||||
def uses_native_ingester(platform: str) -> bool:
|
def uses_native_ingester(platform: str) -> bool:
|
||||||
"""True when `platform` is served by the native ingester (not gallery-dl).
|
"""True when `platform` is served by the native ingester (not gallery-dl).
|
||||||
The single predicate the download path and verify both route on."""
|
The single predicate the download path and verify both route on."""
|
||||||
@@ -150,7 +154,7 @@ async def _run_native_ingester(
|
|||||||
if source_config.sleep_request is not None
|
if source_config.sleep_request is not None
|
||||||
else max(0.5, rate_limit / 4)
|
else max(0.5, rate_limit / 4)
|
||||||
)
|
)
|
||||||
ingester = _NATIVE_INGESTERS[platform](
|
ingester = _native_ingester_cls(platform)(
|
||||||
images_root=gdl.images_root,
|
images_root=gdl.images_root,
|
||||||
cookies_path=ctx["cookies_path"],
|
cookies_path=ctx["cookies_path"],
|
||||||
session_factory=sync_session_factory,
|
session_factory=sync_session_factory,
|
||||||
@@ -209,7 +213,7 @@ async def preview_source(
|
|||||||
"(cookies expired, or the creator moved/renamed?)."
|
"(cookies expired, or the creator moved/renamed?)."
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
ingester = _NATIVE_INGESTERS[platform](
|
ingester = _native_ingester_cls(platform)(
|
||||||
images_root=images_root,
|
images_root=images_root,
|
||||||
cookies_path=cookies_path,
|
cookies_path=cookies_path,
|
||||||
session_factory=sync_session_factory,
|
session_factory=sync_session_factory,
|
||||||
|
|||||||
Reference in New Issue
Block a user