Google App Engine で Flask とフラスコレストフルを使用して、非常に単純な REST API を作成しました。この API は、慈善募金イベントに関するデータを表すために使用するように設計されています。この場合は自転車です。
App Engine のログからの次のスタック トレースに示されている型エラーが断続的に発生することを除いて、すべてが機能しているようです。
Internal Error
Traceback (most recent call last):
File "/base/data/home/apps/s~agonytrackertest/1.376935219653445037/lib/flask/app.py", line 1475, in full_dispatch_request
rv = self.dispatch_request()
File "/base/data/home/apps/s~agonytrackertest/1.376935219653445037/lib/flask/app.py", line 1461, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "/base/data/home/apps/s~agonytrackertest/1.376935219653445037/lib/flask_restful/__init__.py", line 397, in wrapper
resp = resource(*args, **kwargs)
File "/base/data/home/apps/s~agonytrackertest/1.376935219653445037/lib/flask/views.py", line 84, in view
return self.dispatch_request(*args, **kwargs)
File "/base/data/home/apps/s~agonytrackertest/1.376935219653445037/lib/flask_restful/__init__.py", line 487, in dispatch_request
resp = meth(*args, **kwargs)
File "/base/data/home/apps/s~agonytrackertest/1.376935219653445037/main.py", line 268, in post
supersedes=d['Supersedes'])
TypeError: 'RiderStatus' object is not callable
RiderStatus オブジェクトは次のように定義されます。
class RiderStatus(ndb.Model):
""" Models a status for a Rider with rider_id, location, action, time_stamp
status_id
"""
rider_number = ndb.IntegerProperty(indexed=True, required=True)
location = ndb.StringProperty(indexed=False, required=True)
state = ndb.StringProperty(indexed=False, required=True)
time_recorded = ndb.DateTimeProperty(auto_now_add=True)
time_occurred = ndb.IntegerProperty(indexed=False, required=True)
status_id = ndb.StringProperty(indexed=True, required=True)
status_origin = ndb.StringProperty(indexed=True, required=True)
supersedes = ndb.StringProperty(indexed=False, required=True)
ログで呼び出されるコード セクションは、新しい RiderStatus オブジェクトの作成であり、次のようになります。
for d in statuses:
created_count += 1
status = Models.RiderStatus(rider_number=d['RiderNumber'],
location=d['Location'], state=d['State'], time_occurred=d['TimeStamp'],
status_id=d['StatusId'], status_origin=d['StatusOrigin'],
supersedes=d['Supersedes'])
status.put()
return {"created":str(created_count)}, 201
おそらくオブジェクトの初期化方法だと思いましたが、前述の方法はPythonで一般的に使用されていることを理解していたので、クラスと初期化メソッドの明示的なコンストラクターを作成しました。クラスは次のようになりました。
class RiderStatus(ndb.Model):
""" Models a status for a Rider with rider_id, location, action, time_stamp
status_id
"""
def __init__(self, rider_number=0, location='', state='', time_occurred=0, status_id='', status_origin='',
supersedes=''):
super(RiderStatus, self).__init__()
self.rider_number = rider_number
self.location = location
self.state = state
self.time_occurred = time_occurred
self.status_id = status_id
self.status_origin = status_origin
self.supersedes = supersedes
rider_number = ndb.IntegerProperty(indexed=True, required=True)
location = ndb.StringProperty(indexed=False, required=True)
state = ndb.StringProperty(indexed=False, required=True)
time_recorded = ndb.DateTimeProperty(auto_now_add=True)
time_occurred = ndb.IntegerProperty(indexed=False, required=True)
status_id = ndb.StringProperty(indexed=True, required=True)
status_origin = ndb.StringProperty(indexed=True, required=True)
supersedes = ndb.StringProperty(indexed=False, required=True)
def make_rider_status(self, in_dict):
self.rider_number = in_dict['RiderNumber']
self.location = in_dict['Location']
self.state = in_dict['State']
self.time_occurred = in_dict['TimeStamp']
self.status_id = in_dict['StatusId']
self.status_origin = in_dict['StatusOrigin']
self.supersedes = in_dict['Supersedes']
そして、作成は次のようになりました。
for d in statuses:
created_count += 1
status = Models.RiderStatus()
status.make_rider_status(d)
status.put()
return {"created":str(created_count)}, 201
そして、同様のエラーが発生します。
Internal Error
Traceback (most recent call last):
File "/base/data/home/apps/s~agonytrackermain/1.377017814438367636/lib/flask/app.py", line 1475, in full_dispatch_request
rv = self.dispatch_request()
File "/base/data/home/apps/s~agonytrackermain/1.377017814438367636/lib/flask/app.py", line 1461, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "/base/data/home/apps/s~agonytrackermain/1.377017814438367636/lib/flask_restful/__init__.py", line 397, in wrapper
resp = resource(*args, **kwargs)
File "/base/data/home/apps/s~agonytrackermain/1.377017814438367636/lib/flask/views.py", line 84, in view
return self.dispatch_request(*args, **kwargs)
File "/base/data/home/apps/s~agonytrackermain/1.377017814438367636/lib/flask_restful/__init__.py", line 487, in dispatch_request
resp = meth(*args, **kwargs)
File "/base/data/home/apps/s~agonytrackermain/1.377017814438367636/main.py", line 283, in post
status = Models.RiderStatus()
TypeError: 'RiderStatus' object is not callable
おそらく、その API URL に POST する時間の約 50% で、このエラーが発生します。残りの 50% の時間は問題なく動作します。App Engine SDK を使用してローカル ボックスで実行し、App Engine にデプロイした場合とほぼ同じ失敗率が得られます。ただし、デバッガーを接続したときにエラーが発生することはありません。デバッグ印刷呼び出しを追加することで、失敗すると for ループの最初の反復で失敗し、d が実際にアクセスしようとしているキーと値を持つ辞書であることがわかりました。
私はPython、Flask、およびApp Engineに非常に慣れていないため、ここで何かが欠けていることは間違いありませんが、見つけた「オブジェクトは呼び出し可能ではありません」という投稿をすべて読みましたが、当てはまると思われるものは何も見つかりませんでした.コンストラクターの一部が欠落しており、オブジェクトを別の型に再割り当てしておらず、基本型をオーバーライドしていません (とにかく見つけることができました)。
これが FLASK の問題なのか、Python の問題なのか、flask-restful の問題なのか、App Engine の問題なのか、それとも私の問題なのかわかりません。次のステップは、Flask のみを使用して API をやり直し、より確実に動作するかどうかを確認することです。それまでの間、どんな助けも大歓迎です。