Мне было интересно, можно ли использовать remote_api_stub из скрипта, работающего на локальном dev_appserver.py.
Мне удалось успешно подключиться к хранилищу данных разработки/производства через remote_api_stub из базового сценария, который запускается из командной строки, поэтому я вполне уверен, что app.yaml настроен правильно.
Если бы я хотел найти список объектов User с моего локального сервера разработки, я мог бы просто настроить заглушку для подключения к локальному серверу, а затем, как обычно, получить модели ndb.
DEV_HOSTNAME = 'localhost'
DEV_PORT = '54256'
DEV_SERVER = '%s:%s' % (DEV_HOSTNAME, DEV_PORT)
DEV_PATH = '/_ah/remote_api'
DEV_SECURE = False
remote_api_stub.ConfigureRemoteApiForOAuth(DEV_SERVER, DEV_PATH, secure=DEV_SECURE)
users = User.query()
# at this point users will contain data from the DEVELOPMENT server
Если бы я хотел найти список объектов User с рабочего сервера, мне просто нужно было бы изменить некоторые пути
PROD_SERVER = 'myappid.appspot.com'
PROD_PATH = '/_ah/remote_api'
PROD_SECURE = True
remote_api_stub.ConfigureRemoteApiForOAuth(PROD_SERVER, PROD_PATH, secure=PROD_SECURE)
users = User.query()
# at this point users will contain data from the PRODUCTION server
Оба они работают, как и ожидалось, и вернут мне правильные данные.
Проблема начинается, когда я пытаюсь настроить remote_api_sub внутри любого фрагмента кода, который на самом деле работает в экземпляре dev_appserver.py.
Например, если я попытаюсь настроить заглушку для любого базового обработчика запросов, я столкнусь с некоторыми проблемами.
Если я использую remote_api_stub.ConfigureRemoteApiForOAuth с теми же параметрами, что и раньше, я получаю ошибку NotSupportedOnThisPlatform.
INFO 2016-08-30 22:01:40,362 module.py:787] admin: "GET /_ah/start HTTP/1.1" 404 52
INFO 2016-08-30 22:01:47,342 client.py:539] Attempting refresh to obtain initial access_token
INFO 2016-08-30 22:01:47,461 client.py:797] Refreshing access_token
ERROR 2016-08-30 22:01:47,607 webapp2.py:1552]
Traceback (most recent call last):
File "/path/google_appengine/lib/webapp2-2.5.2/webapp2.py", line 1535, in __call__
rv = self.handle_exception(request, response, e)
File "/path/google_appengine/lib/webapp2-2.5.2/webapp2.py", line 1529, in __call__
rv = self.router.dispatch(request, response)
File "/path/google_appengine/lib/webapp2-2.5.2/webapp2.py", line 1278, in default_dispatcher
return route.handler_adapter(request, response)
File "/path/google_appengine/lib/webapp2-2.5.2/webapp2.py", line 1102, in __call__
return handler.dispatch()
File "/path/google_appengine/lib/webapp2-2.5.2/webapp2.py", line 572, in dispatch
return self.handle_exception(e, self.app.debug)
File "/path/google_appengine/lib/webapp2-2.5.2/webapp2.py", line 570, in dispatch
return method(*args, **kwargs)
File "/path/app/admin/controllers/controller.py", line 156, in get
remote_api_stub.ConfigureRemoteApiForOAuth(PROD_SERVER, PROD_PATH, secure=PROD_SECURE)
File "/path/google_appengine/google/appengine/ext/remote_api/remote_api_stub.py", line 768, in ConfigureRemoteApiForOAuth
rpc_server_factory=rpc_server_factory)
File "/path/google_appengine/google/appengine/ext/remote_api/remote_api_stub.py", line 835, in ConfigureRemoteApi
app_id = GetRemoteAppIdFromServer(server, path, rtok)
File "/path/google_appengine/google/appengine/ext/remote_api/remote_api_stub.py", line 569, in GetRemoteAppIdFromServer
response = server.Send(path, payload=None, **urlargs)
File "/path/google_appengine/google/appengine/tools/appengine_rpc_httplib2.py", line 247, in Send
url, method=method, body=payload, headers=headers)
File "/path/google_appengine/lib/oauth2client/oauth2client/client.py", line 562, in new_request
redirections, connection_type)
File "/path/google_appengine/lib/httplib2/httplib2/__init__.py", line 1464, in request
self.disable_ssl_certificate_validation)
File "/path/google_appengine/lib/httplib2/httplib2/__init__.py", line 1143, in __init__
strict, timeout, proxy_info, ca_certs, disable_ssl_certificate_validation)
File "/path/google_appengine/lib/httplib2/httplib2/__init__.py", line 1092, in __init__
raise NotSupportedOnThisPlatform()
NotSupportedOnThisPlatform
INFO 2016-08-30 22:01:47,612 module.py:787] admin: "GET /controller1 HTTP/1.1" 500 2937
Итак, я продолжил поиск и нашел очень похожий вопрос и ответ: здесь
Однако похоже, что они используют remote_api_stub.ConfigureRemoteApi вместо remote_api_stub.ConfigureRemoteApiForOAuth.
Когда я пытаюсь использовать
remote_api_stub.ConfigureRemoteApi(app_id=None, path='/_ah/remote_api',
auth_func=lambda: ('myemail', 'mypass'),
servername='myappid.appspot.com')
я получил
ERROR 2016-08-30 22:06:58,652 webapp2.py:1552] HTTP Error 404: Not Found
Traceback (most recent call last):
File "/path/google_appengine/lib/webapp2-2.5.2/webapp2.py", line 1535, in __call__
rv = self.handle_exception(request, response, e)
File "/path/google_appengine/lib/webapp2-2.5.2/webapp2.py", line 1529, in __call__
rv = self.router.dispatch(request, response)
File "/path/google_appengine/lib/webapp2-2.5.2/webapp2.py", line 1278, in default_dispatcher
return route.handler_adapter(request, response)
File "/path/google_appengine/lib/webapp2-2.5.2/webapp2.py", line 1102, in __call__
return handler.dispatch()
File "/path/google_appengine/lib/webapp2-2.5.2/webapp2.py", line 572, in dispatch
return self.handle_exception(e, self.app.debug)
File "/path/google_appengine/lib/webapp2-2.5.2/webapp2.py", line 570, in dispatch
return method(*args, **kwargs)
File "/path/app/admin/controllers/controller.py", line 154, in get
servername='myappid.appspot.com')
File "/path/google_appengine/google/appengine/ext/remote_api/remote_api_stub.py", line 835, in ConfigureRemoteApi
app_id = GetRemoteAppIdFromServer(server, path, rtok)
File "/path/google_appengine/google/appengine/ext/remote_api/remote_api_stub.py", line 569, in GetRemoteAppIdFromServer
response = server.Send(path, payload=None, **urlargs)
File "/path/google_appengine/google/appengine/tools/appengine_rpc.py", line 409, in Send
self._Authenticate()
File "/path/google_appengine/google/appengine/tools/appengine_rpc.py", line 555, in _Authenticate
super(HttpRpcServer, self)._Authenticate()
File "/path/google_appengine/google/appengine/tools/appengine_rpc.py", line 293, in _Authenticate
auth_token = self._GetAuthToken(credentials[0], credentials[1])
File "/path/google_appengine/google/appengine/tools/appengine_rpc.py", line 232, in _GetAuthToken
response = self.opener.open(req)
File "/usr/lib/python2.7/urllib2.py", line 410, in open
response = meth(req, response)
File "/usr/lib/python2.7/urllib2.py", line 523, in http_response
'http', request, response, code, msg, hdrs)
File "/usr/lib/python2.7/urllib2.py", line 448, in error
return self._call_chain(*args)
File "/usr/lib/python2.7/urllib2.py", line 382, in _call_chain
result = func(*args)
File "/usr/lib/python2.7/urllib2.py", line 531, in http_error_default
raise HTTPError(req.get_full_url(), code, msg, hdrs, fp)
HTTPError: HTTP Error 404: Not Found
INFO 2016-08-30 22:06:58,656 module.py:787] admin: "GET /controller1 HTTP/1.1" 500 3129
Если я попытаюсь использовать (установив app_id самостоятельно)
remote_api_stub.ConfigureRemoteApi(app_id=myappid, path='/_ah/remote_api',
auth_func=lambda: ('myemail', 'mypass'),
servername='myappid.appspot.com')
Я получаю ту же ошибку HTTP 404, что и раньше
Что касается комбинации электронной почты и пароля, которую следует использовать, когда не используется OAuth, я пробовал использовать имя пользователя и пароль, которые владеют приложением, и это, похоже, не сработало.
Мне пришлось настроить учетную запись службы с секретным ключом, чтобы командная строка ConfigureRemoveApiForOAuth работала. Мне было интересно использовать этот адрес электронной почты [email protected]
, но я не был уверен, каким будет пароль, поэтому решил, что он, вероятно, неверен.
Я также попытался настроить remote_api_stub внутри appengine_config.py, а не в отдельных обработчиках, и все проблемы одинаковы.
Я также пробовал это как с vm: true, так и без в app.yaml, и, похоже, это не имеет значения.
Подводя итог: можно ли использовать remote_api_stub для подключения к хранилищу данных движка приложений Google из кода в самом приложении Google? Я уже могу получить доступ к хранилищам данных из ВНЕ приложения, но любой код, работающий внутри, похоже, не работает.
Спасибо
редактировать: рассматриваемая учетная запись имеет «разрешить менее безопасным приложениям входить в систему или любой другой параметр, который в Google установлен на ON»