Move from using API key to userIp in making discovery requests.

Reviewed in http://codereview.appspot.com/5031048/
diff --git a/apiclient/discovery.py b/apiclient/discovery.py
index ee1ae54..7cb4852 100644
--- a/apiclient/discovery.py
+++ b/apiclient/discovery.py
@@ -155,7 +155,14 @@
     http = httplib2.Http()
 
   requested_url = uritemplate.expand(discoveryServiceUrl, params)
-  requested_url = _add_query_parameter(requested_url, 'key', developerKey)
+
+  # REMOTE_ADDR is defined by the CGI spec [RFC3875] as the environment variable
+  # that contains the network address of the client sending the request. If it
+  # exists then add that to the request for the discovery document to avoid
+  # exceeding the quota on discovery requests.
+  if 'REMOTE_ADDR' in os.environ:
+    requested_url = _add_query_parameter(requested_url, 'userIp',
+                                         os.environ['REMOTE_ADDR'])
   logging.info('URL being requested: %s' % requested_url)
 
   resp, content = http.request(requested_url)
diff --git a/samples/api-python-client-doc/main.py b/samples/api-python-client-doc/main.py
index 9aabde5..3ab0bb5 100755
--- a/samples/api-python-client-doc/main.py
+++ b/samples/api-python-client-doc/main.py
@@ -38,14 +38,26 @@
 from google.appengine.ext.webapp import util
 
 
+DISCOVERY_URI = 'https://www.googleapis.com/discovery/v1/apis?preferred=true'
+
+
+def get_directory_doc():
+  http = httplib2.Http(memcache)
+  ip = os.environ.get('REMOTE_ADDR', None)
+  uri = DISCOVERY_URI
+  if ip:
+    uri += ('&userIp=' + ip)
+  resp, content = http.request(uri)
+  directory = simplejson.loads(content)['items']
+  return directory
+
+
 class MainHandler(webapp.RequestHandler):
   """Handles serving the main landing page.
   """
 
   def get(self):
-    http = httplib2.Http(memcache)
-    resp, content = http.request('https://www.googleapis.com/discovery/v1/apis?preferred=true')
-    directory = simplejson.loads(content)['items']
+    directory = get_directory_doc()
     for item in directory:
       item['title'] = item.get('title', item.get('description', ''))
     path = os.path.join(os.path.dirname(__file__), 'index.html')
@@ -60,9 +72,7 @@
   """
 
   def get(self):
-    http = httplib2.Http(memcache)
-    resp, content = http.request('https://www.googleapis.com/discovery/v1/apis?preferred=true')
-    directory = simplejson.loads(content)['items']
+    directory = get_directory_doc()
     for item in directory:
       item['title'] = item.get('title', item.get('description', ''))
     path = os.path.join(os.path.dirname(__file__), 'gadget.html')
@@ -86,7 +96,8 @@
   """
 
   def get(self, service_name, version, collection):
-    resource = discovery.build(service_name, version)
+    http = httplib2.Http(memcache)
+    resource = discovery.build(service_name, version, http=http)
     # descend the object path
     if collection:
       path = collection.split('/')
diff --git a/tests/test_discovery.py b/tests/test_discovery.py
index 5c7045e..71ca0fb 100644
--- a/tests/test_discovery.py
+++ b/tests/test_discovery.py
@@ -23,6 +23,7 @@
 
 __author__ = 'jcgregorio@google.com (Joe Gregorio)'
 
+import copy
 import httplib2
 import os
 import unittest
@@ -83,10 +84,16 @@
 
 
 class DiscoveryFromHttp(unittest.TestCase):
+  def setUp(self):
+    self.old_environ = copy.copy(os.environ)
 
-  def test_api_key_is_added_to_discovery_uri(self):
+  def tearDown(self):
+    os.environ = self.old_environ
+
+  def test_userip_is_added_to_discovery_uri(self):
     # build() will raise an HttpError on a 400, use this to pick the request uri
     # out of the raised exception.
+    os.environ['REMOTE_ADDR'] = '10.0.0.1'
     try:
       http = HttpMockSequence([
         ({'status': '400'}, file(datafile('zoo.json'), 'r').read()),
@@ -95,9 +102,9 @@
                   discoveryServiceUrl='http://example.com')
       self.fail('Should have raised an exception.')
     except HttpError, e:
-      self.assertEqual(e.uri, 'http://example.com?key=foo')
+      self.assertEqual(e.uri, 'http://example.com?userIp=10.0.0.1')
 
-  def test_api_key_of_none_is_not_added_to_discovery_uri(self):
+  def test_userip_missing_is_not_added_to_discovery_uri(self):
     # build() will raise an HttpError on a 400, use this to pick the request uri
     # out of the raised exception.
     try: