Skip to content

EPDD-13457 feat(filter): typed filter builder generated from the API filter grammar - #78

Open
joeyadelman wants to merge 1 commit into
scalar-nextfrom
devin/1788889892-filter-builder
Open

EPDD-13457 feat(filter): typed filter builder generated from the API filter grammar#78
joeyadelman wants to merge 1 commit into
scalar-nextfrom
devin/1788889892-filter-builder

Conversation

@joeyadelman

Copy link
Copy Markdown

Summary

Python counterpart of profound-typescript-sdk#97 (EPDD-13457). The API publishes its report-filter grammar as x-profound-filter-grammar on the OpenAPI spec (CQS #1494); this PR generates a Python field/operator table from that extension and adds a small builder on top so callers don't hand-write filter JSON.

Source of truth is the spec, not this repo:

  • scripts/generate_filter_table.py [path-or-url] reads the spec (default: the Scalar registry @profound/apis/external-api/latest) and writes src/profound/lib/filter_table.py (FieldSpec, FIELD_TABLE, Fields, MAX_DEPTH). It exits non-zero if the extension is missing, so the table is never silently overwritten with an empty grammar.
  • .github/workflows/sync-filter-table.yml regenerates on every Scalar regeneration (push to scalar-next touching scalar-sdk.manifest.json), nightly, and on dispatch, and commits the result to scalar-next. It will fail until CQS #1494 is live in the published spec — that is intended.
  • .github/workflows/filter-builder-ci.yml runs the tests and regenerates from the committed fixture tests/fixtures/filter-grammar.openapi.json, failing on any diff so the generated file can't be hand-edited.

Builder (profound.lib.filter) returns plain dicts matching the API tree:

from profound.lib import filter as f
from profound.lib.filter_table import Fields

f.and_(
    f.or_(f.equals(Fields.model, "ChatGPT"), f.equals(Fields.model, "Perplexity")),
    f.not_(f.equals(Fields.region, "United States")),
)

Runtime guards mirror the TS builder and the server validators: unsupported field/op, depth > MAX_DEPTH, prompt/entity layer mixing under or/not, empty in/not_in, matches patterns shorter than 3 chars.

Targets scalar-next per VERSIONING.md (custom code lands there; main only advances via release PRs).

Link to Devin session: https://profound.devinenterprise.com/sessions/7601ee8459424184a5c2525a48e94f99
Open in Devin Desktop: https://profound.devinenterprise.com/desktop/session/7601ee8459424184a5c2525a48e94f99?variant=devin
Requested by: @joeyadelman

@devin-ai-integration

Copy link
Copy Markdown

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment, CI, and merge conflict monitoring

@devin-ai-integration

Copy link
Copy Markdown

@codex please do an in-depth review of this PR.

@chatgpt-codex-connector

Copy link
Copy Markdown

To use Codex here, create a Codex account and connect to github.

@devin-ai-integration devin-ai-integration Bot added the devin Opened by Devin label Sep 8, 2026
@devin-ai-integration devin-ai-integration Bot changed the title feat(filter): typed filter builder generated from the API filter grammar EPDD-13457 feat(filter): typed filter builder generated from the API filter grammar Sep 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

devin Opened by Devin

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant