Why sanic return response as text?

Next code:

    def request_processing(req):
        answer = json.dumps(get_db_regions(), ensure_ascii=False)
        return response.json(answer)

JS typeof show data type as text

is return to web-browser text instead of json-object. What’s wrong? How I can fix it?

But this code is return correct json:

return response.json([{"eng_name": "moskva", "rus_name": "Москва"}, {"eng_name": "adygeya_resp", "rus_name": "Адыгейская республика"}])

UPD:

this code is return correct json:

return response.json(get_db_regions())

Why? Response convert any answer to json? Who can explain?

When you do json.dumps, that will convert your dict object into a string. Then, you are passing that string to the Sanic response.json, which also under the hood performs a json.dumps like call.

Therefore, you are essentially serializing your data twice.

async def test(request):
    output = {'hello': 'world'}
    return response.json(output)

When I hit this endpoint, I get JSON as expected:

HTTP/1.1 200 OK
Connection: keep-alive
Keep-Alive: 5
Content-Length: 17
Content-Type: application/json

{"hello":"world"}

If I wrap it in json.dumps:

@app.route('/')
async def test(request):
    output = json.dumps({'hello': 'world'})
    return response.json(output)

I get an unintended result:

HTTP/1.1 200 OK
Connection: keep-alive
Keep-Alive: 5
Content-Length: 24
Content-Type: application/json

"{\"hello\": \"world\"}"

This explains why … but it does not explain how you can achieve your goal of customizing the serialization method.

Luckily, the response.json method takes a dumps keyword, which is the function that will perform the serializing. So, if I need to make a modification to the serializing method (as in your case with ensure_ascii=False), then I can do it like this:

from functools import partial

@app.route('/')
async def test(request):
    output = {'hello': 'world'}
    dumps = partial(json.dumps, ensure_ascii=False)
    return response.json(output, dumps=dumps)

And, using your example, the response:

HTTP/1.1 200 OK
Connection: keep-alive
Keep-Alive: 5
Content-Length: 139
Content-Type: application/json

[{"eng_name": "moskva", "rus_name": "Москва"}, {"eng_name": "adygeya_resp", "rus_name": "Адыгейская республика"}]
1 Like

Thanks for answer. But if I have string

mystr = “”"{’'aa":“11”}"""

What it the proper way to send answer?

Assuming you have that text and you want to send it as json, you would strip out the extra quotes and use json.loads() to convert the string to a dict, then use response.json() to spit it out to the browser.

json_object = json.loads(mystr.replace('""',''))
response.json(json_object)

note the above is really only pythonic pseudocode; you’ll need to handle properly unquoting your string before you can successfully do the string-to-dict conversion. You may also need to convert the double-quotes to single quotes for your keys and values, because I don’t remember how fussy json.loads() is offhand.