Repository navigation
fix: reject fields without profile, remove duplicate fields and count field filtering by set - #256
Conversation
…unt field filtering by set
aditeyabaral
left a comment
There was a problem hiding this comment.
Thanks for the update! This follows up on the review on #255. Most of it is addressed, and the logic is right: I checked that each new test fails when its fix is reverted, and coverage of app/ is still 100%. Two things block merging, plus some smaller items below.
Blocking
- Stray import in
tests/unit/test_request_model.py(inline comment). On a Python withoutidlelib, the whole module fails to import and none of the request-model tests run. - The docs don't describe the new behaviour yet. None of these are in the diff, so I can't comment on the lines:
app/models/request.py:75, thefieldsdescription. "Only used when profile istrue" is no longer accurate: it can only be given whenprofileistrue, otherwise the request is rejected. Also mention that repeated names are ignored. This text is the Swagger description, so it matters.README.md:180, thefieldsrow of the request table: same change.README.md:184, the list of requests rejected with a400: addfieldswithoutprofile: true.README.md:371, theprofile_field_filtering_totalrow: "a caller passing exactly the default list counts asfalse" should now say "in any order".app/docs/authenticate.py: add a 400 example for this case next tounknown_profile_field, with the exact message the API returns:Could not validate request data - body: Value error, Fields can only be requested when profile is true.. Also add "fields without profile set to true" to the 400description.
PR title and description
The PR is squash-merged, so its title becomes the commit message. Please update it to cover the main change, e.g. fix: reject fields without profile, remove duplicate fields and count field filtering by set. The description still says it "adds a debug log when fields are sent without enabling the profile option" and ticks "Debug/logging enhancement". Please describe the 400 instead, and untick that box.
Checked and fine
- Deduplication, the set comparison and the comment above it, and the metric tests (
.name,== 1.0,collector). - The new validator: a request with
fieldsandprofileomitted orfalsegets a 400 with the standard error body and never reaches PESU Academy."fields": nullwithoutprofileis still accepted. A bad field name still reports the field error, not this one. - The version bump to 5.5.0 against
dev's 5.4.0 (minor), anduv.lockmatches. - The commit email is fixed.
tests/ was excluded from ruff, so import order, unused imports, long lines and comparisons to True or None in tests were left to review to catch. Lint and format it like the rest of the repo, except for the annotation (ANN) and missing-docstring (D1) rules: a test's name says what it checks, and pytest fixture arguments need no annotations. Ruff now reports syntax errors in tests/, so the compileall hook that existed only for that is removed, along with its CONTRIBUTING entry. The fixes are the ones ruff asked for: unused imports, including a stray idlelib import that broke collecting test_request_model.py wherever idlelib is not installed; unsorted imports; lines over 120 characters; == comparisons to True, False and None; an unused variable; three docstrings without a summary line; and fixture annotations in test_sync_agents.py that needed Path imported only for them.
aditeyabaral
left a comment
There was a problem hiding this comment.
Re-review at fc1ac47.
Note: I pushed a commit to your branch (fc1ac47, "chore: lint and format tests/ with ruff"). It turns ruff on for tests/, so most of the style nits from the last review are now caught by pre-commit and CI. It also fixes the ones ruff found here, including the stray idlelib import. Please git pull before you push again, or your push will be rejected. If you run uv run pre-commit run --all-files before committing, ruff will flag these for you from now on.
I've resolved the threads that commit fully fixed and replied on the ones it only partly fixed.
New in this review
- Should fix: the new check should live in
validate_fields, so the error is reported againstfields. See the inline comment onapp/models/request.py:103. It replaces the earlier comments on lines 106 and 114–117.
Still open from the last review
- Blocking: the docs. These aren't in the diff, so they're listed here:
app/models/request.py:75, thefieldsdescription: it can only be given whenprofileistrue, otherwise the request is a 400. Repeated names are ignored.README.md:180, thefieldsrow of the request table: same change.README.md:184, the list of requests rejected with a400: addfieldswithoutprofile: true.README.md:371, theprofile_field_filtering_totalrow: "exactly the default list, in any order".app/docs/authenticate.py: a 400 example next tounknown_profile_field, plus "fields without profile set to true" in the 400description. With the suggestion below, the message isCould not validate request data - body.fields: Value error, Fields can only be requested when profile is true..
- The PR title and description. The title should cover the rejection, e.g.
fix: reject fields without profile, remove duplicate fields and count field filtering by set. The description still describes a DEBUG log and ticks "Debug/logging enhancement". - The open threads below: the test rename in
test_authenticate_flow.py, the always-true assert in the integration test, the docstrings of the two rejection tests, and the duplicate test.
Checked and fine: deduplication and the set comparison (each test fails when its fix is reverted); requests with fields but no profile: true never reach PESU Academy; the version bump to 5.5.0; uv.lock; all CI checks.
Co-authored-by: Aditeya Baral <aditeya.baral@gmail.com>
Co-authored-by: Aditeya Baral <aditeya.baral@gmail.com>
Co-authored-by: Aditeya Baral <aditeya.baral@gmail.com>
There was a problem hiding this comment.
Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.
An organization owner can choose the repository organization as the billing source for reviews requested by members with a paid Copilot license. Learn about Copilot code review billing.
There was a problem hiding this comment.
Re-review at f008e27.
What's been fixed since the previous reviews
- Validator check moved into
validate_fields— error is now atbody.fields, matching the expected message format. ✅ - All five docs items from the blocking list:
app/models/request.py:75,README.md:180,README.md:184,README.md:371,app/docs/authenticate.py400 example. ✅ - PR title updated to match the change. ✅
- Test renamed to
test_fields_without_profile_are_rejected. ✅ assert data["status"] is Truein the health-check integration test. ✅- The
idlelibstray import, line-length violations, and trailing-comma issues — all resolved byfc1ac47. ✅
New finding — docs: timestamp type in the fields_without_profile example
app/docs/authenticate.py, fields_without_profile example:
"timestamp": 1700000000,Every other 400 example in this file uses an ISO 8601 datetime string (e.g. "2024-07-28T22:30:10.103368+05:30"). The actual API emits a datetime, never a Unix integer. Please update to match:
"timestamp": "2024-07-28T22:30:10.103368+05:30",New finding — test: ordering assertion removed without replacement
In test_authenticate_flow.py, test_requested_fields_only_and_null_when_empty, the diff removes:
# On the wire, in the documented order
assert list(profile) == [field for field in full_profile if field in fields]The README states "Fields come back in the table's order, whatever order they are asked for in." This was the only automated check of that ordering guarantee. Nothing replaces it. Please restore the assertion or add an equivalent one so the documented contract stays tested.
Still open from @aditeyabaral review
-
Docstrings on
test_validate_profile_key_omittedandtest_validate_profile_is_set_as_false— the current docstrings describe the input ("Test that fields are rejected when profile is omitted/false"). The repo convention and the reviewer's suggestion is to state what is expected instead (e.g.,"""fields with profile omitted is a 400."""). The inline threads on these are still open. -
test_validate_profile_false_without_fields— the reviewer flagged this as duplicating an existing test (test_validate_fields_noneortest_validate_with_no_duplicates). The thread is still open. Iftest_validate_fields_nonealready coversfields=Nonewith the defaultprofile=False, one of them can be removed.
aditeyabaral
left a comment
There was a problem hiding this comment.
Re-review at 23bd3e4. Thanks, this is close!
Fixed since the last review:
- The check now lives in
validate_fields, so the error isbody.fields: ...and the metric recordsfield="fields". - The
model_validatorimport is gone. - The docs are updated: the
fieldsdescription, the README request table, the list of rejected requests, the metrics row, and a 400 example inapp/docs/authenticate.py. - The PR title, the test rename, the always-true assert, the test docstrings and the duplicate test.
I confirmed each of these on the threads that were resolved without a reply. I've reopened one thread whose fix is only partial (see below).
@achyu-dev's two findings are already fixed at 23bd3e4: the example's timestamp is an ISO string again, and the ordering assertion in test_requested_fields_only_and_null_when_empty is still there with its comment reworded. I've answered the questions about the ruff config on those threads.
I also checked:
- Sending
fieldsbeforeprofilein the JSON still gets the 400, because pydantic validates fields in declaration order, not input order. "profile": "yes"reports only theprofileerror.- Coverage of
app/is 100%. - All CI checks pass.
Still to do:
- Should fix: the new metrics test doesn't test the new rule (inline comment).
- Nits: wording in the docs and the README (inline suggestions, already checked against mdformat and ruff). The
fieldsdescription and README suggestions also answer @jois-code's question aboutfields: null. - PR description: the Description section should also say that
fieldswithoutprofile: trueis now rejected with a 400. That's the main user-visible change.
Co-authored-by: Aditeya Baral <aditeya.baral@gmail.com>
aditeyabaral
left a comment
There was a problem hiding this comment.
Thanks for applying the suggestions. The docs, README and fields description are all done now, and I've confirmed and resolved those threads.
Two things are left, both as one-click suggestions below:
- Pre-commit is failing because of trailing blank lines at the end of
tests/integration/test_app_integration.py. - The replacement metrics test is missing. The old test was removed, but the new one, which lived in
tests/unit/test_metrics_endpoints.py, wasn't added.
Please also mention the new 400 in the PR description. It currently describes only the duplicate removal and the metric fix, but rejecting fields without profile: true is a behaviour change callers will notice, and the squash-merge title only partly covers it.
Co-authored-by: Aditeya Baral <aditeya.baral@gmail.com>
Co-authored-by: Aditeya Baral <aditeya.baral@gmail.com>
|
Thanks, everything from the reviews is in, all threads are resolved, and CI is green on f7d0b92. One thing left before this can be approved: the PR description. It still describes only the duplicate removal and the metric fix. Please add a line saying that While you are there, a few boxes are now out of date:
|
aditeyabaral
left a comment
There was a problem hiding this comment.
Make PR description updates, else LGTM
📌 Description
This PR fixes how profile fields are handled by removing duplicate names, making sure reordered full lists don't falsely trigger the filtering metric.
🧱 Type of Change
pyproject.toml,uv.lock🧪 How Has This Been Tested?
tests/unit/)tests/functional/)tests/integration/)✅ Checklist
scripts/run_tests.py)pre-commit run --all-files).envvars updated (if applicable)scripts/benchmark/benchmark_requests.py)🛠️ Affected API Behaviour
app/app.py– Modified/authenticateroute logicapp/pesu.py– Updated PESU Academy login or profile handlingapp/exceptions/– Error types, their status codes or messagesapp/metrics/– Metrics collection, exposition or the/metricstokenapp/docs/– OpenAPI (Swagger) examples and descriptions🧩 Models
app/models/request.py– Input validation or request schema changesapp/models/response.py– Authentication response formattingapp/models/profile.py– Profile response schemaapp/models/upstream.py– Parsing of PESU Academy's login and profile responses🐳 DevOps & Config
Dockerfile– Changes to base image or build process.github/workflows/*.yml– CI/CD pipeline or deployment updatespyproject.toml/uv.lock– Dependency version changes.pre-commit-config.yaml– Linting or formatting hook changes.github/scripts/check_version_bump.py– The CI version check📊 Benchmarks & Analysis
scripts/benchmark/benchmark_requests.py– Performance or latency measurement changesscripts/benchmark/analyze_benchmark.py– Benchmark result analysis changesscripts/run_tests.py– Custom test runner logic or behavior updates📸 Screenshots / API Demos (if applicable)
🧠 Additional Notes (if applicable)
Fields sent without
profile: true(either omitted or set to false) are now rejected with a400 Bad Request