scrapy-jev
A Scrapy item pipeline that uses Jev (TypeSafe AI's System One model) to spot-check scraped fields and stop a crawl when the data stops looking real.
Scraping silently degrades: a selector drifts to a new class name and fields start coming back empty or wrong long before anyone notices. This pipeline samples a bounded batch of items, asks Jev how plausible each of a few core fields looks, and halts the spider when the pass rate drops below a threshold.
Install
uv add scrapy-jev
Configure
Recommended: use the add-on. One line auto-registers the pipeline, so you
never touch ITEM_PIPELINES:
ADDONS = {
"scrapy_jev.Addon": 350,
}
OPENROUTER_API_KEY = "..." # or JEV_API_KEY; either may live in the env instead
JEV_FIELDS = ["name", "price", "sku", "category"]
If you prefer to wire the pipeline yourself (or need a different priority), skip the add-on and list it directly:
ITEM_PIPELINES = {
"scrapy_jev.QualityGatePipeline": 400,
}
The first JEV_SAMPLE_SIZE items that carry any of JEV_FIELDS are judged, and
if fewer than JEV_PASS_RATE_THRESHOLD pass, the spider stops.
Installing the package with no JEV_FIELDS and no API key has no effect — the
add-on (and the pipeline) disable themselves until you configure them.
Settings
| Setting | Default | Meaning |
|---|---|---|
JEV_FIELDS |
[] |
Fields to judge on each item. |
JEV_SAMPLE_SIZE |
20 |
Items to judge before deciding. |
JEV_PASS_RATE_THRESHOLD |
0.7 |
Minimum share (0–1) of items that must pass. |
JEV_FIELD_THRESHOLD |
0.5 |
Per-field plausibility below which a field fails. |
JEV_MODEL |
~typesafe/jev-latest |
Model id passed to the decisions endpoint. |
JEV_BASE_URL |
https://openrouter.ai/api/alpha/decisions |
Endpoint. |
JEV_PIPELINE_PRIORITY |
400 |
ITEM_PIPELINES priority used by the add-on. |
JEV_API_KEY / OPENROUTER_API_KEY |
— | API key (setting or env var). |
JEV_STOP_REASON |
"Extraction quality fell below threshold (Jev plausibility check)" |
Closing reason. |
How it works
- An item is judged only if it declares at least one of
JEV_FIELDS; other items (e.g. list pages) pass through untouched. - Per item, Jev returns a 0–1 score per field. An item passes only when
every field scores at or above
JEV_FIELD_THRESHOLD. A field that comes back empty (None) is a failure, not a skip — that's the classic "selector drifted and returns nothing" break. - After
JEV_SAMPLE_SIZEitems, if the passed share is belowJEV_PASS_RATE_THRESHOLD, the spider is stopped.
Releasing
Releases are published to PyPI via GitHub Actions using trusted publishing (no token stored in the repo). To cut a release:
- Bump the version in
pyproject.tomland add an entry toCHANGELOG.md.uv build # sanity check: builds clean, twine check passes
- Commit, then tag and push the tag:
git tag v0.1.0 git push origin v0.1.0
- The
publish.ymlworkflow builds and uploads to PyPI automatically.
Release files for scrapy-jev 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| scrapy_jev-0.1.0.tar.gz | 8.4 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| scrapy_jev-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 17.8 kB
Release files / scrapy_jev-0.1.0.tar.gz
| Download URL | scrapy_jev-0.1.0.tar.gz |
|---|---|
| Size | 8.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
8bc725e414a4537f4966de21b5e88ae84f99146c9f1aecfb71abb7f9676d826a
|
|
BLAKE2b-256 checksum How to use checksums |
388a69e06041722904822cf8b89fb27a6e4c90d2ab7d923a23395a31ec22adc2
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 21, 2026.
Transparency logRelease files / scrapy_jev-0.1.0-py3-none-any.whl
| Download URL | scrapy_jev-0.1.0-py3-none-any.whl |
|---|---|
| Size | 9.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
fa79f49d983ccd3b8e76a6c53eb52bd714df8c6f2235021f76a94c750565fa6e
|
|
BLAKE2b-256 checksum How to use checksums |
5c73904f5d7cced98c5cec484c67f3213d4b8d03b251763c619071033bd6600f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 21, 2026.
Transparency log