Skip to content

Custom proxy on App Engine

Jason Salas edited this page Jan 24, 2015 · 8 revisions

Caching & scaling

The key cog that makes Trending Time work is the custom proxy handler that I wrote in Python, hosted on Google App Engine. Maybe at some point this will be a RESTful API using Cloud Endpoints, but it works wonderfully for now - high performance and beautiful scalability.

It uses memcache to store data that's fetched from Twitter's /trends/place API, using the Temboo Library for Twitter. This is a pattern I've advocated for for a long time. Because I've only got a finite number of monthly calls to Temboo with their freemium plan, minimizing the number of requests users make as more people download/install Trending Time is critical. This could very easily get out of hand and max-out my quota, leading to negative ratings in Google Play and unhappy users. So, my proxy sits between Temboo and the user.

The memcache'd entry expires every 57 minutes, at which point the next request rehydrates the cache with fresh data from Twitter.

In Trending Time's mobile module, a configuration activity enables/disables an AlarmManager that once an hour calls the proxy's URL. This meams for people running the app constantly, it'll only ever make 24 API calls day. Since the payload returned from he proxy is ~100 bytes, and with App Engine allotting 1 GB of daily bandwidth, Trending Time could reasonably facilitate about 419,000 installations per day before reaching capacity for API calls.


Code

    `def get(self):
	if memcache.get("cached_trends") is None:
		memcache.add(key="cached_trends", value=self.get_twitter_trending_topics(), time=3420)
	
	self.response.out.write(memcache.get("cached_trends"))

def get_twitter_trending_topics(self):
	# Create a session with your Temboo account details
	session = TembooSession(<TEMBOO_USER_ID>, <TEMBOO_APP_NAME>, <TEMBOO_APP_KEY>)

	# Instantiate the Choreo
	placeChoreo = Place(session)

	# Get an InputSet object for the Choreo
	placeInputs = placeChoreo.new_input_set()

	# Set the Choreo inputs
	placeInputs.set_AccessToken(<ACCESS_TOKEN>)
	placeInputs.set_ID(<REGION_ID>)
	placeInputs.set_AccessTokenSecret(<ACCESS_TOKEN_SECRET>)
	placeInputs.set_ConsumerSecret(<CONSUMER_SECRET>)
	placeInputs.set_ConsumerKey(<CONSUMER_KEY>)

	TWITTER_JSON = placeChoreo.execute_with_results(placeInputs)

	data = json.loads(TWITTER_JSON.get_Response())
	response_trends = ""
	for trend in data[0]["trends"][:5]:
		response_trends += (trend["name"] + ";")	
	return response_trends		
   application = webapp2.WSGIApplication([ ("/", TwitterTrendsProxyHandler), ], debug=False)`

Clone this wiki locally