質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Flask

FlaskはPython用のマイクロフレームワークであり、Werkzeug・Jinja 2・good intentionsをベースにしています。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

2896閲覧

PythonのFlaskでのユーザー定義関数呼び出し

nagomisan

総合スコア14

Flask

FlaskはPython用のマイクロフレームワークであり、Werkzeug・Jinja 2・good intentionsをベースにしています。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2019/06/19 02:15

編集2019/06/19 02:17

遭遇しているトラブルの概要

初めてFlaskを使用してREST APIの学習用のコードを書いて試しています。
以下コード(抜粋)において、get_item() 関数内で find_item_by() 関数を呼び出しているコードを書いているのですが、なぜか find_item_by() 関数が呼び出されず困っています。

該当のソースコード

python

1def find_item_by(id): 2 return list(filter(lambda item: item["id"] == id, items)) 3 4@app.route('/items/', methods=['GET']) 5def get_items(): 6 return jsonify(items), 200 7 8@app.route('/items/<string:id>', methods=['GET']) 9def get_item(id): 10 11 item = find_item_by(request.form["id"]) 12 13 if not item: 14 abort(404) 15 16 return jsonify(item)

試したこと

  • get_items() はきちんと動作しており、クライアントのWebブラウザに Items の内容がきちんと表示されます。
  • クライアントからのリクエストに対する get_item() の呼び出しは成功しており、find_item_by() の呼び出しの直前に print('OK') を記述すると、コンソールに「OK」が表示されます。
  • find_item_by() 関数内の先頭に print('OK') を記述したのですが、コンソールに「OK」が表示されないため関数が呼び出されていないようです。
  • find_item_by() 関数呼び出しの部分を削除して、処理をインラインで記述すれば、問題なくクライアントに正しい Item の内容が表示されます。
  • サーバー側ではエラー・メッセージは表示されていませんが、クライアント側は400の「Bad request」が表示されます。
  • 該当のコード部分をFlaskではなく main() 関数を書いた通常のスクリプトとしてファイルで実行すると、問題なく動作します。

当方PythonもFlaskも最近学習しだしたばかりで、わかっていないことがあるのかもしれませんが、ユーザー定義の関数が通常のファイルだと呼び出せて、Flask上だと呼び出せない理由が調べてもわかりませんでした。

どなたか何かわかりましたらアドバイスを頂けると幸いです。

補足情報(FW/ツールのバージョンなど)

Python 3.7.3
Flask 1.0.3

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

◯ 改善策

対話モード >>> にコピペで実行できます。

python

1from flask import Flask, jsonify, abort, request 2 3app = Flask('__main__') 4items = [ 5 {'id': 0, 'name': 'hello'}, 6 {'id': 1, 'name': 'nihao'}, 7 {'id': 2, 'name': 'konnichiwa'} 8] 9 10 11def find_item_by(id): 12 return list(filter(lambda item: item['id'] == id, items)) 13 14 15@app.route('/items/', methods=['GET']) 16def get_items(): 17 return jsonify(items), 200 18 19 20@app.route('/items/<string:id>', methods=['GET']) 21def get_item(id): 22 # 原因 23 # find_item_by(request.form["id"]) 24 # 改善策 1 25 item = find_item_by(int(id)) 26 # 改善策 2 27 # item = find_item_by(int(request.view_args['id'])) 28 if not item: 29 abort(404) 30 return jsonify(item) 31 32 33app.run()

引数からそのまま取ってこれるので、あとは str から int にキャストすれば OK です。

◯ デバッグで気づけなかった原因

そして頑張ってデバッグ時で気づけなかったのは request.form に間違ったキーを入れても None を返して来るからです。間違った箇所を静かに通り過ぎていきます。本来は、例外を投げ返してほしいです。ちょうど今日自分もハマってました笑

◯ ちなみに...

request.form は POST メソッドから値を取り出すときに使います。

投稿2019/06/19 09:33

編集2019/06/19 09:36
nico25

総合スコア830

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

nagomisan

2019/06/19 22:51

早速の回答ありがとうございました。PythonもFlaskも学習し始めたばかりで、勝手な思い込みからPythonの言語仕様やFlaskの仕様ばかりに目が行き、request.formはPOSTメソッドから値を取り出すという基本的な部分が盲点となっていました。request.form["id"]の値をきちんと確かめていたら気付けていたかもしれませんね。やはりデバッグは先入観を捨てて客観的に診ていくことが大切だと改めて勉強になりました。 そうですね、当方もJavaやC#といった静的型付け言語中心にやってきたので例外を投げてほしいところです。動的型付け言語の嵌りポイントにまだまだ慣れていませんが、学習を進めて対応できるようにしていきます。ありがとうございました。
nagomisan

2019/06/19 22:59

【追伸】 リンクのページのNoneに関する説明、非常にわかりやすくためになる内容ですね。改めてお礼申し上げます。
nico25

2019/06/20 02:07

そう言っていただけると嬉しいです。 ありがとうございます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問