Search code examples
pythonjsonunicodeflaskiso-8859-1

How to prevent Unicode representation for Latin1 characters?


How can I prevent Flask from returning Latin characters as Unicode representation? For example, for this sort of characters: http://graphemica.com/%C3%91

My FlaskApp performs a SELECT inside a MySQL database, retrieves row by row, adding them to a list, storing the list into a dictionary and finally, returning a JSON.

FlaskAPP

@app.route("/json")
def show_json():
    avisos_dict = {}
    records_list = []
    query = "SELECT * FROM tjs_stage.avisos"
    cur.execute(query)
    con.commit()
    records = cur.fetchall()
    for row in records:
        records_list.append(row)
    avisos_dict['avisos'] = records_list
    return jsonify(avisos_dict)

MySQL data

mysql> SELECT * FROM tjs_stage.avisos;
+----+---------------------+---------------------------------+---------------------+---------------------+
| Id | Titulo              | Aviso                           | Creacion            | Modificacion        |
+----+---------------------+---------------------------------+---------------------+---------------------+
|  1 | PRIMERO AVISO       | MAÑANA EMPIEZAM VACACIONES     | 2016-04-06 18:12:52 | 2016-04-06 18:12:52 |
| 64 | Aviso de Vacaciones | Mañana empezam las vacaciones! | 2016-05-30 17:19:17 | 2016-05-30 17:19:17 |
+----+---------------------+---------------------------------+---------------------+---------------------+
2 rows in set (0.00 sec)

JSON

enter image description here

Does anyone knows how to solve this?

Thanks in advance ;)


Solution

  • "Ñ" and "\u00d1" json strings represent the same U+00D1 Unicode character:

    >>> import json
    >>> json.loads(u'"Ñ"') == json.loads(u'"\\u00d1"')
    True
    

    Note: the backslash is escaped because it is special inside Python string literals too.

    To avoid ascii-encoded json, set JSON_AS_ASCII to False:

    By default Flask serialize object to ascii-encoded JSON. If this is set to False Flask will not encode to ASCII and output strings as-is and return unicode strings. jsonify will automatically encode it in utf-8 then for transport for instance.

    Example:

    #!/usr/bin/env python
    from flask import Flask, jsonify
    
    app = Flask(__name__)
    app.config['JSON_AS_ASCII'] = False
    
    
    @app.route('/')
    def unicode_json():
        return jsonify({'text': u'\xd1'})
    
    
    if __name__ == '__main__':
        app.debug = True
        app.run()
    

    To run the server (assuming you saved it to app.py):

    $ python -mpip install flask -U
    $ python app.py
    

    To test it:

    $ python -mpip install httpie
    $ http --pretty=none :5000
    

    Output:

    HTTP/1.0 200 OK
    Content-Length: 18
    Content-Type: application/json
    Date: Tue, 31 May 2016 14:54:20 GMT
    Server: Werkzeug/0.10.4 Python/2.7.9
    
    {
        "text": "Ñ"
    }
    

    @Hareendra Chamara Philips suggests in the comment:

    Alternatively, if some one is using config.py and doing application.config.from_pyfile('config.py') in __init__.py, you can use JSON_AS_ASCII = False in the config.py.