Skip to content

feat(scraper): add pluggable provider with crawl4ai backend - #45

Merged
deandevz merged 11 commits into
mainfrom
feat/pluggable-scraper-provider
May 6, 2026
Merged

feat(scraper): add pluggable provider with crawl4ai backend#45
deandevz merged 11 commits into
mainfrom
feat/pluggable-scraper-provider

Conversation

@deandevz

@deandevz deandevz commented May 6, 2026

Copy link
Copy Markdown
Owner

Summary

Adds a pluggable scraper provider abstraction to king-scrape, with Crawl4AI as the first local opt-in backend. Firecrawl remains the zero-config default.

Why?

king-scrape was Firecrawl-only, contradicting the local-first positioning (ADR-0001). Users without Firecrawl credits, with private docs, or who wanted transparent HTML to Markdown conversion had no path. Mirrors the LLM provider pattern from ADR-0003.

Decisions: ADR-0009 (provider abstraction), ADR-0010 (thin provider, pipeline-owned IO), ADR-0011 (Crawl4AI as first local backend).

What changed

  • src/scraper_providers/ (new, 5 files): registry, DiscoveryProvider / FetchProvider Protocols, PageContent dataclass, ProviderUnavailableError, plus Firecrawl and Crawl4AI implementations with soft import.
  • Pipeline (src/king_context/scraper/{cli,config,discover,fetch}.py): --provider CLI flag, stage-aware env resolution (SCRAPE_PROVIDER, SCRAPE_DISCOVER_PROVIDER, SCRAPE_FETCH_PROVIDER), provider injection. Checkpoint, slug paths, and manifest semantics preserved.
  • pyproject.toml: firecrawl-py moved to [firecrawl] extra. New [crawl4ai] and [all] extras. entry_points group king_context.scraper_providers for future plugin discovery.
  • installer/lib/python.js: install/upgrade now use king-context[all] @ git+... so init keeps pulling firecrawl-py after the extras move.
  • CI: new .github/workflows/test.yml with test (pytest) and gated smoke-crawl4ai job (crawl4ai-setup + scripts/smoke-crawl4ai.py). Blocking by design (ADR-0011) to detect API churn across crawl4ai>=0.8.5,<0.9 minor versions.
  • Docs: README "Scraper providers" section, CLI_GUIDE flag entry + troubleshooting, .env.example + installer template synced, CHANGELOG [Unreleased] entry.
  • Tests: 280+ new tests in tests/test_scraper_providers/ (registry, soft import, stage resolution, entry points, both provider clients with mocked SDKs). Existing scraper tests adapted for provider injection.

Validation

  • pytest -q: 683 passed
  • Crawl4AI end to end on python-httpx.org: 114 sections exported
  • Firecrawl end to end on python-httpx.org: 112 sections exported
  • Default path (no env, no flag) resolves firecrawl and reaches the API (zero breaking change)
  • kctx adr validate: passed

deandevz added 8 commits May 6, 2026 16:47
Wire the registry from Tasks 1-3 into the existing pipeline. discover.py
and fetch.py now take DiscoveryProvider/FetchProvider as a parameter and
no longer import the Firecrawl SDK directly. cli.py adds a --provider
flag, resolves both stages via resolve_provider_name() before any I/O,
and surfaces clean exits: 2 for unknown provider names, 3 for
ProviderUnavailableError with the install hint. config.py reads the new
SCRAPE_PROVIDER / SCRAPE_DISCOVER_PROVIDER / SCRAPE_FETCH_PROVIDER envs.

Existing tests drop the FirecrawlApp module-level patches (the symbol
no longer exists in those modules) and inject fake providers instead.
Adds tests/test_scraper/test_pipeline_injection.py with 5 cases:
default firecrawl, flag sets env, stage env overrides flag, unknown
provider exits 2, ProviderUnavailableError exits 3.

Zero breaking change: with no env and no flag, the pipeline still
resolves 'firecrawl' for both stages, identical to the prior behavior.
Task 1 of the pluggable scraper provider work moved firecrawl-py from
core dependencies to the [firecrawl] extra. Without updating the npm
installer, every npx @king-context/cli init and update would silently
install a Firecrawl-less venv and break the default scraper.

Switch both install and upgrade calls to PEP 508 direct reference form
"king-context[all] @ git+https://...king-context.git" so init keeps
pulling firecrawl-py and crawl4ai together as before.
New .github/workflows/test.yml runs pytest on the firecrawl install
path and adds a gated smoke-crawl4ai job that installs the crawl4ai
extra, runs crawl4ai-setup, and executes scripts/smoke-crawl4ai.py.

The smoke job is intentionally blocking (ADR-0011): detecting API
churn between crawl4ai>=0.8.5,<0.9 minor versions before release is
the entire reason it exists.
README gains a Scraper providers section with the env-var table and
links to the CLI guide. docs/CLI_GUIDE.md adds the --provider flag
entry plus a subsection covering resolution rules, four scenario
examples (default, Crawl4AI, mixing, resume), and a troubleshooting
block for the four canonical errors.

.env.example and installer/templates/env.example add commented
SCRAPE_PROVIDER, SCRAPE_DISCOVER_PROVIDER, and SCRAPE_FETCH_PROVIDER
entries, with em-dashes in pre-existing comments swept out.

CHANGELOG records the abstraction, Crawl4AI extra, CI workflow,
firecrawl-py move to extras, and the installer PEP 508 update under
Unreleased.
deandevz added 3 commits May 6, 2026 18:19
The previous Scraper providers section showed only the standalone pip
install path, which was misleading for the majority flow where the npm
installer already bundles crawl4ai via the [all] extra. Adds:

- A brief paragraph on why Crawl4AI was added (no external credits,
  no third-party HTML pass-through, transparent conversion, private
  docs friendly)
- A beta notice with a link to file issues
- Two distinct enable paths: one for npx-init users (just run
  crawl4ai-setup from the project venv) and one for standalone pip
  installs
- Same env-var table and mixing example as before
king-context is not on PyPI yet (the standalone distribution is on the
roadmap), so 'pip install king-context[...]' was misleading users into
a command that does not work today.

Replaced with the two paths that actually work:

- npx-installed projects: the [all] extra is bundled by
  'npx @king-context/cli init', so users only need 'crawl4ai-setup'.
- Cloned-repo developers: 'pip install -e ".[crawl4ai]" && crawl4ai-setup'
  from the repo root.

Updated:

- README.md and docs/CLI_GUIDE.md (Scraper providers section,
  troubleshooting block)
- .env.example and installer/templates/env.example (comments)
- CHANGELOG.md [Unreleased] entries
- src/scraper_providers/{firecrawl,crawl4ai}_provider.py: _INSTALL_HINT
  strings now point at the npx and dev-clone paths instead of the fake
  PyPI command. _SETUP_HINT for crawl4ai-setup is unchanged.
@deandevz
deandevz merged commit 951f17f into main May 6, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant