尝试使用oauth
&列表来列出Google电子表格Google Appengine中的GData
。但是我得到了以下错误。我的代码有什么问题吗?
请告知。
File "/home/RKS/Appengine/test/main.py", line 99, in get
feed = client.get_spreadsheets()
File "/home/RKS/Appengine/test/gdata/spreadsheets/client.py", line 78, in get_spreadsheets
desired_class=desired_class, **kwargs)
File "/home/RKS/Appengine/test/gdata/client.py", line 640, in get_feed
**kwargs)
File "/home/RKS/Appengine/test/gdata/client.py", line 278, in request
version=get_xml_version(self.api_version))
File "/home/RKS/Appengine/test/atom/core.py", line 520, in parse
tree = ElementTree.fromstring(xml_string)
File "<string>", line 125, in XML
ParseError: no element found: line 1, column 0
代码:
#!/usr/bin/env python
import webapp2
import logging
from google.appengine.api import users
import gdata.auth
import gdata.gauth
import gdata.client
import gdata.service
import gdata.spreadsheets
import gdata.spreadsheets.client
import gdata.spreadsheets.data
SETTINGS = {
'APP_NAME': 'hidden', # intentionally hidden
'CONSUMER_KEY': 'hidden',
'CONSUMER_SECRET': 'hidden',
'SCOPES': ['https://spreadsheets.google.com/feeds'],
'CALLBACK_URL': '',
'SIG_METHOD': gdata.auth.OAuthSignatureMethod.HMAC_SHA1
}
class FetchToken(webapp2.RequestHandler):
def get(self):
current_uid = users.get_current_user().user_id()
if isinstance(gdata.gauth.AeLoad(current_uid), gdata.gauth.OAuthHmacToken):
# the user has gone through the process before
self.redirect('/')
else:
# the user has not gone through this process, or the authorization has expired or been revoked.
SETTINGS['CALLBACK_URL'] = 'http://%s/HandleOAuthCallback' % self.request.host
client = gdata.client.GDClient()
request_token = client.GetOAuthToken(
SETTINGS['SCOPES'],
SETTINGS['CALLBACK_URL'],
SETTINGS['CONSUMER_KEY'],
consumer_secret=SETTINGS['CONSUMER_SECRET'])
gdata.gauth.AeSave(request_token, current_uid)
self.redirect(str(request_token.generate_authorization_url()))
class HandleOAuthCallback(webapp2.RequestHandler):
def get(self):
current_uid = users.get_current_user().user_id()
client = gdata.client.GDClient()
saved_request_token = gdata.gauth.AeLoad(current_uid)
request_token = gdata.gauth.AuthorizeRequestToken(saved_request_token, self.request.uri)
access_token = client.GetAccessToken(request_token)
gdata.gauth.AeSave(access_token, current_uid)
self.redirect('/')
class GetDocsList(webapp2.RequestHandler):
def get(self):
if not users.get_current_user():
self.redirect(users.create_login_url('/'))
else:
current_uid = users.get_current_user().user_id()
if isinstance(gdata.gauth.AeLoad(current_uid), gdata.gauth.OAuthHmacToken):
# the user has gone through the process before
access_token = gdata.gauth.AeLoad(current_uid)
client = gdata.service.GDataService()
oauth_input_params = gdata.auth.OAuthInputParams(
gdata.auth.OAuthSignatureMethod.HMAC_SHA1,
SETTINGS['CONSUMER_KEY'],
SETTINGS['CONSUMER_SECRET']) # consumer_secret=
oauth_token = gdata.auth.OAuthToken(
key=access_token.token,
secret=access_token.token_secret,
scopes=SETTINGS['SCOPES'],
oauth_input_params=oauth_input_params)
client.SetOAuthToken(oauth_token)
client = gdata.spreadsheets.client.SpreadsheetsClient()
feed = client.get_spreadsheets()
else:
self.redirect('/FetchToken')
app = webapp2.WSGIApplication([('/HandleOAuthCallback', HandleOAuthCallback), ('/', GetDocsList), ('/FetchToken', FetchToken)], debug=False)
答案 0 :(得分:0)
我建议切换到OAuth2,我的大部分答案将解释如何通过这样做来解决您的问题。但是,在尝试切换到OAuth2之前,我建议您尝试这一行更改,这可能是您问题的快速解决方案。我要尝试的第一件事是向客户端添加标题,如下所示。
client.additional_headers = {
'Authorization': 'Bearer %s' % access_token,
}
我有一个使用GData电子表格API和OAuth2的应用程序,并添加该标头是必要的。如果我拿出那个标题,我会得到一个像你描述的错误。
现在,回答: 在App Engine中使用OAuth2执行您尝试执行的操作甚至比您已经完成的操作更简单。以下是它的完成方式。
首先创建一个OAuth2装饰器。 (我将在答案结尾处描述在何处创建客户端ID和客户端密码。)
from oauth2client.appengine import OAuth2Decorator
GlobalOAuth2Decorator = OAuth2Decorator(
client_id=OAUTH2_CLIENT_ID,
client_secret=OAUTH2_CLIENT_SECRET,
scope='https://spreadsheets.google.com/feeds',
)
然后在创建请求处理程序时使用此装饰器。
class SpreadsheetHandler(webapp2.RequestHandler):
@GlobalOAuth2Decorator.oauth_required
def get(self):
client = gdata.spreadsheet.service.SpreadsheetsService()
client.additional_headers = {
'Authorization': 'Bearer %s' % GlobalOAuth2Decorator.credentials.access_token,
}
请注意,我使用SpreadsheetsService而不是SpreadsheetsClient。这对我来说很有用,虽然我没有尝试过SpreadsheetsClient(客户端实际上可能更容易使用)。
创建此client
对象后,您可以根据需要使用它来读取和编写电子表格。例如,sheets = client.GetSpreadsheetsFeeds()
会为您提供可以访问的电子表格列表。
最后,确保在创建应用程序时在您的处理程序列表中包含OAuth处理程序:
app = webapp2.WSGIApplication([..., (GlobalOAuth2Decorator.callback_path, GlobalOAuth2Decorator.callback_handler())]
要使OAuth2正常工作,您必须在https://console.developers.google.com转到开发人员控制台,然后1)从“凭据”菜单中选择您的应用,2)创建新的客户端ID(这将生成客户端ID和您的秘密),3)从同意屏幕菜单中为您的应用程序提供一个电子邮件地址和名称。