Reputation: 9
I have been going through the google cloud NDB Async examles tutorials
https://cloud.google.com/appengine/docs/standard/python/ndb/async
You can specify a whole WSGIApplication as ndb.toplevel. This makes sure that each of the WSGIApplication's handlers waits for all async requests before returning. (It does not "toplevel" all the WSGIApplication's handlers.)
app = ndb.toplevel(webapp2.WSGIApplication([('/', MyRequestHandler)]))
Is this same functionality compatible with Flask? For example my code
app = Flask(__name__)
app.config.update(DEBUG = not SERVER_ISPRODUCTION)
app = ndb.toplevel(app)
...
@app.route('/test')
def testBackfill():
Gives me error
Traceback (most recent call last):
File "/base/data/home/runtimes/python27_experiment/python27_lib/versions/1/google/appengine/runtime/wsgi.py", line 240, in Handle
handler = _config_handle.add_wsgi_middleware(self._LoadHandler())
File "/base/data/home/runtimes/python27_experiment/python27_lib/versions/1/google/appengine/runtime/wsgi.py", line 299, in _LoadHandler
handler, path, err = LoadObject(self._handler)
File "/base/data/home/runtimes/python27_experiment/python27_lib/versions/1/google/appengine/runtime/wsgi.py", line 85, in LoadObject
obj = __import__(path[0])
@app.route('/test')
AttributeError: 'function' object has no attribute 'route'
This error goes away when I move the toplevel back directly to the request handler. I feel either flask doesn't work with this functionality, or I'm doing something wrong in how I'm using toplevel. My intention is for each of my request handlers within my application to wait for all of my async Google DataStore calls to finish before exiting (I'm using yield statements and tasklets within my request handlers).
Upvotes: 0
Views: 179
Reputation: 39824
The error is kind of expected: app
is no longer the Flask app you created. I see 2 options to try:
rename the top level app (you need to match the change in the app.yaml
config file as well):
app = Flask(__name__)
app.config.update(DEBUG = not SERVER_ISPRODUCTION)
my_app = ndb.toplevel(app) # change .app -> .my_app app.yaml
rename the flask app and all its references:
flask_app = Flask(__name__)
flask_app.config.update(DEBUG = not SERVER_ISPRODUCTION)
app = ndb.toplevel(flask_app)
...
@flask_app.route('/test')
def testBackfill(): **strong text**
Note: I'm not a Flask user, this may fix the missing route
attribute error but I don't know if it will ultimately make the top level stuff work. But I can't write this as a comment.
Upvotes: 0