Skip to content

Commit

Permalink
Merge branch 'master' of https://github.com/vitalik/django-ninja
Browse files Browse the repository at this point in the history
  • Loading branch information
vitalik committed Sep 5, 2023
2 parents 3b64989 + 805ee6a commit b632bb9
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 3 deletions.
2 changes: 1 addition & 1 deletion docs/docs/guides/async-support.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ uvicorn your_project.asgi:application --reload

### Test

Go to your browser and open <a href="<<<<<<<http://127.0.0.1:8000/api/say-after?delay=3&word=hello>>>>>>>" target="_blank">http://127.0.0.1:8000/api/say-after?delay=3&word=hello</a> (**delay=3**)
Go to your browser and open <a href="http://127.0.0.1:8000/api/say-after?delay=3&word=hello" target="_blank">http://127.0.0.1:8000/api/say-after?delay=3&word=hello</a> (**delay=3**)
After a 3-second wait you should see the "hello" message.

Now let's flood this operation with **100 parallel requests**:
Expand Down
8 changes: 6 additions & 2 deletions ninja/errors.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,14 +39,18 @@ class ValidationError(Exception):
"""

def __init__(self, errors: List[DictStrAny]) -> None:
super().__init__()
self.errors = errors
super().__init__(errors)


class HttpError(Exception):
def __init__(self, status_code: int, message: str) -> None:
self.status_code = status_code
super().__init__(message)
self.message = message
super().__init__(status_code, message)

def __str__(self) -> str:
return self.message


def set_default_exc_handlers(api: "NinjaAPI") -> None:
Expand Down
3 changes: 3 additions & 0 deletions ninja/responses.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from enum import Enum
from ipaddress import IPv4Address, IPv6Address
from typing import Any, FrozenSet

Expand All @@ -22,6 +23,8 @@ def default(self, o: Any) -> Any:
return o.model_dump()
if isinstance(o, (IPv4Address, IPv6Address)):
return str(o)
if isinstance(o, Enum):
return str(o)
return super().default(o)


Expand Down
26 changes: 26 additions & 0 deletions tests/test_errors.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import pickle

from ninja.errors import HttpError, ValidationError


def test_validation_error_is_picklable_and_unpicklable():
error_to_serialize = ValidationError([{"testkey": "testvalue"}])

serialized = pickle.dumps(error_to_serialize)
assert serialized # Not empty

deserialized = pickle.loads(serialized)
assert isinstance(deserialized, ValidationError)
assert deserialized.errors == error_to_serialize.errors


def test_http_error_is_picklable_and_unpicklable():
error_to_serialize = HttpError(500, "Test error")

serialized = pickle.dumps(error_to_serialize)
assert serialized # Not empty

deserialized = pickle.loads(serialized)
assert isinstance(deserialized, HttpError)
assert deserialized.status_code == error_to_serialize.status_code
assert deserialized.message == error_to_serialize.message
13 changes: 13 additions & 0 deletions tests/test_response.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import json
from enum import Enum
from ipaddress import IPv4Address, IPv6Address
from typing import List, Union

Expand Down Expand Up @@ -30,6 +31,11 @@ def __init__(self, id, user_name, password):
self.password = password


class MyEnum(Enum):
first = "first"
second = "second"


def to_camel(string: str) -> str:
return "".join(word.capitalize() for word in string.split("_"))

Expand Down Expand Up @@ -157,3 +163,10 @@ def test_ipv6address_encoding():
response = Response(data)
response_data = json.loads(response.content)
assert response_data["ipv6"] == str(data["ipv6"])


def test_enum_encoding():
data = {"enum": MyEnum.first}
response = Response(data)
response_data = json.loads(response.content)
assert response_data["enum"] == str(data["enum"])

0 comments on commit b632bb9

Please sign in to comment.