2. Python back-end
In my application I store feeds information in the Google App Engine datastore. The App Engine datastore is not a relational database, yet it uses a SQL-like query language called GQL, where data objects called entities replace tables.
2.1 The main Python script handler main.py
Again I used a Google AJAX API and unsurprisingly it requires JSON parsing with simplejson. The ingredients present in “Flex Search on Google App Engine” I discussed last time are also present:
- a webapp RequestHandler called FeedRequestHandler
- a navigation page template configuration class by the name of MainPage
- a main function that runs the WSGIApplication
The UML diagram in Figure 3 is a bit different than the typical Java class diagram. First, the return type was made up, because the return type does not need to be specified in Python. Second, in the Python method signature you have self, which can be seen as a parameter. I left it out of the diagram, because I felt it did not belong there. Finally, there is the main function, which is not part of any of the classes so I left it out as well. But, there are also similarities. In Google App Engine you extend the RequestHandler classes, whereas in Java servlets you extend HTTPServlet. In addition certain methods are linked to GET and POST requests – doPost and doGet for HTTPServlet, post and get for RequestHandler.
Listing 9: The main Python script handler main.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 | from google.appengine.ext import webapp from google.appengine.ext.webapp.util import run_wsgi_app import os from google.appengine.ext.webapp import template import urllib from django.utils import simplejson from google.appengine.ext import db from net.ivanidris.flexreader import Feed from google.appengine.api import urlfetch import logging import cgi class FeedRequestHandler(webapp.RequestHandler): def post(self): self.printOutput() def encode(self, s): return urllib.quote_plus(s) def getQuery(self): feeds = db.GqlQuery("SELECT * from Feed") form = cgi.FieldStorage() feedLinks = simplejson.loads(urllib.unquote_plus(form.getfirst("feedLinks"))) for feed in feeds: query = feed.link if query not in feedLinks: return query if len(feedLinks) > 0: return feedLinks[0] else: return '' def printOutput(self): resultList = [] query = urllib.quote_plus(urllib.unquote(self.getQuery())) if query != '': url = "http://ajax.googleapis.com/ajax/services/feed/load?v=1.0&num=100&q=" + query result = urlfetch.fetch(url) if query != '' and result.status_code == 200: json = simplejson.loads(result.content.strip()) if json['responseStatus'] == 200: entriesList = [] for searchResult in json['responseData']['feed']['entries']: filteredDict = dict(title = searchResult['title'], url = searchResult['link'], content = searchResult['content']) entriesList.append(filteredDict) resultList.append(dict(feedLink = query)) resultList.append(dict(entries = entriesList)) logging.debug('resultList ' + str(resultList)) jsonString = simplejson.dumps( resultList ) self.response.out.write( jsonString.strip()) class MainPage(webapp.RequestHandler): def get(self): template_values = { 'reader_url': 'static/reader/FlexReader.html', 'reader_url_linktext': 'Reader', } path = os.path.join(os.path.dirname(__file__), 'nav.html') self.response.out.write(template.render(path, template_values)) application = webapp.WSGIApplication( [('/', MainPage), ('/feed', FeedRequestHandler)], debug=True) def main(): run_wsgi_app(application) if __name__ == "__main__": main() |
Recall from Listing 3 that a POST request was sent with URL /feed and parameter feedLinks. As you can see this URL is mapped in main.py to FeedRequestHandler. FeedRequestHandler has a post method, which processes HTTP POST requests. The post method resembles, as I already mentioned, the doPost method in Java servlets. Similarly, MainPage has a get method for GET requests. The JSON response format of feeds loading is different from that of web search. This makes reusing the JSON parsing part of my Python code difficult. Fortunately, the parsing code only consists of a few lines. The simplejson module from Django is again used for parsing. The simplejson loads and dumps method execute the JSON decoding and encoding. FeedRequestHandler sends back a filtered summary of the search result in the JSON format, containing the titles and urls of the found feeds.
1 2 3 4 5 6 7 8 9 10 11 | {"responseData": {"feed": {"title":"Ivan Idris Blog", "link":"http://ivanidris.net/wordpress", "author":"", "description":"Just another WordPress weblog", "type":"rss20", "entries": [{"title":"Flex Search on Google App Engine", "link":"http://feedproxy.google.com/~r/IvanIdrisBlog/~3/4qQGogdYzeQ/flex-search-on-google-app-engine", ... |
JSON format of the feed load response
Except for the different JSON format, there is one major difference, the datastore. The only method that interacts with the Google App Engine datastore is getQuery. It takes the value of the feedLinks parameter sent in the request. getQuery checks whether the feed we are querying for is already in the datastore.
More From ivanidris
ivanidris Recommends
- Seven Characteristics of Stepper Motors | Solder In The Veins (Solder In The Veins)
- 10 Questions with Facebook Research Engineer – Andrei Alexandrescu (Server-Side Magazine)

