From c9e49e813e706619c89a021e3e9471e3985e9cdf Mon Sep 17 00:00:00 2001 From: Silvano Luciani Date: Wed, 1 Oct 2014 15:03:41 -0700 Subject: [PATCH 1/2] feat: add user agent to API requests --- gcloud/connection.py | 4 ++++ gcloud/datastore/connection.py | 1 + gcloud/datastore/test_connection.py | 16 ++++++++++++++++ gcloud/storage/connection.py | 2 ++ gcloud/storage/test_connection.py | 6 ++++++ 5 files changed, 29 insertions(+) diff --git a/gcloud/connection.py b/gcloud/connection.py index 7ecf47763ce0..003dbdfd2d12 100644 --- a/gcloud/connection.py +++ b/gcloud/connection.py @@ -1,3 +1,4 @@ +from pkg_resources import get_distribution import httplib2 @@ -17,6 +18,9 @@ class Connection(object): _EMPTY = object() """A pointer to represent an empty value for default arguments.""" + USER_AGENT = "gcloud-python/{0}".format(get_distribution('gcloud').version) + """The user agent for gcloud-python requests.""" + def __init__(self, credentials=None): """:type credentials: :class:`gcloud.credentials.Credentials` :param credentials: The OAuth2 Credentials to use for this connection. diff --git a/gcloud/datastore/connection.py b/gcloud/datastore/connection.py index fd5602577f97..3f0b05b88694 100644 --- a/gcloud/datastore/connection.py +++ b/gcloud/datastore/connection.py @@ -50,6 +50,7 @@ def _request(self, dataset_id, method, data): headers = { 'Content-Type': 'application/x-protobuf', 'Content-Length': str(len(data)), + 'User-Agent': self.USER_AGENT, } headers, content = self.http.request( uri=self.build_api_url(dataset_id=dataset_id, method=method), diff --git a/gcloud/datastore/test_connection.py b/gcloud/datastore/test_connection.py index c7c40f64c437..3d00d3a74196 100644 --- a/gcloud/datastore/test_connection.py +++ b/gcloud/datastore/test_connection.py @@ -65,6 +65,7 @@ def test__request_w_200(self): 'method': 'POST', 'headers': {'Content-Type': 'application/x-protobuf', 'Content-Length': '4', + 'User-Agent': conn.USER_AGENT, }, 'body': DATA, }) @@ -115,6 +116,7 @@ def FromString(cls, pb): 'method': 'POST', 'headers': {'Content-Type': 'application/x-protobuf', 'Content-Length': '5', + 'User-Agent': conn.USER_AGENT, }, 'body': b'REQPB', }) @@ -218,6 +220,7 @@ def test_begin_transaction_default_serialize(self): self.assertEqual(cw['headers'], {'Content-Type': 'application/x-protobuf', 'Content-Length': '2', + 'User-Agent': conn.USER_AGENT, }) rq_class = datastore_pb.BeginTransactionRequest request = rq_class() @@ -248,6 +251,7 @@ def test_begin_transaction_explicit_serialize(self): self.assertEqual(cw['headers'], {'Content-Type': 'application/x-protobuf', 'Content-Length': '2', + 'User-Agent': conn.USER_AGENT, }) rq_class = datastore_pb.BeginTransactionRequest request = rq_class() @@ -299,6 +303,7 @@ def id(self): self.assertEqual(cw['headers'], {'Content-Type': 'application/x-protobuf', 'Content-Length': '6', + 'User-Agent': conn.USER_AGENT, }) rq_class = datastore_pb.RollbackRequest request = rq_class() @@ -333,6 +338,7 @@ def test_run_query_wo_namespace_empty_result(self): self.assertEqual(cw['headers'], {'Content-Type': 'application/x-protobuf', 'Content-Length': '14', + 'User-Agent': conn.USER_AGENT, }) rq_class = datastore_pb.RunQueryRequest request = rq_class() @@ -369,6 +375,7 @@ def test_run_query_w_namespace_nonempty_result(self): self.assertEqual(cw['headers'], {'Content-Type': 'application/x-protobuf', 'Content-Length': '16', + 'User-Agent': conn.USER_AGENT, }) rq_class = datastore_pb.RunQueryRequest request = rq_class() @@ -401,6 +408,7 @@ def test_lookup_single_key_empty_response(self): self.assertEqual(cw['headers'], {'Content-Type': 'application/x-protobuf', 'Content-Length': '26', + 'User-Agent': conn.USER_AGENT, }) rq_class = datastore_pb.LookupRequest request = rq_class() @@ -439,6 +447,7 @@ def test_lookup_single_key_nonempty_response(self): self.assertEqual(cw['headers'], {'Content-Type': 'application/x-protobuf', 'Content-Length': '26', + 'User-Agent': conn.USER_AGENT, }) rq_class = datastore_pb.LookupRequest request = rq_class() @@ -474,6 +483,7 @@ def test_lookup_multiple_keys_empty_response(self): self.assertEqual(cw['headers'], {'Content-Type': 'application/x-protobuf', 'Content-Length': '52', + 'User-Agent': conn.USER_AGENT, }) rq_class = datastore_pb.LookupRequest request = rq_class() @@ -516,6 +526,7 @@ def test_commit_wo_transaction(self): self.assertEqual(cw['headers'], {'Content-Type': 'application/x-protobuf', 'Content-Length': '47', + 'User-Agent': conn.USER_AGENT, }) rq_class = datastore_pb.CommitRequest request = rq_class() @@ -561,6 +572,7 @@ def id(self): self.assertEqual(cw['headers'], {'Content-Type': 'application/x-protobuf', 'Content-Length': '53', + 'User-Agent': conn.USER_AGENT, }) rq_class = datastore_pb.CommitRequest request = rq_class() @@ -595,6 +607,7 @@ def test_save_entity_wo_transaction_w_upsert(self): self.assertEqual(cw['headers'], {'Content-Type': 'application/x-protobuf', 'Content-Length': '47', + 'User-Agent': conn.USER_AGENT, }) rq_class = datastore_pb.CommitRequest request = rq_class() @@ -645,6 +658,7 @@ def test_save_entity_wo_transaction_w_auto_id(self): self.assertEqual(cw['headers'], {'Content-Type': 'application/x-protobuf', 'Content-Length': '44', + 'User-Agent': conn.USER_AGENT, }) rq_class = datastore_pb.CommitRequest request = rq_class() @@ -720,6 +734,7 @@ def test_delete_entities_wo_transaction(self): self.assertEqual(cw['headers'], {'Content-Type': 'application/x-protobuf', 'Content-Length': '30', + 'User-Agent': conn.USER_AGENT, }) rq_class = datastore_pb.CommitRequest request = rq_class() @@ -791,6 +806,7 @@ def test_delete_entity_wo_transaction(self): self.assertEqual(cw['headers'], {'Content-Type': 'application/x-protobuf', 'Content-Length': '30', + 'User-Agent': conn.USER_AGENT, }) rq_class = datastore_pb.CommitRequest request = rq_class() diff --git a/gcloud/storage/connection.py b/gcloud/storage/connection.py index 7a426205b9d8..8f7817dc19b6 100644 --- a/gcloud/storage/connection.py +++ b/gcloud/storage/connection.py @@ -159,6 +159,8 @@ def make_request(self, method, url, data=None, content_type=None, if content_type: headers['Content-Type'] = content_type + headers['User-Agent'] = self.USER_AGENT + return self.http.request(uri=url, method=method, headers=headers, body=data) diff --git a/gcloud/storage/test_connection.py b/gcloud/storage/test_connection.py index 0fb2209bf136..213016af25c2 100644 --- a/gcloud/storage/test_connection.py +++ b/gcloud/storage/test_connection.py @@ -170,6 +170,7 @@ def test_make_request_no_data_no_content_type_no_headers(self): self.assertEqual(http._called_with['headers'], {'Accept-Encoding': 'gzip', 'Content-Length': 0, + 'User-Agent': conn.USER_AGENT, }) def test_make_request_w_data_no_extra_headers(self): @@ -189,6 +190,7 @@ def test_make_request_w_data_no_extra_headers(self): {'Accept-Encoding': 'gzip', 'Content-Length': 0, 'Content-Type': 'application/json', + 'User-Agent': conn.USER_AGENT, }) def test_make_request_w_extra_headers(self): @@ -208,6 +210,7 @@ def test_make_request_w_extra_headers(self): {'Accept-Encoding': 'gzip', 'Content-Length': 0, 'X-Foo': 'foo', + 'User-Agent': conn.USER_AGENT, }) def test_api_request_defaults(self): @@ -228,6 +231,7 @@ def test_api_request_defaults(self): self.assertEqual(http._called_with['headers'], {'Accept-Encoding': 'gzip', 'Content-Length': 0, + 'User-Agent': conn.USER_AGENT, }) def test_api_request_w_non_json_response(self): @@ -287,6 +291,7 @@ def test_api_request_w_query_params(self): self.assertEqual(http._called_with['headers'], {'Accept-Encoding': 'gzip', 'Content-Length': 0, + 'User-Agent': conn.USER_AGENT, }) def test_api_request_w_data(self): @@ -312,6 +317,7 @@ def test_api_request_w_data(self): {'Accept-Encoding': 'gzip', 'Content-Length': len(DATAJ), 'Content-Type': 'application/json', + 'User-Agent': conn.USER_AGENT, }) def test_api_request_w_404(self): From dca6f00ba8eac62fd59be9a7e82f5612316828dd Mon Sep 17 00:00:00 2001 From: Silvano Luciani Date: Wed, 1 Oct 2014 16:16:55 -0700 Subject: [PATCH 2/2] add test for user agent format also removed spurious empty line --- gcloud/test_connection.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/gcloud/test_connection.py b/gcloud/test_connection.py index 1e0ebb8f690f..1a9b274e91a5 100644 --- a/gcloud/test_connection.py +++ b/gcloud/test_connection.py @@ -43,3 +43,9 @@ def authorize(self, http): conn = self._makeOne(creds) self.assertTrue(conn.http is authorized) self.assertTrue(isinstance(creds._called_with, Http)) + + def test_user_agent_format(self): + from pkg_resources import get_distribution + expected_ua = 'gcloud-python/{0}'.format(get_distribution('gcloud').version) + conn = self._makeOne() + self.assertEqual(conn.USER_AGENT, expected_ua)