refactor(console): dep-inject model provider payloads with @model_validate - #41539
Merged
asukaminato0721 merged 4 commits intoSep 1, 2026
Merged
Conversation
…idate Moves the eight inline parses in console/workspace/model_providers.py onto the @model_validate decorator. Six read the JSON body; the two get handlers already read request.args.to_dict(flat=True), which is what the decorator's GET branch does, so they convert the same way AccountAvatarApi.get and EducationAutoCompleteApi.get did. request is no longer used in the module, so the flask import drops it. The existing tests unwrap the view and pass the model themselves, which leaves the decorators unexercised, so this also adds one bound-method test asserting the 422 the decorator raises for an invalid query. Removing any decorator now fails it.
Contributor
Pyrefly Diffbase → PR--- /tmp/pyrefly_base.txt 2026-08-31 16:25:40.736934292 +0000
+++ /tmp/pyrefly_pr.txt 2026-08-31 16:25:31.472893528 +0000
@@ -3533,7 +3533,7 @@
ERROR Missing argument `endpoint_id` in function `controllers.console.workspace.endpoint.EndpointIdPayload.__init__` [missing-argument]
--> tests/unit_tests/controllers/console/workspace/test_endpoint.py:513:46
ERROR Argument `Literal['team']` is not assignable to parameter `plan` with type `CloudPlan | None` in function `services.workspace_service.EffectiveCreditPool.__init__` [bad-argument-type]
- --> tests/unit_tests/controllers/console/workspace/test_model_providers.py:236:18
+ --> tests/unit_tests/controllers/console/workspace/test_model_providers.py:260:18
ERROR Argument `list[FromClause]` is not assignable to parameter `tables` with type `Sequence[Table] | None` in function `sqlalchemy.sql.schema.MetaData.create_all` [bad-argument-type]
--> tests/unit_tests/controllers/console/workspace/test_workspace.py:54:54
ERROR `SimpleNamespace` is not assignable to attribute `db` with type `SQLAlchemy` [bad-assignment]
|
Contributor
Pyrefly Type Coverage
|
The decorator test only exercised ModelProviderListApi; dropping any of the other seven decorators left the suite green. It is now parametrized over all eight handlers, covering both sources the decorator reads — query args for the two get handlers, the JSON body for the rest — and each of the eight is individually detected when its decorator is removed. Also drops the blank lines the parse statements left behind, and reattaches the credential comment to the call it describes.
CI's Python Style job runs pyrefly over tests/ with its own config, which the new parametrized test tripped: unannotated parameters, a bare dict return on the payload helper, and typing.Any (banned by ruff TID251). Annotated with object, leaving the file at its baseline diagnostic count.
scripts/check_no_new_getattr.py rejects net-new getattr() in changed code, and the parametrized decorator test dispatched through getattr(api, verb). Each row now carries the bound call directly.
asukaminato0721
enabled auto-merge
September 1, 2026 04:23
asukaminato0721
approved these changes
Sep 1, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
part of #36659
Moves the eight inline parses in
console/workspace/model_providers.pyonto the@model_validatedecorator, the same change as #41374, #41490, #41491, #41500 and #41501. Claimed in this comment.Six read the JSON body. The other two —
ModelProviderListApi.getandModelProviderCredentialApi.get— already readrequest.args.to_dict(flat=True), which is exactly what the decorator's GET branch does, so they convert the same wayAccountAvatarApi.getandEducationAutoCompleteApi.getdid.requestis then unused in the module and drops out of the flask import.One thing worth flagging
ModelProviderCredentialApi.deleteis a DELETE, and the decorator readsrequest.argsfirst, falling back to the JSON body only when the query string is empty. The console sends that request with a body and no query string (web/service/use-models.ts), so behaviour is unchanged — but it is a real difference from the previous unconditional body read, so I would rather state it than have it found.Deliberately left alone
The rest of
console/workspace:skills.pywraps every parse inexcept ValidationError -> {"code": ..., "message": ...}, 400, andmembers.py/workspace.py/rbac.pyhave open PRs with hunks on the parse lines themselves.How did you test it?
pytest tests/unit_tests/controllers/console/— 2118 passed, against 2110 onmain; the eight extra are the parametrized decorator test added here. The single pre-existing failure (test_datasets_document_download.py, a Windows temp-file lock) reproduces identically onmainand is in a file this PR does not touch.ruff check/ruff format --check— clean;pyrefly check— 0 diagnosticsModelProviderSummaryListApi,ModelProviderCreditsApiandModelProviderPaymentCheckoutUrlApiare untouchedgethandlers, the JSON body for the restThis PR was fully generated with an AI assistant. I have reviewed the changes and run the relevant tests.