Hi Jose, This is a known incompatibility in App Engine. The GData APIs send an absolute URL to the httplib library where it expects a relative one (since the host and port was specified in the constructor); the Python httplib handles this properly, but the App Engine replacement currently does not.
-Nick Johnson On Fri, May 15, 2009 at 7:32 PM, Jose Vidal <[email protected]> wrote: > > I am trying to read a spreadsheet from app engine using text_db and > authsub. > > I read http://code.google.com/appengine/articles/gdata.html and got it > to work. Then I read > http://code.google.com/p/gdata-python-client/wiki/AuthSubWithTextDB > and I tried to merge the two in the file below (step4.py) but when I > run it locally I get: > > Traceback (most recent call last): > File "/home/jmvidal/share/progs/googleapps/google_appengine/google/ > appengine/ext/webapp/__init__.py", line 498, in __call__ > handler.get(*groups) > File "/home/jmvidal/share/progs/googleapps/google_appengine/ > glassboard/step4.py", line 56, in get > session_token = client._GetDocsClient().UpgradeToSessionToken > (auth_token) #If I don't pass this argument I get a NonAuthSubToken > File "/home/jmvidal/share/progs/googleapps/google_appengine/ > glassboard/gdata/service.py", line 866, in UpgradeToSessionToken > self.SetAuthSubToken(self.upgrade_to_session_token(token)) > File "/home/jmvidal/share/progs/googleapps/google_appengine/ > glassboard/gdata/service.py", line 885, in upgrade_to_session_token > headers={'Content-Type':'application/x-www-form-urlencoded'}) > File "/home/jmvidal/share/progs/googleapps/google_appengine/ > glassboard/gdata/auth.py", line 678, in perform_request > return http_client.request(operation, url, data=data, > headers=headers) > File "/home/jmvidal/share/progs/googleapps/google_appengine/ > glassboard/atom/http.py", line 163, in request > return connection.getresponse() > File "/home/jmvidal/share/progs/googleapps/google_appengine/google/ > appengine/dist/httplib.py", line 200, in getresponse > self._allow_truncated, self._follow_redirects) > File "/home/jmvidal/share/progs/googleapps/google_appengine/google/ > appengine/api/urlfetch.py", line 267, in fetch > raise DownloadError(str(e)) > DownloadError: ApplicationError: 2 nonnumeric port: '' > > Can anyone shed some light on this? > > > # step4.py > # > # Trying to read spreadsheets from app engine using text_db and > authsub. > # > # Merge of this code > # http://code.google.com/p/gdata-python-client/wiki/AuthSubWithTextDB > # with this one > # http://code.google.com/appengine/articles/gdata.html (step 3) > > import wsgiref.handlers > import cgi > from google.appengine.ext import webapp > from google.appengine.api import users > import atom.url > import gdata.service > import gdata.alt.appengine > import gdata.spreadsheet.text_db > import settings > > > class Fetcher(webapp.RequestHandler): > > def get(self): > # Write our pages title > self.response.out.write("""<html><head><title> > Google Data Feed Fetcher: read Google Data API Atom feeds</ > title>""") > self.response.out.write('</head><body>') > next_url = atom.url.Url('http', settings.HOST_NAME, path='/step4') > # Allow the user to sign in or sign out > if users.get_current_user(): > self.response.out.write('<a href="%s">Sign Out</a><br>' % ( > users.create_logout_url(str(next_url)))) > else: > self.response.out.write('<a href="%s">Sign In</a><br>' % ( > users.create_login_url(str(next_url)))) > > # Initialize a client to talk to Google Data API services. > # client = gdata.service.GDataService() > # auth_url = client.GenerateAuthSubURL( > # next_url, > # ('http://docs.google.com/feeds/',), secure=False, session=True) > > client = gdata.spreadsheet.text_db.DatabaseClient() > auth_url = client._GetDocsClient().GenerateAuthSubURL( > next_url, > ('http://spreadsheets.google.com/feeds/','http://docs.google.com/ > feeds/documents/'), secure=False, session=True) > > gdata.alt.appengine.run_on_appengine(client) > > feed_url = self.request.get('feed_url') > > session_token = None > # Find the AuthSub token and upgrade it to a session token. > auth_token = gdata.auth.extract_auth_sub_token_from_url > (self.request.uri) > if auth_token: > # Upgrade the single-use AuthSub token to a multi-use session > token. > client._GetDocsClient().SetAuthSubToken(auth_token) > session_token = client._GetDocsClient().UpgradeToSessionToken > (auth_token) #If I don't pass this argument I get a NonAuthSubToken > client._GetSpreadsheetsClient().SetAuthSubToken > (client._GetDocsClient().GetAuthSubToken()) > # session_token = client.upgrade_to_session_token(auth_token) > if session_token and users.get_current_user(): > # If there is a current user, store the token in the datastore > and > # associate it with the current user. Since we told the client > to > # run_on_appengine, the add_token call will automatically store > the > # session token if there is a current_user. > client.token_store.add_token(session_token) > elif session_token: > # Since there is no current user, we will put the session token > # in a property of the client. We will not store the token in > the > # datastore, since we wouldn't know which user it belongs to. > # Since a new client object is created with each get call, we > don't > # need to worry about the anonymous token being used by other > users. > client.current_token = session_token > > self.response.out.write('<div id="main">') > self.fetch_feed(client, feed_url) > self.response.out.write('</div>') > self.response.out.write( > '<div id="sidebar"><div id="scopes"><h4>Request a token</ > h4><ul>') > self.response.out.write('<li><a href="%s">Google Documents</a></ > li>' % (auth_url)) > self.response.out.write('</ul></div><br/><div id="tokens">') > > def fetch_feed(self, client, feed_url): > # Attempt to fetch the feed. > if not feed_url: > self.response.out.write( > 'No feed_url was specified for the app to fetch.<br/>') > example_url = atom.url.Url('http', settings.HOST_NAME, path='/ > step4', > params={'feed_url': > 'http://docs.google.com/feeds/documents/private/full'} > ).to_string() > self.response.out.write('Here\'s an example query which will > show the' > ' XML for the feed listing your Google Documents <a ' > 'href="%s">%s</a>' % (example_url, example_url)) > return > try: > response = client.Get(feed_url, converter=str) > self.response.out.write(cgi.escape(response)) > except gdata.service.RequestError, request_error: > # If fetching fails, then tell the user that they need to login > to > # authorize this app by logging in at the following URL. > if request_error[0]['status'] == 401: > # Get the URL of the current page so that our AuthSub request > will > # send the user back to here. > next = atom.url.Url('http', settings.HOST_NAME, path='/step4', > params={'feed_url': feed_url}) > # If there is a current user, we can request a session token, > otherwise > # we should ask for a single use token. > auth_sub_url = client.GenerateAuthSubURL(next, feed_url, > secure=False, session=True) > self.response.out.write('<a href="%s">' % (auth_sub_url)) > self.response.out.write( > 'Click here to authorize this application to view the > feed</a>') > else: > self.response.out.write( > 'Something went wrong, here is the error object: %s ' % ( > str(request_error[0]))) > > > def main(): > application = webapp.WSGIApplication([('/.*', Fetcher),], > debug=True) > wsgiref.handlers.CGIHandler().run(application) > > > if __name__ == '__main__': > main() > > --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Google App Engine" group. To post to this group, send email to [email protected] To unsubscribe from this group, send email to [email protected] For more options, visit this group at http://groups.google.com/group/google-appengine?hl=en -~----------~----~----~----~------~----~------~--~---
