Add custom loads function (#2445)
Co-authored-by: Zhiwei <chihwei.public@outlook.com> Co-authored-by: Adam Hopkins <adam@amhopkins.com>
This commit is contained in:
parent
13d5a44278
commit
e4be70bae8
|
@ -170,6 +170,7 @@ class Sanic(BaseSanic, RunnerMixin, metaclass=TouchUpMeta):
|
|||
log_config: Optional[Dict[str, Any]] = None,
|
||||
configure_logging: bool = True,
|
||||
dumps: Optional[Callable[..., AnyStr]] = None,
|
||||
loads: Optional[Callable[..., Any]] = None,
|
||||
) -> None:
|
||||
super().__init__(name=name)
|
||||
|
||||
|
@ -223,6 +224,8 @@ class Sanic(BaseSanic, RunnerMixin, metaclass=TouchUpMeta):
|
|||
|
||||
if dumps:
|
||||
BaseHTTPResponse._dumps = dumps # type: ignore
|
||||
if loads:
|
||||
Request._loads = loads # type: ignore
|
||||
|
||||
@property
|
||||
def loop(self):
|
||||
|
|
|
@ -87,6 +87,7 @@ class Request:
|
|||
"""
|
||||
|
||||
_current: ContextVar[Request] = ContextVar("request")
|
||||
_loads = json_loads
|
||||
|
||||
__slots__ = (
|
||||
"__weakref__",
|
||||
|
@ -462,8 +463,11 @@ class Request:
|
|||
|
||||
return self.parsed_json
|
||||
|
||||
def load_json(self, loads=json_loads):
|
||||
def load_json(self, loads=None):
|
||||
try:
|
||||
if not loads:
|
||||
loads = self.__class__._loads
|
||||
|
||||
self.parsed_json = loads(self.body)
|
||||
except Exception:
|
||||
if not self.body:
|
||||
|
|
52
tests/test_json_decoding.py
Normal file
52
tests/test_json_decoding.py
Normal file
|
@ -0,0 +1,52 @@
|
|||
from json import loads as sloads
|
||||
|
||||
import pytest
|
||||
|
||||
|
||||
try:
|
||||
from ujson import loads as uloads
|
||||
|
||||
NO_UJSON = False
|
||||
DEFAULT_LOADS = uloads
|
||||
except ModuleNotFoundError:
|
||||
NO_UJSON = True
|
||||
DEFAULT_LOADS = sloads
|
||||
|
||||
from sanic import Request, Sanic, json
|
||||
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
def default_back_to_ujson():
|
||||
yield
|
||||
Request._loads = DEFAULT_LOADS
|
||||
|
||||
|
||||
def test_change_decoder():
|
||||
Sanic("Test", loads=sloads)
|
||||
assert Request._loads == sloads
|
||||
|
||||
|
||||
def test_change_decoder_to_some_custom():
|
||||
def my_custom_decoder(some_str: str):
|
||||
dict = sloads(some_str)
|
||||
dict["some_key"] = "new_value"
|
||||
return dict
|
||||
|
||||
app = Sanic("Test", loads=my_custom_decoder)
|
||||
assert Request._loads == my_custom_decoder
|
||||
|
||||
req_body = {"some_key": "some_value"}
|
||||
|
||||
@app.post("/test")
|
||||
def handler(request):
|
||||
new_json = request.json
|
||||
return json(new_json)
|
||||
|
||||
req, res = app.test_client.post("/test", json=req_body)
|
||||
assert sloads(res.body) == {"some_key": "new_value"}
|
||||
|
||||
|
||||
@pytest.mark.skipif(NO_UJSON is True, reason="ujson not installed")
|
||||
def test_default_decoder():
|
||||
Sanic("Test")
|
||||
assert Request._loads == uloads
|
Loading…
Reference in New Issue
Block a user