-
Notifications
You must be signed in to change notification settings - Fork 159
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: typed request / response schema #1752
Conversation
src/ai/backend/manager/api/utils.py
Outdated
if isinstance(checker, t.Trafaret): | ||
checked_params = checker.check(stripped_params) | ||
else: | ||
checked_params = checker.model_validate(stripped_params) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For extra type safety, let's use the pattern matching.
if isinstance(checker, t.Trafaret): | |
checked_params = checker.check(stripped_params) | |
else: | |
checked_params = checker.model_validate(stripped_params) | |
match checker: | |
case t.Trafaret(): | |
checked_params = checker.check(stripped_params) | |
case BaseModel(): | |
checked_params = checker.model_validate(stripped_params) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've added a commit to keep consistency of the decorated request handler's typing. The request handler should use Callable[[web.Request, ...], web.StreamResponse]
always, so that middleware could be composed in any order and additional strong-typed decorators do not get confused.
Currently I couldn't find a good way to apply typing.overload
to embrace both the trafaret version and the pydantic version of check_api_params()
, and thus split out check_api_params_v2()
for new codes.
Please work on the remaining migration that I've left as TODOs, and also ensure the OpenAPI doc generator's implementation to work with check_api_params_v2()
.
This PR introduces Pydantic based request and response schema validation, along with automatic OpenAPI spec generation of those who've opted in for Pydantic based handler instead of traditional trafaret way.
What's changed
support for Pydantic validator on both request and response body
Now you can pass a Pydantic model, which inherits
BaseModel
, as a request body validator.There are two major advantages of choosing Pydantic in place of of Trafaret: much faster, and native type inference support for
params
parameter (which will act as a parsed request body). Please note that, after transiting the validator to Pydantic model, you can no longer access values described under request body via string index (params["abc"]
way).Same way also applies for the response schema:
Note the difference of function return type annotation between two handlers. Explicitly defining the response type will help Backend.AI's automated OpenAPI spec generator understand the response schema and render it as OpenAPI spec.
On-the-fly REST API reference viewer
Two new GET resources (
/spec
,/spec/spec.json
) are newly introduced on this patch.GET /spec
: returns HTML page containing a REST API reference documentation for Backend.AI. Please keep in mind that this page won't work under the air-gapped environment.GET /spec/spec.json
: returns OpenAPI-3.0.0 compliant JSON schema of whole Backend.AI REST APIThe entire
/spec
resource is disabled by default, so in order to activate these system administrator has to set value ofconfig/api/allow-openapi-schema-introspection
etcd key toyes
.Checklist: (if applicable)