Skip to content

Commit 76274ca

Browse files
committed
pulled out helper method
1 parent 0d8865a commit 76274ca

1 file changed

Lines changed: 32 additions & 22 deletions

File tree

  • packages/google-api-core/google/api_core/gapic_v1

packages/google-api-core/google/api_core/gapic_v1/method.py

Lines changed: 32 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,34 @@ def _apply_decorators(func, decorators):
5757
return func
5858

5959

60+
def _extract_metrics_header(metadata):
61+
"""Extract x-google-api-client header from metadata list.
62+
63+
Args:
64+
metadata (Sequence[Tuple[str, str]]): The metadata to extract from.
65+
66+
Returns:
67+
Tuple[List[Tuple[str, str]], List[str]]: A tuple containing:
68+
- A list of remaining metadata tuples.
69+
- A list of metrics header values found.
70+
"""
71+
if not metadata:
72+
return [], []
73+
74+
for i, (key, val) in enumerate(metadata):
75+
if key == client_info.METRICS_METADATA_KEY:
76+
# Key located. Check the rest of the list for duplicate entries
77+
arbitrary_metadata = list(metadata[:i])
78+
metric_values = [val]
79+
for k, v in metadata[i+1:]:
80+
if k == client_info.METRICS_METADATA_KEY:
81+
metric_values.append(v)
82+
else:
83+
arbitrary_metadata.append((k, v))
84+
return arbitrary_metadata, metric_values
85+
# No key found
86+
return list(metadata), []
87+
6088
class _GapicCallable(object):
6189
"""Callable that applies retry, timeout, and metadata logic.
6290
@@ -91,17 +119,9 @@ def __init__(
91119
self._timeout = timeout
92120
self._compression = compression
93121
self._metadata = metadata
94-
95-
# Pre-extract the client metrics header from the initialized metadata.
96-
# This avoids repeating this work on every single RPC request invocation.
97-
self._arbitrary_metadata = []
98-
self._metrics_values = ""
99-
if metadata:
100-
for key, val in metadata:
101-
if key == client_info.METRICS_METADATA_KEY:
102-
self._metrics_values = val
103-
else:
104-
self._arbitrary_metadata.append((key, val))
122+
# Pre-extract the x-goog-api-client header from the initialized metadata.
123+
self._arbitrary_metadata, metric_values = _extract_metrics_header(metadata)
124+
self._metrics_values = " ".join(metric_values) if metric_values else ""
105125

106126
def __call__(
107127
self, *args, timeout=DEFAULT, retry=DEFAULT, compression=DEFAULT, **kwargs
@@ -127,23 +147,13 @@ def __call__(
127147
if self._metadata is not None:
128148
metadata = kwargs.get("metadata")
129149
if not metadata:
130-
# Fast path: in 99% of calls, the user did not pass any custom metadata,
131-
# so we can directly assign the pre-extracted metadata and skip any merging overhead.
132150
if self._metrics_values:
133151
kwargs["metadata"] = [(client_info.METRICS_METADATA_KEY, self._metrics_values)] + self._arbitrary_metadata
134152
else:
135153
kwargs["metadata"] = self._arbitrary_metadata
136154
else:
137155
# Merge user-supplied metadata with library-supplied metadata.
138-
# All keys in gRPC metadata are already lowercase.
139-
metadata = list(metadata)
140-
api_client_values = []
141-
merged_metadata = []
142-
for key, val in metadata:
143-
if key == client_info.METRICS_METADATA_KEY:
144-
api_client_values.append(val)
145-
else:
146-
merged_metadata.append((key, val))
156+
merged_metadata, api_client_values = _extract_metrics_header(metadata)
147157
if self._metrics_values:
148158
api_client_values.append(self._metrics_values)
149159
if api_client_values:

0 commit comments

Comments
 (0)