Reputation: 45
I am using Django Ninja to develop APIs
from ninja import Schema
from ninja.errors import HttpError, ValidationError
class MyOutSchema(Schema)
@router.get("/", response={200: MyOutSchema, 404:XXX, 429:XXX, 400:XXX})
def my_api(request, params)
{
// Some code that may raise HttpError and ValidationError
}
What can I use in place of XXX
?
I cannot use HttpError or ValidationError since the documentation then fails to get the correct schema from Ninja
How can I convert the Ninja error objects to "Schem"able classes ?
I tried using HttpError
in the response dictionary and I was expecting it to work.
The documentation generation failed.
[14:13:01] [DJANGO] @router.get(
[14:13:01] [DJANGO] ^^^^^^^^^^^
[14:13:01] [DJANGO] File "/home/Work/web-framework/.venv/lib/python3.11/site-packages/ninja/router.py", line 239, in decorator
[14:13:01] [DJANGO] self.add_api_operation(
[14:13:01] [DJANGO] File "/home/Work/web-framework/.venv/lib/python3.11/site-packages/ninja/router.py", line 288, in add_api_operation
[14:13:01] [DJANGO] path_view.add_operation(
[14:13:01] [DJANGO] File "/home/Work/web-framework/.venv/lib/python3.11/site-packages/ninja/operation.py", line 306, in add_operation
[14:13:01] [DJANGO] operation = OperationClass(
[14:13:01] [DJANGO] ^^^^^^^^^^^^^^^
[14:13:01] [DJANGO] File "/home/Work/web-framework/.venv/lib/python3.11/site-packages/ninja/operation.py", line 75, in __init__
[14:13:01] [DJANGO] self.response_models = self._create_response_model_multiple(response)
[14:13:01] [DJANGO] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
[14:13:01] [DJANGO] File "/home/Work/web-framework/.venv/lib/python3.11/site-packages/ninja/operation.py", line 241, in _create_response_model_multiple
[14:13:01] [DJANGO] result[code] = self._create_response_model(model)
[14:13:01] [DJANGO] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
[14:13:01] [DJANGO] File "/home/Work/web-framework/.venv/lib/python3.11/site-packages/ninja/operation.py", line 248, in _create_response_model
[14:13:01] [DJANGO] return type("NinjaResponseSchema", (Schema,), attrs)
[14:13:01] [DJANGO] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
[14:13:01] [DJANGO] File "/home/Work/web-framework/.venv/lib/python3.11/site-packages/ninja/schema.py", line 145, in __new__
[14:13:01] [DJANGO] result = super().__new__(cls, name, bases, namespace, **kwargs)
[14:13:01] [DJANGO] ^
[14:13:01] [DJANGO] ^
[14:13:01] [DJANGO] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
[14:13:01] [DJANGO] File "pydantic/main.py", line 197, in pydantic.main.ModelMetaclass.__new__
[14:13:01] [DJANGO] File "pydantic/fields.py", line 506, in pydantic.fields.ModelField.infer
[14:13:01] [DJANGO] File "pydantic/fields.py", line 436, in pydantic.fields.ModelField.__init__
[14:13:01] [DJANGO] File "pydantic/fields.py", line 557, in pydantic.fields.ModelField.prepare
[14:13:01] [DJANGO] File "pydantic/fields.py", line 831, in pydantic.fields.ModelField.populate_validators
[14:13:01] [DJANGO] File "pydantic/validators.py", line 765, in find_validators
[14:13:01] [DJANGO] RuntimeError: no validator found for <class 'ninja.errors.ValidationError'>, see `arbitrary_types_allowed` in Config
Also I tried using None
hoping that it would default to some nice Ninja error schema but it did not.
Upvotes: 3
Views: 1094
Reputation: 13289
Django Ninja can do this more automatically for you if you just raise HttpError
as an exception with the corresponding error message, instead of returning anything. You don't really need to handle this using schemas yourself.
Try something like this instead:
from ninja.errors import HttpError
from ninja.schema import Schema
class MyOutSchema(Schema):
something: str
@router.get("/", response=MyOutSchema)
def my_api(request, params):
if not params_make_sense(params):
raise HttpError(400, "Example error message")
return {
"something": "daddara",
}
Note that it is using raise
instead of return
.
Using httpie
to test the endpoint from the command line, the client output might look something like:
HTTP/1.1 400 Bad Request
Content-Language: is
Content-Length: 35
Content-Type: application/json; charset=utf-8
Cross-Origin-Opener-Policy: same-origin
Date: Sun, 12 Nov 2023 19:24:50 GMT
Referrer-Policy: same-origin
Server: WSGIServer/0.2 CPython/3.11.6
Vary: Accept-Language
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
{
"detail": "Example error message"
}
Upvotes: 1