0

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 の問題なのか、fl​​ask-restful の問題なのか、App Engine の問題なのか、それとも私の問題なのかわかりません。次のステップは、Flask のみを使用して API をやり直し、より確実に動作するかどうかを確認することです。それまでの間、どんな助けも大歓迎です。

4

1 に答える 1