jevfilter
Judge content against plain-English definitions with TypeSafe's Jev. Describe what you care about in a few words; get back typed answers with calibrated probabilities: which topics match, which category, which company, how urgent.
jevfilter is stateless: no storage, no cache and no network except Jev. You get plain results back and store them however you like.
Pre-alpha. The API may change before 1.0.
Install
pip install "jevfilter[yaml]"
export TYPESAFE_API_KEY=...
Python 3.10+. You can also set the key in code with
jf.configure(api_key=..., model="jev-1.13.0"). jevfilter never reads
.env files, so load one yourself if you use it.
Quick start
import jevfilter as jf
jf.choose("I was charged twice", ["billing", "bug", "feature request"])
# Choice(value='billing', confidence=0.96, ...)
jf.check("Can you send the form by Friday?", {"needs_reply": "The sender wants a reply"})
# {'needs_reply': 0.98}
jf.rate("The site is down for everyone", "severity", ["cosmetic", "degraded", "blocking"])
# Score(value=2.0, level='blocking', ...)
Topics
A topic only needs a name and a description. Categories, fields, scores and flags are optional.
# topics/jobs.yaml
name: Jobs
description: Applications I submitted, and recruiters contacting me about a role.
exclude: Job alerts, digests, newsletters.
categories:
applied: Confirms I submitted an application.
interview: Invites me to an interview.
rejection: Tells me I'm not moving forward.
fields:
company: {about: The hiring company, required: true}
flags:
needs_reply: The sender is asking me to reply.
f = jf.Filter(jf.Topic.load("topics/"))
email = {"from": "...", "subject": "...", "body": "..."}
r = f.judge(jf.Content(email, candidates={"Jobs": {"company": ["Acme", "Initech"]}}))
for t in r.matches:
print(t.topic, t.p, t.category.value, t.fields["company"].value, t.flags)
for t in r.review: # uncertain: let a person decide
print(t.topic, t.reasons)
r.cost_usd # every result reports its cost
db.save(r.to_dict()) # plain JSON; restore with jf.Result.from_dict
Each topic comes back as match, review or no. All questions for one
piece of content go to Jev in a single request. Field values are picked
from the candidates you pass in, never generated. f.explain(email) shows
the exact request and its estimated cost without sending it.
See docs/topic-format.md for every topic option
(scores, composites, when, thresholds, meta) and docs/api.md
for the rest of the API.
Testing without an API key
from jevfilter.judges import FakeJudge
fake = FakeJudge({"Jobs/membership": 0.95, "Jobs/categories": "applied"})
r = jf.Filter(topics, judge=fake).judge("...")
Development
uv sync
uv run pytest # unit tests, no network
JEVFILTER_LIVE=1 uv run pytest tests/live -s # real Jev, prints spend
uv run ruff check . && uv run ruff format .
License
MIT
Release files for jevfilter 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 | |
|---|---|---|---|
| jevfilter-0.1.0.tar.gz | 77.7 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| jevfilter-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 107.2 kB
Release files / jevfilter-0.1.0.tar.gz
| Download URL | jevfilter-0.1.0.tar.gz |
|---|---|
| Size | 77.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
bac320a0a3ec2dda2434f0e630deadbd42cab3cba8e9727f4d1c01cdecb43063
|
|
BLAKE2b-256 checksum How to use checksums |
a494454a36ee0f25080d60c7e27140fa124e10b10ea9bcb8433c7afc4673b3ce
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.12.19 {"installer":{"name":"uv","version":"0.12.19","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / jevfilter-0.1.0-py3-none-any.whl
| Download URL | jevfilter-0.1.0-py3-none-any.whl |
|---|---|
| Size | 29.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
5e08b9c0c0c3e74cd79b39b320cbb563ebe369a758bde9e93deb07bcee989e0e
|
|
BLAKE2b-256 checksum How to use checksums |
921e77f0a5987e8b3474eae058fb3cf7e273eb84d7a5945df143008c2a23da44
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.12.19 {"installer":{"name":"uv","version":"0.12.19","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|