feat(scraper): SCRAPE_CACHE_MODE and --no-fetch-cache for crawl4ai (#50) - #54
Closed
nelsonmfinda wants to merge 1 commit into
Closed
feat(scraper): SCRAPE_CACHE_MODE and --no-fetch-cache for crawl4ai (#50)#54nelsonmfinda wants to merge 1 commit into
nelsonmfinda wants to merge 1 commit into
Conversation
This was referenced May 12, 2026
Owner
|
Verified locally: 182 tests pass, env precedence is correct (existing One blocking issue and one merge mechanic worth knowing about, both in #55: |
Owner
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fix #50: adds
--no-fetch-cacheflag andSCRAPE_CACHE_MODEenv var to bypass Crawl4AI's local cache (~/.crawl4ai/) without wiping the directory by hand. Maps to Crawl4AI'sCacheModeenum and is plumbed into both the discover and fetch paths viaCrawlerRunConfig. CLI flag is shorthand forSCRAPE_CACHE_MODE=bypassand usessetdefaultsemantics so an explicit pre-existing env value wins (mirrors--provider's precedence).main()restores the prior env value on exit so the flag does not leak into a test session or an embedding application.Honoured by the crawl4ai provider; firecrawl ignores it (its API defaults to fresh-fetch). Knob is global today; per-stage variants (
SCRAPE_DISCOVER_CACHE_MODE/SCRAPE_FETCH_CACHE_MODE) deferred to a follow-up if real configurations need them.Related issue
Closes #50.
Type of change
How it was tested
pytest -q
752 passed, 1 skipped
15 new tests:
_resolve_cache_modeenv mapping forbypass,disabled,read_only,write_only, case-insensitive, default/unset, unknown value (warns), missing library (silent), future enum-rename viagetattrAttributeError fallback, warn-once per raw value across repeated callsCrawl4AIDiscoveryProvider.discover_urlspassescache_modeinto the constructedCrawlerRunConfigwhen the env is set, omits it when unsetCrawl4AIFetchProvider.fetch_onepassesconfig=run_configwhen override is set, preserves the originalcrawler.arun(url=url)call shape when unset--no-fetch-cachesetsSCRAPE_CACHE_MODE=bypass, the flag respects a pre-existing env (disabledsurvives), andmain()restores the prior env (popped or restored to original) on every exit path includingsys.exitChecklist
pytest)docs/and/orREADME.mdif behavior changed (new flag entry indocs/CLI_GUIDE.md;.env.exampleandinstaller/templates/env.examplecarry thevalue list; CHANGELOG entry added)
Additional notes
A few choices worth flagging:
registry.py:_FETCH_FACTORIESstoreslambda: Crawl4AIFetchProvider()). Adding constructor args would change the registry contract and break any third-party providers. ReadingSCRAPE_CACHE_MODEat fetch time keeps the factory contract intact and matches the existingSCRAPE_PROVIDER/SCRAPE_DISCOVER_PROVIDER/SCRAPE_FETCH_PROVIDERpattern from ADR-0009. Trade-off: one more env var to maintain, but it composes naturally with how the rest of the scraper is configured.setdefaultprecedence. Mirrors--provider's behaviour at line 124 of the same file. A user who explicitly setSCRAPE_CACHE_MODE=read_onlyin their.envand then passes--no-fetch-cachethinking they're stacking gets to keepread_onlyrather than being silently downgraded. The "flag wins" alternative was considered and rejected for asymmetry with--provider.try/finallyenv restore. Without it,os.environ["SCRAPE_CACHE_MODE"] = ...would persist for the lifetime of the process. Fine for a one-shot CLI invocation; broken for teststhat call
main()directly and for any future embedding application that reuses the same Python process. The restore is unconditional and runs even onsys.exit(2)/sys.exit(3).Nonepaths in_resolve_cache_mode. Library missing → silent (the caller's_ensure_availablesurfaces a clearerProviderUnavailableError). Value missing orunrecognised → warn once per raw value via a module-level
_WARNED_CACHE_VALUES: set[str]. Without the dedupe, a typo would emit hundreds of duplicate stderr lines on a deep crawl.getattr(CacheMode, mapped)is wrapped intry/except AttributeError. A future Crawl4AI release that renames an enum value falls through to the warn-once branch instead of crashingthe run.
app.scrape(url, ...)defaults to fresh-fetch; the API has amaxAgeparameter for opt-in caching that king-scrape doesn't use today. IfFirecrawl ever gains a default cache, the same env can grow a Firecrawl-specific mapping.
This lays the primitive
king-scrape update <name>(#46) needs to makeforce_refresh=Trueactually fetch from the network instead of being shadowed by Crawl4AI's local cache.