feat(web): POST forms-for-synsets batch endpoint [SIGN-690] - #5
Conversation
…GN-690] Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
📝 WalkthroughWalkthroughThe forms endpoint now supports POST requests that return written forms for supplied synset IDs. The implementation validates request data, queries distinct forms, supports entity filtering, and reports totals. Tests cover normal, empty, invalid, and malformed-input cases. ChangesForms filtered by synsets
Estimated code review effort: 3 (Moderate) | ~20 minutes Sequence Diagram(s)sequenceDiagram
participant Client
participant forms_for_synsets
participant _get_forms_for_synsets
participant SQLDatabase
Client->>forms_for_synsets: POST synset IDs and with_entities
forms_for_synsets->>_get_forms_for_synsets: Validate and query forms
_get_forms_for_synsets->>SQLDatabase: Join forms, senses, and synsets
SQLDatabase-->>_get_forms_for_synsets: Distinct written forms
_get_forms_for_synsets-->>forms_for_synsets: Form list
forms_for_synsets-->>Client: JSON data and meta.total
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
…ue map [SIGN-690] Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
5b7c82e to
543d750
Compare
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@tests/web_test.py`:
- Line 161: Add the pytest.mark.usefixtures('mini_db_web') decorator to
test_forms_for_synsets, matching the surrounding tests and ensuring it runs with
the mini_db_web fixture.
In `@wn/web.py`:
- Around line 449-450: Validate the request payload around `await
request.json()` before accessing `body.get`: catch malformed JSON errors and
return a 400 Bad Request, then verify the parsed `body` is a dictionary and
return 400 for other JSON types. Preserve the existing `synset_ids` extraction
for valid object payloads.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 5a3af29e-6989-4d17-927a-13fff3a8e469
📒 Files selected for processing (2)
tests/web_test.pywn/web.py
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Part of SIGN-690: the dictionary website should only surface (sitemap, A-Z browse) concepts that have signs. The dictionary API knows which synsets have signs; this endpoint answers "which forms express any of these synsets" — with the join running in wn's SQLite instead of shipping the whole form→synsets map to the caller.
What
POST /lexicons/{lexicon}/formswith{"synsets": ["omw-en-02084071-n", ...]}→ the unique forms having at least one sense in those synsets:{ "data": ["dog", ...], "meta": { "total": 1 } }sensestosynsets;with_entitiescomposes (body field).json_eachparameter, so it clears SQLite's variable-count limit at any batch size.GET /lexicons/{lexicon}/formsis unchanged; POST follows the existingPOST /lexicons/{lexicon}/definitionsbatch precedent.Tests
Plain GET forms (previously untested), the POST batch (including a secondary written form inheriting its entry's synsets), empty/unknown ids, non-string rejection, bad lexicon specifier. Local CI: ruff, mypy, build, full pytest suite (155) all pass.
🤖 Generated with Claude Code
Note
Low Risk
Additive read-only API and SQL; no auth or data mutation. Risk is mainly query correctness and input validation, which the new tests exercise.
Overview
Adds
POST /lexicons/{lexicon}/formsso callers can batch-resolve distinct written forms that express any of a given synset id list—intended for dictionary sitemap/A-Z surfaces that only show concepts with signs, without shipping a full form→synset map.The handler mirrors the existing
POST …/definitionspattern: JSON body{"synsets": [...], "with_entities": ...}, response{"data": [...], "meta": {"total": N}}, with 400 on invalid JSON or non-string synset ids.GET …/formsis unchanged.Implementation adds
_get_forms_for_synsets, extending the GET forms SQL with joins through senses and synsets, filtering ids viajson_each(?)so large batches stay within SQLite’s bound-parameter limits. Malformed lexicon specifiers yield an empty list (same as GET forms).Tests cover GET forms listing, POST batch results (including secondary written forms), empty/unknown ids, validation errors, and bad lexicon specifiers.
Reviewed by Cursor Bugbot for commit 0c73517. Bugbot is set up for automated code reviews on this repo. Configure here.
Summary by CodeRabbit
POSTcapability for/lexicons/{lexicon}/formsto return distinct written forms filtered by a providedsynsetslist.with_entitiesto control how returned forms are normalized.meta.total, including0with an empty result when the lexicon specifier is malformed.GETlisting andPOSTsynset-driven results, including empty/unknown IDs and validation for non-string IDs.