
GCP上でサーバーの設定をせずにプログラムだけを実行できるCloudFuntions。
CloudFuntionsではいくつかのプログラム言語を利用できる。
その中のひとつ「Python」を使い、トリガーに「HTTP」を指定した場合、あるエラーに遭遇することがある。
TypeError: string indices must be integers
requestにstringではなく配列(list)や辞書型(dict)を渡すとこのエラーが発生する。
一体何が原因なのか。
そこで今回は、requestにlistやdict変数を格納したのに「TypeError: string indices must be integers」になる原因と解決方法について解説する。
この記事を書いている人

記事を読むメリット
requestにlistやdict変数を格納したのに「TypeError: string indices must be integers」になる現象

エラーが発生する現象はどのようなものか。
まず http request に以下の要素を持つjsonを格納してCloudFunctionsのトリガーとする。
"data":[{"key1":"val11","key2":"val12"},
{"key1":"val21","key2":"val22"},
{"key1":"val31","key2":"val32"}]
CloudFunctions側は request.get_json() でrequestのjsonを読み解き、その中に格納した data 要素を呼ぶ。
そして data の中の配列を順に print() しようとしている。
request_json = request.get_json() json_data = request_json["data"] for v in json_data: print(v["key1"])
すると以下のエラーが発生する。
TypeError: string indices must be integers
「TypeError: string indices must be integers」になる原因

原因はエラーメッセージを見るとわかる。
TypeError: string indices must be integers なので「string型の添字はint型でないとダメです」と言っている。
つまり print(v["key1"]) で辞書型変数の中身を表示しようとしたが、Pythonは辞書型(dict)ではなく文字列型として認識しているのでエラーになっている。
何故文字列として認識しているかというと、 request.get_json() の仕様。
request.get_json()で読み込まれた各要素は文字列として認識される。
つまりdata要素の中身は
[{"key1":"val11","key2":"val12"},
{"key1":"val21","key2":"val22"},
{"key1":"val31","key2":"val32"}]
という辞書型を複数格納した配列ではなく
'[{"key1":"val11","key2":"val12"},
{"key1":"val21","key2":"val22"},
{"key1":"val31","key2":"val32"}]'
という長い文字列として認識されているので、辞書型のつもりで要素を呼ぶとエラーになってしまう。
「TypeError: string indices must be integers」の解決方法

「TypeError: string indices must be integers」の解決方法だが、文字列を配列(list)や辞書型(dict)として認識させればいい。
文字列を配列(list)や辞書型(dict)として認識させるには eval() を使う。
request_json = request.get_json() json_data = eval(request_json["data"]) for v in json_data: print(v["key1"])
こうすることで eval() に指定した文字列を式として評価し直すので、文字列を配列(list)や辞書型(dict)として認識させることができる。
eval() については過去記事を参考。
あわせて読みたい
requestにlistやdict変数を格納したのに「TypeError: string indices must be integers」になる原因と解決方法 まとめ

CloudFunctionsのPythonを利用する際、requestにlistやdict変数を格納したのに「TypeError: string indices must be integers」になる原因は送ったデータが文字列として認識されているから。
解決方法として、取り込んだ文字列に eval() を適用するとlistやdictとして認識してくれる。




Pythonの外側からデータを渡す方法として、iniファイルを読む方法についても記事があるので、もし気になったら見て欲しい。




