我使用Flask构建了一个带有REST API的Web应用程序。我利用Flask的g
来保存当前用户并从数据存储中提取我想要的用户数据(该应用程序托管在Google Cloud上)。但是,我想实施Google Cloud Endpoints,因为它具有一些优势,但如果我在Cloud Endpoints中调用其中一个网址,则会收到错误消息:
Traceback (most recent call last):
File "/Users/manuelgodoy/Documents/Google/google-cloud-sdk/platform/google_appengine/google/appengine/runtime/wsgi.py", line 239, in Handle
handler = _config_handle.add_wsgi_middleware(self._LoadHandler())
File "/Users/manuelgodoy/Documents/Google/google-cloud-sdk/platform/google_appengine/google/appengine/runtime/wsgi.py", line 298, in _LoadHandler
handler, path, err = LoadObject(self._handler)
File "/Users/manuelgodoy/Documents/Google/google-cloud-sdk/platform/google_appengine/google/appengine/runtime/wsgi.py", line 95, in LoadObject
__import__(cumulative_path)
File "/Users/manuelgodoy/Projects/Eatsy/Eatsy/src/application/apis.py", line 18, in <module>
user = g.user
File "/Users/manuelgodoy/Projects/Eatsy/Eatsy/src/lib/werkzeug/local.py", line 338, in __getattr__
return getattr(self._get_current_object(), name)
File "/Users/manuelgodoy/Projects/Eatsy/Eatsy/src/lib/werkzeug/local.py", line 297, in _get_current_object
return self.__local()
File "/Users/manuelgodoy/Projects/Eatsy/Eatsy/src/lib/flask/globals.py", line 27, in _lookup_app_object
raise RuntimeError('working outside of application context')
RuntimeError: working outside of application context
如何为云端点使用烧瓶的上下文变量,如g
,login_required
,current_user
等?
在我的代码中,我将current_user
存储在g.user
中,并且我有一个端点,我可以获得g.user
,因此我可以获取ID。
from flask.ext.login import login_user, logout_user, current_user, login_required
from flask import session, g, request
import requests
@app.before_request
def before_request():
log.info('Received request: %s' % request.path)
g.user = current_user
@app.route('/recommendations', methods = ['GET'])
def recommendations_retrieve():
# This HTTP call is what I'd like to get rid off
app_url = request.url_root
usr_id = g.user.key().id()
d = {'id': str(usr_id)}
r = requests.get(urljoin(app_url,"/_ah/api/myapp/v1/recommendations"),
params = d)
return (r.text, r.status_code, r.headers.items())
My Cloud Endpoints文件如下所示:
from views import g
@endpoints.api(name='myapp', version='v1', description='myapp API',
allowed_client_ids=[WEB_CLIENT_ID, endpoints.API_EXPLORER_CLIENT_ID])
class MyAppApi(remote.Service):
@endpoints.method(IdRequestMessage, RecommendationsResponseMessage,
path='recommendations', http_method='GET',
name='recommendations.recommendations')
def recommendations(self, request):
# I would prefer to use this, but I get the
# "Working outside the app context" error
# when I uncomment it
#user = User.get_by_id(g.user.key().id())
user = User.get_from_message(request)
response = user.get_recommendations()
return response
我的Javascript功能如下:
loadRecommendationsFromServer: function() {
$.ajax({
// This is how I *would* call it, if it worked
//url: this.props.url+"/_ah/api/myapp/v1/recommendations",
//data: JSON.stringify({'id':2}),
url: this.props.url+"/recommendations",
dataType: 'json',
success: function(data) {
this.setState({data: data.recommendations});
}.bind(this),
error: function(xhr, status, err) {
console.error(this.props.url, status, err.toString());
}.bind(this)
});
现有代码有效 - 如何避免在我的视图处理程序中发出HTTP请求,并在使用RuntimeError
时避免MyAppApi
服务中的g.user
?