20
20
Generally, these headers are specified as gRPC metadata.
21
21
"""
22
22
23
+ import functools
23
24
from enum import Enum
24
25
from urllib .parse import urlencode
25
26
26
27
ROUTING_METADATA_KEY = "x-goog-request-params"
28
+ # This is the value for the `maxsize` argument of @functools.lru_cache
29
+ # https://docs.python.org/3/library/functools.html#functools.lru_cache
30
+ # This represents the number of recent function calls to store.
31
+ ROUTING_PARAM_CACHE_SIZE = 32
27
32
28
33
29
34
def to_routing_header (params , qualified_enums = True ):
30
35
"""Returns a routing header string for the given request parameters.
31
36
32
37
Args:
33
- params (Mapping[str, Any ]): A dictionary containing the request
38
+ params (Mapping[str, str | bytes | Enum ]): A dictionary containing the request
34
39
parameters used for routing.
35
40
qualified_enums (bool): Whether to represent enum values
36
41
as their type-qualified symbol names instead of as their
37
42
unqualified symbol names.
38
43
39
44
Returns:
40
45
str: The routing header string.
41
-
42
46
"""
47
+ tuples = params .items () if isinstance (params , dict ) else params
43
48
if not qualified_enums :
44
- if isinstance (params , dict ):
45
- tuples = params .items ()
46
- else :
47
- tuples = params
48
- params = [(x [0 ], x [1 ].name ) if isinstance (x [1 ], Enum ) else x for x in tuples ]
49
- return urlencode (
50
- params ,
51
- # Per Google API policy (go/api-url-encoding), / is not encoded.
52
- safe = "/" ,
53
- )
49
+ tuples = [(x [0 ], x [1 ].name ) if isinstance (x [1 ], Enum ) else x for x in tuples ]
50
+ return "&" .join ([_urlencode_param (* t ) for t in tuples ])
54
51
55
52
56
53
def to_grpc_metadata (params , qualified_enums = True ):
57
54
"""Returns the gRPC metadata containing the routing headers for the given
58
55
request parameters.
59
56
60
57
Args:
61
- params (Mapping[str, Any ]): A dictionary containing the request
58
+ params (Mapping[str, str | bytes | Enum ]): A dictionary containing the request
62
59
parameters used for routing.
63
60
qualified_enums (bool): Whether to represent enum values
64
61
as their type-qualified symbol names instead of as their
@@ -69,3 +66,22 @@ def to_grpc_metadata(params, qualified_enums=True):
69
66
and value.
70
67
"""
71
68
return (ROUTING_METADATA_KEY , to_routing_header (params , qualified_enums ))
69
+
70
+
71
+ # use caching to avoid repeated computation
72
+ @functools .lru_cache (maxsize = ROUTING_PARAM_CACHE_SIZE )
73
+ def _urlencode_param (key , value ):
74
+ """Cacheable wrapper over urlencode
75
+
76
+ Args:
77
+ key (str): The key of the parameter to encode.
78
+ value (str | bytes | Enum): The value of the parameter to encode.
79
+
80
+ Returns:
81
+ str: The encoded parameter.
82
+ """
83
+ return urlencode (
84
+ {key : value },
85
+ # Per Google API policy (go/api-url-encoding), / is not encoded.
86
+ safe = "/" ,
87
+ )
0 commit comments