feat: replace check_expected_keys with typed pydantic models (#1034) - #1071
feat: replace check_expected_keys with typed pydantic models (#1034)#1071reachsridhard wants to merge 10 commits into
Conversation
📝 WalkthroughWalkthroughThis change adds shared Pydantic models for REST, MQTT, and gRPC specifications, replaces plugin-specific key checks, adds type validation coverage, and moves Pydantic to the runtime dependency set. ChangesPydantic validation
Estimated code review effort: 3 (Moderate) | ~20 minutes 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 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 |
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 `@tavern/_core/pydantic_models.py`:
- Around line 19-52: Sanitize type-validation errors in
_BaseKeyValidator.validate_keys so UnexpectedKeysError never exposes raw input
values. Enable Pydantic’s input-repr hiding option in model_config and replace
the direct str(e) fallback with a safe validation-error summary that retains
field and type information without including offending values; preserve the
existing unexpected-key handling.
In `@tests/unit/test_pydantic_models.py`:
- Around line 300-309: Reformat the data dictionary literals in
test_grpc_request_body_can_be_dict and test_grpc_request_body_can_be_string
using ruff-format’s multi-line layout so the tests pass formatting checks; do
not change their behavior or assertions.
🪄 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: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: bf83fe31-983a-4a53-9831-50bfe3530dd6
📒 Files selected for processing (9)
pyproject.tomltavern/_core/pydantic_models.pytavern/_plugins/grpc/client.pytavern/_plugins/grpc/request.pytavern/_plugins/grpc/response.pytavern/_plugins/mqtt/client.pytavern/_plugins/mqtt/request.pytavern/_plugins/rest/request.pytests/unit/test_pydantic_models.py
TypeConvertToken objects (from !force_format_include, !int, etc.) and dict values (from $ext function calls) exist at validation time before resolution. Add these to Union types so pydantic accepts them while still rejecting clearly wrong types (e.g. int for headers, list for method).
Integration tests use cookies as a list (e.g. cookie name lists, cookie override dicts in list form, empty list to send no cookies).
|
@michaelboulton, as per your suggestion in PR 1065, I have updated the code to include type checking. |
I think that they can still be reduced a bit more, for example: |
Boolean fields (enable, clean_session, stream, follow_redirects, retain, secure, attempt_reflection) should never receive dicts. Keep TypeConvertToken for !bool YAML tag support.
Done in the latest commit. Removed dict from all boolean fields. Kept TypeConvertToken for ! bool YAML tag support (used in integration tests like verify: !bool "{verify_false}"). Thank you!! |
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Sorry, to be clear, I meant for all the fields, not just boolean ones. Another thing while I'm looking at it again, the type checking on the conversion tokens should be more strict (eg ints can only be I think this is quite a lot of work, if you don't mind I could make those changes and push it to your branch? |
Summary
Replace the 9-year-old
check_expected_keyspattern with pydantic models that useextra='forbid'for key validation and proper type annotations for value validation.This replaces #1065 by addressing the review feedback: all fields now have specific types instead of
Optional[Any], so pydantic actually validates both keys and values — otherwise using dataclasses/dacite would be just as effective.Changes
tavern/_core/pydantic_models.py— typedBaseModelsubclasses for REST, MQTT, and gRPC request/response/client specsvalidate_keys()instead ofcheck_expected_keys()tests/unit/test_pydantic_models.py— tests for key validation + type enforcementpyproject.toml— pydantic as runtime dependencyType annotations
RestRequestSpecmethod: str,headers: dict,stream: bool,json: JSONType,timeout: Union[float, list]MQTTRequestSpectopic: str,qos: int,retain: bool,payload: Union[str, bytes, int, float]MQTTConnectArgshost: str,port: int,keepalive: intGRPCResponseSpecstatus: Union[str, int, list[str], list[int]],body: dictGRPCClientTopLevelattempt_reflection: bool,connect: dict,metadata: dictCloses
Closes #1034
Summary by CodeRabbit
New Features
Tests