staticdev
staticdev

Reputation: 3060

How to correctly produce and consume UTF-8 json in Python3? (with flask and requests)

I've made some basic code to explain my question:

produceUTF8.py (replies 'ít wórked!' with unicode characters) - you run this first

# -*- coding: utf-8 -*-
import os
from sys import argv

from flask import Flask, request, Response, jsonify
import json

app = Flask(__name__)
app.config['JSON_AS_ASCII'] = False # contribution from Erdem

@app.route('/reply', methods=['POST'])
def reply():
    """Fetch a reply
    """
    print("DEBUG entered")
    params = request.json
    print("DEBUG entered2")
    if not params:
        return jsonify({
            'status': 'error',
            'error': 'Request must be of the application/json type!',
        })

    reply = "ít wórked!"

    # Send the response.
    return jsonify({
        'status': 'ok',
        'reply': reply,
    })

if __name__ == '__main__':
    app.run(host='0.0.0.0', debug=True)

consumeUTF8.py (posts the message 'óíá' to get answer from producer)

# -*- coding: utf-8 -*-
import requests

HEADERS = {'Content-Type': 'application/json; charset=utf-8',}
DATA = '{"message": "óíá"}'
my_request = requests.post('http://localhost:5000/reply', headers=HEADERS, data=DATA)
response = my_request.json()['reply']

In my producer I am getting "Bad Request (400)" and in the consumer "json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)."

It seems to be a problem in params = request.json as seen in the debug prints. What is the recommended approach here?

Thanks!

Upvotes: 4

Views: 9518

Answers (2)

PRMoureu
PRMoureu

Reputation: 13327

You can fix the way you make the request by encoding the data object :

my_request = requests.post('http://localhost:5000/reply', 
                           headers=HEADERS, 
                           data=DATA.encode('utf-8'))

#>>> ít wórked with óíá!

If you add a try/except statement in the app, it returns :

try:
    params = request.json
except Exception as e:
    params = None
    print(e)

400 Bad Request: Failed to decode JSON object: 'utf-8' codec can't decode byte 0xf3 in position 14: invalid continuation byte

You could use this pattern to assign a default value for param

Upvotes: 2

user762630
user762630

Reputation:

I have not tried the code but may be setting

app.config['JSON_AS_ASCII'] = False

may help.

Upvotes: 2

Related Questions