Add Firecrawl web monitoring example#5065
Open
htahir1 wants to merge 11 commits into
Open
Conversation
Turns each Firecrawl monitor.page webhook into a ZenML pipeline run that versions the raw event, normalized diff, change analysis, and final report as named artifacts. Analysis uses an OpenAI model when a ZenML secret is provided and falls back to Firecrawl's own meaningful-change judgment otherwise; a configured stack alerter can post meaningful changes to Slack. Includes a FastAPI webhook receiver, a monitor provisioning script, and an artifact history utility. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
|
|
All alerts resolved. Learn more about Socket for GitHub. This PR previously contained dependency changes with security issues that have been resolved, removed, or ignored. |
Socket flagged the example branch because its manifest parser read the setuptools py-modules list as PyPI dependencies and matched "constants" against the obfuscated `constants` package on PyPI. The example never depended on that package, but installing generic top-level module names (constants, models, run) also shadows other projects in shared venvs. The project now installs dependencies only; all code runs from the example directory as the README already instructs. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Contributor
Documentation Link Check Results✅ Absolute links check passed |
Firecrawl's monitoring API supports reading check results directly
(GET /v2/monitor/{id}/checks), so the local flow does not need webhook
infrastructure: `run.py --monitor-id` pulls the latest completed check
and runs the pipeline once per page result. The custom FastAPI receiver
is removed along with the fastapi/uvicorn dependencies; event-driven
production setups should trigger a ZenML pipeline snapshot via the REST
API instead, which the README now documents. Monitor creation makes the
webhook optional for the same reason.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Versions written from another environment (e.g. an S3 store without the s3 integration installed locally) crashed history.py; they are now reported and skipped. The README notes that zenml init scopes the active stack to the directory and resets it to default, which silently sent fresh-clone runs to the local store, and that S3-backed stacks need the s3 integration installed before the first run. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The first check of a monitor reports pages with status 'new' and an explicit null diff, which failed FirecrawlPageData validation when pulling real checks via the API. Found by running the pipeline against a live monitor; the bundled sample payload never exercised this. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Examples in this repo do not ship test suites; the pipeline is validated by running it. Removing the tests also removes the need for the dev optional dependencies. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Server-triggered runs of static pipelines reject pipeline-level parameters; verified against a live snapshot trigger. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Fold the stack-set ordering into the quick-start block, remove the redundant raw-payload section (superseded by --monitor-id), and delete configs/prod.yaml, which nothing referenced. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Fix demo correctness and honesty issues raised in review of #5065: - Align configs/snapshot.yaml goal with the baked pricing payload so a default snapshot run no longer analyzes a price diff against an unrelated "AI stories" goal. - Select the newest monitor check by timestamp instead of assuming the checks API returns newest-first, falling back to the first entry when no recognized timestamp field is present. - Warn when a monitor.page event carries multiple pages, since only the first is normalized; a multi-page event would otherwise drop pages silently. - Document ongoing Firecrawl/OpenAI cost and add a curl snippet to delete a monitor after a demo, and note the pip fallback for the install step. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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.
What this does
Adds
examples/firecrawl_web_monitor, an example that turns each Firecrawlmonitor.pageevent into a ZenML pipeline run. Firecrawl monitors and scrapes a page; ZenML versions the raw event, normalized diff, change analysis, and final report as independently named artifacts (firecrawl_monitor_event,web_page_change,web_change_analysis,web_monitoring_report), so every check is comparable in the dashboard.The pipeline:
run.py --monitor-idfetches the latest completed check from Firecrawl's API and runs the pipeline once per page result. No webhook infrastructure needed locally; the README documents triggering a pipeline snapshot via the ZenML REST API as the event-driven production path.--llm-secret); otherwise falls back to Firecrawl's own meaningful-change judgment, and failing that a deterministic diff summary — each clearly labeled via theanalyzerfield. No credentials are needed for the first run (a realistic sample payload is bundled).--notify-slack).create_firecrawl_monitor.py, webhook optional) and an artifact history utility (history.py).Why
Shows an event-driven, non-ML use of ZenML's artifact versioning and lineage: monitor-triggered runs, Pydantic contracts as artifacts, secrets-based LLM configuration, and portable Docker settings sourced from the example's
pyproject.toml.Implementation notes
zenml initis run in the example directory and the README instructs running all commands from there, so the source root and the relativepyproject_pathinDockerSettingsresolve correctly for remote image builds.py-modules = []) — it exists purely to declare dependencies. This avoids shadowing generic module names and a Socket supply-chain false positive that matched the localconstants.pyagainst the obfuscatedconstantspackage on PyPI.--monitor-idpulls, snapshot creation via an AWS CodeBuild image builder, snapshot runs on a Kubernetes stack triggered both viaClient().trigger_pipeline(including live payload + LLM secret as step-level parameter overrides) and via a raw external POST to the snapshot runs endpoint.Reviewer attention
fetch_firecrawl_check.py) maps Firecrawl's check-details response onto the same envelope asmonitor.pagewebhook deliveries; per-page objects are identical per Firecrawl's docs, withmonitorId/checkIdmerged in from the parent check.🤖 Generated with Claude Code