当サイトは、アフィリエイト広告を利用しています

【Python × Flask】REST APIでjsonifyのレスポンスが文字化けする時の対応方法

作成日:2024月08月23日
更新日:2024年08月23日

flaskで作ったREST APIのレスポンスの日本語が文字化けしたので
対応を方法を忘備録として残しておく。
※Flask==3.0.2で発生した

下記のような文字化けが発生する

curlで実行
$ curl -X GET http://localhost:5000/
[
{
"book": "\u3059\u3079\u3066\u304cF\u306b\u306a\u308b",
"id": "1",
"name": "\u68ee\u535a\u55e3"
},
{
"book": "\u6697\u95c7\u5742\u306e\u4eba\u98df\u3044\u306e\u6728",
"id": "2",
"name": "\u5cf6\u7530\u8358\u53f8"
},
{
"book": "\u540d\u524d\u63a2\u3057\u306e\u653e\u8ab2\u5f8c",
"id": "3",
"name": "\u8fbb\u6751\u6df1\u6708"
},
{
"book": "\u9b4d\u9b4e\u306e\u5323",
"id": "4",
"name": "\u4eac\u6975\u590f\u5f66"
}
]

発生状況

レスポンスの日本語が文字化けした状況をまとめる。

REST API

下記のようなFlaskのREST APIを実装、起動した

プロジェクト構成
.
|-- app
|-- __init__.py
|-- api.py
`-- wsgi.py

シンプルなREST API

api.py

api.py
from flask import Flask, jsonify,make_response
# ディクショナリ
users = [
{"id": "1", "name": "森博嗣", "book":"すべてがFになる"},
{"id": "2", "name": "島田荘司", "book":"暗闇坂の人食いの木"},
{"id": "3", "name": "辻村深月", "book":"名前探しの放課後"},
{"id": "4", "name": "京極夏彦", "book":"魍魎の匣"}]
def routers(api):
@api.route('/', methods=['GET'])
def get_users():
return make_response(jsonify(users), 200)
# flaskインスタンス作成
def create_app():
# 作成
api = Flask(__name__)
# 関数ベースのルーティング設定
routers(api)
return api

GETリクエストでusersをレスポンスとして返却する

wsgi.py

wsgi.py
# flaskインスタンス生成関数をimport
from app.api import create_app
# flaskインスタンスを生成
api = create_app()

Flaskアプリケーションをで起動するためのエントリーポイント

FlaskのREST APIについては下記で詳しくまとめています。

リクエスト

発生する際、リクエストをどう送ったかをまとめる。
下記のツール等でリクエストを送信し検証した

  1. ブラウザから実行(GoogleChrome)
  2. WindowsTermnalからCurlcommandで実行
  3. Postmanで実行
  4. Talend API Tester -Free Editionで実行

先に結論をいうと3,4などのツールを使った場合は文字化けは発生しない。
ツール系はそのへんちゃんとしてくれているらしい。

ブラウザから実行(GoogleChrome)

ブラウザにURLを入力してリクエストする
2024-08-22-00-09-46

文字化けする

WindowsTermnalからCurlコマンドで実行

bash
$ curl -X GET http://localhost:5000/
[
{
"book": "\u3059\u3079\u3066\u304cF\u306b\u306a\u308b",
"id": "1",
"name": "\u68ee\u535a\u55e3"
},
{
"book": "\u6697\u95c7\u5742\u306e\u4eba\u98df\u3044\u306e\u6728",
"id": "2",
"name": "\u5cf6\u7530\u8358\u53f8"
},
{
"book": "\u540d\u524d\u63a2\u3057\u306e\u653e\u8ab2\u5f8c",
"id": "3",
"name": "\u8fbb\u6751\u6df1\u6708"
},
{
"book": "\u9b4d\u9b4e\u306e\u5323",
"id": "4",
"name": "\u4eac\u6975\u590f\u5f66"
}
]

冒頭の通り、文字化けする

Postmanで実行

2024-08-22-00-11-13

文字化けしない

Talend API Tester -Free Editionで実行

2024-08-22-00-12-14 文字化けしない

発生原因

デフォルトでは、FlaskはJSONレスポンスを生成する際に、ASCIIモードでエンコードするため
非ASCII文字である日本語もASCIIモードで出力され文字化けする

対応方法

非ASCII文字をUnicodeエスケープ(\uXXXX)形式で出力せず、そのままのUTF-8形式で出力するようにする。 これにより日本語などの非ASCII文字がエスケープされず、そのままJSONレスポンスに含まれるようになる。

具体的いは下記のようにする

api.py
from flask import Flask, jsonify,make_response
# ディクショナリ
users = [
{"id": "1", "name": "森博嗣", "book":"すべてがFになる"},
{"id": "2", "name": "島田荘司", "book":"暗闇坂の人食いの木"},
{"id": "3", "name": "辻村深月", "book":"名前探しの放課後"},
{"id": "4", "name": "京極夏彦", "book":"魍魎の匣"}]
def routers(api):
@api.route('/', methods=['GET'])
def get_users():
return make_response(jsonify(users), 200)
# flaskインスタンス作成
def create_app():
# 作成
api = Flask(__name__)
# 日本語文字化け対応
api.json.ensure_ascii = False
# 関数ベースのルーティング設定
routers(api)
return api

これでブラウザでもcurlコマンドでも文字化けしなくなる。

その他の方法について

ネットを調べると

対応方法
api.json.ensure_ascii = False

ではなく

その他の対応
api.config['JSON_AS_ASCII'] = False

にするという対応をよく見るが、今回動作させた
Flask==3.0.2では

その他の対応
api.config['JSON_AS_ASCII'] = False

では文字化けは解消されなかった。
※古いversionでは有効かもしれない

まとめ

flaskのレスポンス文字化けについてすこし調べてみた。
curlやブラウザから実行した時のみ発生したので
気を付けようと思った。
※実際の開発ではツールを使うことが多いので。。。

新着記事

タグ別一覧
top