Skip to content

Commit ba7bfd3

Browse files
authored
Refactor 'client_info' support. (#7849)
* Add 'user_agent' and 'extra_headers' properties to 'Connection'. Deprecate the 'USER_AGENT' and '_EXTRA_HEADERS' class-level attributes. * Add 'client_info' parameter to 'Connection' ctor. * Implement 'Connection.user_agent' via its '_client_info'. * Ensure 'X-Goog-API-Client' header is always passed. * Create/use non-GAPIC-specific 'ClientInfo' class FBO HTTP/JSON clients. Derive the existing GAPIC class from it.
1 parent 1f2b658 commit ba7bfd3

File tree

4 files changed

+167
-105
lines changed

4 files changed

+167
-105
lines changed

google/api_core/client_info.py

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
# Copyright 2017 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
"""Helpers for providing client information.
16+
17+
Client information is used to send information about the calling client,
18+
such as the library and Python version, to API services.
19+
"""
20+
21+
import platform
22+
23+
import pkg_resources
24+
25+
_PY_VERSION = platform.python_version()
26+
_API_CORE_VERSION = pkg_resources.get_distribution("google-api-core").version
27+
28+
try:
29+
_GRPC_VERSION = pkg_resources.get_distribution("grpcio").version
30+
except pkg_resources.DistributionNotFound: # pragma: NO COVER
31+
_GRPC_VERSION = None
32+
33+
34+
class ClientInfo(object):
35+
"""Client information used to generate a user-agent for API calls.
36+
37+
This user-agent information is sent along with API calls to allow the
38+
receiving service to do analytics on which versions of Python and Google
39+
libraries are being used.
40+
41+
Args:
42+
python_version (str): The Python interpreter version, for example,
43+
``'2.7.13'``.
44+
grpc_version (Optional[str]): The gRPC library version.
45+
api_core_version (str): The google-api-core library version.
46+
gapic_version (Optional[str]): The sversion of gapic-generated client
47+
library, if the library was generated by gapic.
48+
client_library_version (Optional[str]): The version of the client
49+
library, generally used if the client library was not generated
50+
by gapic or if additional functionality was built on top of
51+
a gapic client library.
52+
user_agent (Optional[str]): Prefix to the user agent header. This is
53+
used to supply information such as application name or partner tool.
54+
Recommended format: ``application-or-tool-ID/major.minor.version``.
55+
"""
56+
57+
def __init__(
58+
self,
59+
python_version=_PY_VERSION,
60+
grpc_version=_GRPC_VERSION,
61+
api_core_version=_API_CORE_VERSION,
62+
gapic_version=None,
63+
client_library_version=None,
64+
user_agent=None,
65+
):
66+
self.python_version = python_version
67+
self.grpc_version = grpc_version
68+
self.api_core_version = api_core_version
69+
self.gapic_version = gapic_version
70+
self.client_library_version = client_library_version
71+
self.user_agent = user_agent
72+
73+
def to_user_agent(self):
74+
"""Returns the user-agent string for this client info."""
75+
76+
# Note: the order here is important as the internal metrics system
77+
# expects these items to be in specific locations.
78+
ua = ""
79+
80+
if self.user_agent is not None:
81+
ua += "{user_agent} "
82+
83+
ua += "gl-python/{python_version} "
84+
85+
if self.grpc_version is not None:
86+
ua += "grpc/{grpc_version} "
87+
88+
ua += "gax/{api_core_version} "
89+
90+
if self.gapic_version is not None:
91+
ua += "gapic/{gapic_version} "
92+
93+
if self.client_library_version is not None:
94+
ua += "gccl/{client_library_version} "
95+
96+
return ua.format(**self.__dict__).strip()

google/api_core/gapic_v1/client_info.py

Lines changed: 2 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -18,22 +18,13 @@
1818
such as the library and Python version, to API services.
1919
"""
2020

21-
import platform
21+
from google.api_core import client_info
2222

23-
import pkg_resources
24-
25-
_PY_VERSION = platform.python_version()
26-
_API_CORE_VERSION = pkg_resources.get_distribution("google-api-core").version
27-
28-
try:
29-
_GRPC_VERSION = pkg_resources.get_distribution("grpcio").version
30-
except pkg_resources.DistributionNotFound: # pragma: NO COVER
31-
_GRPC_VERSION = None
3223

3324
METRICS_METADATA_KEY = "x-goog-api-client"
3425

3526

36-
class ClientInfo(object):
27+
class ClientInfo(client_info.ClientInfo):
3728
"""Client information used to generate a user-agent for API calls.
3829
3930
This user-agent information is sent along with API calls to allow the
@@ -56,47 +47,6 @@ class ClientInfo(object):
5647
Recommended format: ``application-or-tool-ID/major.minor.version``.
5748
"""
5849

59-
def __init__(
60-
self,
61-
python_version=_PY_VERSION,
62-
grpc_version=_GRPC_VERSION,
63-
api_core_version=_API_CORE_VERSION,
64-
gapic_version=None,
65-
client_library_version=None,
66-
user_agent=None,
67-
):
68-
self.python_version = python_version
69-
self.grpc_version = grpc_version
70-
self.api_core_version = api_core_version
71-
self.gapic_version = gapic_version
72-
self.client_library_version = client_library_version
73-
self.user_agent = user_agent
74-
75-
def to_user_agent(self):
76-
"""Returns the user-agent string for this client info."""
77-
78-
# Note: the order here is important as the internal metrics system
79-
# expects these items to be in specific locations.
80-
ua = ""
81-
82-
if self.user_agent is not None:
83-
ua += "{user_agent} "
84-
85-
ua += "gl-python/{python_version} "
86-
87-
if self.grpc_version is not None:
88-
ua += "grpc/{grpc_version} "
89-
90-
ua += "gax/{api_core_version} "
91-
92-
if self.gapic_version is not None:
93-
ua += "gapic/{gapic_version} "
94-
95-
if self.client_library_version is not None:
96-
ua += "gccl/{client_library_version} "
97-
98-
return ua.format(**self.__dict__).strip()
99-
10050
def to_grpc_metadata(self):
10151
"""Returns the gRPC metadata for this client info."""
10252
return (METRICS_METADATA_KEY, self.to_user_agent())

tests/unit/gapic/test_client_info.py

Lines changed: 0 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -16,59 +16,6 @@
1616
from google.api_core.gapic_v1 import client_info
1717

1818

19-
def test_constructor_defaults():
20-
info = client_info.ClientInfo()
21-
22-
assert info.python_version is not None
23-
assert info.grpc_version is not None
24-
assert info.api_core_version is not None
25-
assert info.gapic_version is None
26-
assert info.client_library_version is None
27-
28-
29-
def test_constructor_options():
30-
info = client_info.ClientInfo(
31-
python_version="1",
32-
grpc_version="2",
33-
api_core_version="3",
34-
gapic_version="4",
35-
client_library_version="5",
36-
user_agent="6"
37-
)
38-
39-
assert info.python_version == "1"
40-
assert info.grpc_version == "2"
41-
assert info.api_core_version == "3"
42-
assert info.gapic_version == "4"
43-
assert info.client_library_version == "5"
44-
assert info.user_agent == "6"
45-
46-
47-
def test_to_user_agent_minimal():
48-
info = client_info.ClientInfo(
49-
python_version="1", api_core_version="2", grpc_version=None
50-
)
51-
52-
user_agent = info.to_user_agent()
53-
54-
assert user_agent == "gl-python/1 gax/2"
55-
56-
57-
def test_to_user_agent_full():
58-
info = client_info.ClientInfo(
59-
python_version="1",
60-
grpc_version="2",
61-
api_core_version="3",
62-
gapic_version="4",
63-
client_library_version="5",
64-
user_agent="app-name/1.0",
65-
)
66-
67-
user_agent = info.to_user_agent()
68-
69-
assert user_agent == "app-name/1.0 gl-python/1 grpc/2 gax/3 gapic/4 gccl/5"
70-
71-
7219
def test_to_grpc_metadata():
7320
info = client_info.ClientInfo()
7421

tests/unit/test_client_info.py

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
# Copyright 2017 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
16+
from google.api_core import client_info
17+
18+
19+
def test_constructor_defaults():
20+
info = client_info.ClientInfo()
21+
22+
assert info.python_version is not None
23+
assert info.grpc_version is not None
24+
assert info.api_core_version is not None
25+
assert info.gapic_version is None
26+
assert info.client_library_version is None
27+
28+
29+
def test_constructor_options():
30+
info = client_info.ClientInfo(
31+
python_version="1",
32+
grpc_version="2",
33+
api_core_version="3",
34+
gapic_version="4",
35+
client_library_version="5",
36+
user_agent="6"
37+
)
38+
39+
assert info.python_version == "1"
40+
assert info.grpc_version == "2"
41+
assert info.api_core_version == "3"
42+
assert info.gapic_version == "4"
43+
assert info.client_library_version == "5"
44+
assert info.user_agent == "6"
45+
46+
47+
def test_to_user_agent_minimal():
48+
info = client_info.ClientInfo(
49+
python_version="1", api_core_version="2", grpc_version=None
50+
)
51+
52+
user_agent = info.to_user_agent()
53+
54+
assert user_agent == "gl-python/1 gax/2"
55+
56+
57+
def test_to_user_agent_full():
58+
info = client_info.ClientInfo(
59+
python_version="1",
60+
grpc_version="2",
61+
api_core_version="3",
62+
gapic_version="4",
63+
client_library_version="5",
64+
user_agent="app-name/1.0",
65+
)
66+
67+
user_agent = info.to_user_agent()
68+
69+
assert user_agent == "app-name/1.0 gl-python/1 grpc/2 gax/3 gapic/4 gccl/5"

0 commit comments

Comments
 (0)