@@ -69,175 +69,186 @@ def read_environment_variables():
6969
7070DEFAULT_UNIVERSE = "googleapis.com"
7171
72+ try :
73+ from google .api_core .universe import get_default_mtls_endpoint
74+ except ImportError : # pragma: NO COVER
75+ def get_default_mtls_endpoint (api_endpoint : Optional [str ]) -> Optional [str ]:
76+ """Converts api endpoint to mTLS endpoint.
77+
78+ Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to
79+ "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively.
80+ Other URLs (including those that do not match these domain suffixes or
81+ already contain '.mtls.') are passed through as-is.
82+
83+ Args:
84+ api_endpoint (Optional[str]): the api endpoint to convert.
85+
86+ Returns:
87+ Optional[str]: converted mTLS api endpoint.
88+ """
89+ if not api_endpoint or ".mtls." in api_endpoint .lower ():
90+ return api_endpoint
91+
92+ has_scheme = "://" in api_endpoint
93+ if not has_scheme :
94+ parsed = urlparse ("//" + api_endpoint )
95+ else :
96+ parsed = urlparse (api_endpoint )
97+
98+ host = parsed .hostname
99+ if not host :
100+ return api_endpoint
101+
102+ port = f":{ parsed .port } " if parsed .port else ""
103+
104+ lowered_host = host .lower ()
105+ suffix_sandbox = ".sandbox.googleapis.com"
106+ suffix_google = ".googleapis.com"
107+ if lowered_host .endswith (suffix_sandbox ):
108+ new_host = host [: - len (suffix_sandbox )] + ".mtls.sandbox.googleapis.com"
109+ elif lowered_host .endswith (suffix_google ):
110+ new_host = host [: - len (suffix_google )] + ".mtls.googleapis.com"
111+ else :
112+ return api_endpoint
113+
114+ netloc = new_host + port
115+ new_parsed = parsed ._replace (netloc = netloc )
116+
117+ if not has_scheme :
118+ return urlunparse (new_parsed )[2 :]
119+ else :
120+ return urlunparse (new_parsed )
72121
73- def get_default_mtls_endpoint (api_endpoint : Optional [str ]) -> Optional [str ]:
74- """Converts api endpoint to mTLS endpoint.
75-
76- Convert "*.sandbox.googleapis.com" and "*.googleapis.com" to
77- "*.mtls.sandbox.googleapis.com" and "*.mtls.googleapis.com" respectively.
78- Other URLs (including those that do not match these domain suffixes or
79- already contain '.mtls.') are passed through as-is.
80-
81- Args:
82- api_endpoint (Optional[str]): the api endpoint to convert.
122+ try :
123+ from google .api_core .universe import get_api_endpoint
124+ except ImportError : # pragma: NO COVER
125+ def get_api_endpoint (
126+ api_override : Optional [str ],
127+ universe_domain : str ,
128+ default_universe : str ,
129+ default_mtls_endpoint : Optional [str ],
130+ default_endpoint_template : str ,
131+ use_mtls : bool ,
132+ ) -> str :
133+ """Return the API endpoint used by the client.
134+
135+ Args:
136+ api_override (Optional[str]): The API endpoint override. If specified,
137+ this is always returned.
138+ universe_domain (str): The universe domain used by the client.
139+ default_universe (str): The default universe domain.
140+ default_mtls_endpoint (Optional[str]): The default mTLS endpoint.
141+ default_endpoint_template (str): The default endpoint template containing
142+ a placeholder `{UNIVERSE_DOMAIN}`.
143+ use_mtls (bool): Whether to use the mTLS endpoint.
144+
145+ Returns:
146+ str: The API endpoint to be used by the client.
147+
148+ Raises:
149+ google.auth.exceptions.MutualTLSChannelError: If mTLS is requested but
150+ not supported in the configured universe domain.
151+ ValueError: If mTLS is requested but no mTLS endpoint is available.
152+ """
153+ if api_override is not None :
154+ return api_override
155+
156+ if use_mtls :
157+ if universe_domain .lower () != default_universe .lower ():
158+ raise MutualTLSChannelError (
159+ f"mTLS is not supported in any universe other than { default_universe } ."
160+ )
161+ if not default_mtls_endpoint :
162+ raise ValueError ("mTLS endpoint is not available." )
163+ return default_mtls_endpoint
164+ else :
165+ return default_endpoint_template .format (UNIVERSE_DOMAIN = universe_domain )
83166
84- Returns:
85- Optional[str]: converted mTLS api endpoint.
86- """
87- if not api_endpoint or ".mtls." in api_endpoint .lower ():
88- return api_endpoint
89-
90- has_scheme = "://" in api_endpoint
91- if not has_scheme :
92- parsed = urlparse ("//" + api_endpoint )
93- else :
94- parsed = urlparse (api_endpoint )
95-
96- host = parsed .hostname
97- if not host :
98- return api_endpoint
99-
100- port = f":{ parsed .port } " if parsed .port else ""
101-
102- lowered_host = host .lower ()
103- suffix_sandbox = ".sandbox.googleapis.com"
104- suffix_google = ".googleapis.com"
105- if lowered_host .endswith (suffix_sandbox ):
106- new_host = host [: - len (suffix_sandbox )] + ".mtls.sandbox.googleapis.com"
107- elif lowered_host .endswith (suffix_google ):
108- new_host = host [: - len (suffix_google )] + ".mtls.googleapis.com"
109- else :
110- return api_endpoint
111-
112- netloc = new_host + port
113- new_parsed = parsed ._replace (netloc = netloc )
114-
115- if not has_scheme :
116- return urlunparse (new_parsed )[2 :]
117- else :
118- return urlunparse (new_parsed )
119-
120- def get_api_endpoint (
121- api_override : Optional [str ],
122- universe_domain : str ,
123- default_universe : str ,
124- default_mtls_endpoint : Optional [str ],
125- default_endpoint_template : str ,
126- use_mtls : bool ,
127- ) -> str :
128- """Return the API endpoint used by the client.
129-
130- Args:
131- api_override (Optional[str]): The API endpoint override. If specified,
132- this is always returned.
133- universe_domain (str): The universe domain used by the client.
134- default_universe (str): The default universe domain.
135- default_mtls_endpoint (Optional[str]): The default mTLS endpoint.
136- default_endpoint_template (str): The default endpoint template containing
137- a placeholder `{UNIVERSE_DOMAIN}`.
138- use_mtls (bool): Whether to use the mTLS endpoint.
167+ try :
168+ from google .api_core .universe import get_universe_domain
169+ except ImportError : # pragma: NO COVER
170+ def get_universe_domain (
171+ * potential_universes : Optional [str ],
172+ default_universe : str ,
173+ ) -> str :
174+ """Return the universe domain used by the client.
175+
176+ Args:
177+ *potential_universes (Optional[str]): Potential universe domains in order of preference.
178+ default_universe (str): The default universe domain.
179+
180+ Returns:
181+ str: The universe domain to be used by the client.
182+
183+ Raises:
184+ EmptyUniverseError: If the resolved universe domain is an empty string.
185+ """
186+ resolved = next (
187+ (x .strip () for x in potential_universes if x is not None ),
188+ default_universe ,
189+ )
139190
140- Returns:
141- str: The API endpoint to be used by the client.
191+ if not resolved :
192+ raise EmptyUniverseError ()
193+ return resolved
142194
143- Raises:
144- google.auth.exceptions.MutualTLSChannelError: If mTLS is requested but
145- not supported in the configured universe domain.
146- ValueError: If mTLS is requested but no mTLS endpoint is available.
147- """
148- if api_override is not None :
149- return api_override
150195
151- if use_mtls :
152- if universe_domain .lower () != default_universe .lower ():
153- raise MutualTLSChannelError (
154- f"mTLS is not supported in any universe other than { default_universe } ."
196+ try :
197+ from google .api_core .rest_helpers import transcode_request # type: ignore
198+ except ImportError : # pragma: NO COVER
199+ def transcode_request (
200+ http_options : List [Dict [str , str ]],
201+ request : Any ,
202+ required_fields_default_values : Optional [Dict [str , Any ]] = None ,
203+ rest_numeric_enums : bool = False ,
204+ ) -> Tuple [Dict [str , Any ], Optional [str ], Dict [str , Any ]]:
205+ """Transcodes a request into HTTP method, URI, body, and query parameters.
206+
207+ Args:
208+ http_options (List[Dict[str, str]]): List of HTTP transcoding rules.
209+ request (Any): The protobuf or proto-plus request message.
210+ required_fields_default_values (Optional[Dict[str, Any]]): Dictionary
211+ of required fields default values to merge into query parameters if missing.
212+ rest_numeric_enums (bool): Whether to encode enums as integers.
213+
214+ Returns:
215+ Tuple[Dict[str, Any], Optional[str], Dict[str, Any]]: A tuple containing:
216+ - The raw transcoded request dictionary (containing keys like 'uri', 'method').
217+ - The serialized request body JSON string, or None if no body.
218+ - The query parameters dictionary.
219+ """
220+ if request is None :
221+ raise TypeError ("request cannot be None" )
222+
223+ # Convert proto-plus message to its underlying protobuf message if needed
224+ pb_request = getattr (request , "_pb" , request )
225+
226+ transcoded_request = path_template .transcode (http_options , pb_request )
227+
228+ body_json = None
229+ if transcoded_request .get ("body" ) is not None :
230+ body_json = json_format .MessageToJson (
231+ transcoded_request ["body" ],
232+ use_integers_for_enums = rest_numeric_enums ,
155233 )
156- if not default_mtls_endpoint :
157- raise ValueError ("mTLS endpoint is not available." )
158- return default_mtls_endpoint
159- else :
160- return default_endpoint_template .format (UNIVERSE_DOMAIN = universe_domain )
161-
162- def get_universe_domain (
163- * potential_universes : Optional [str ],
164- default_universe : str = DEFAULT_UNIVERSE ,
165- ) -> str :
166- """Return the universe domain used by the client.
167-
168- Args:
169- *potential_universes (Optional[str]): Potential universe domains in order of preference.
170- default_universe (str): The default universe domain.
171-
172- Returns:
173- str: The universe domain to be used by the client.
174-
175- Raises:
176- EmptyUniverseError: If the resolved universe domain is an empty string.
177- """
178- resolved = next (
179- (x .strip () for x in potential_universes if x is not None ),
180- default_universe ,
181- )
182-
183- if not resolved :
184- raise EmptyUniverseError ()
185- return resolved
186-
187-
188- def transcode_request (
189- http_options : List [Dict [str , str ]],
190- request : Any ,
191- required_fields_default_values : Optional [Dict [str , Any ]] = None ,
192- rest_numeric_enums : bool = False ,
193- ) -> Tuple [Dict [str , Any ], Optional [str ], Dict [str , Any ]]:
194- """Transcodes a request into HTTP method, URI, body, and query parameters.
195-
196- Args:
197- http_options (List[Dict[str, str]]): List of HTTP transcoding rules.
198- request (Any): The protobuf or proto-plus request message.
199- required_fields_default_values (Optional[Dict[str, Any]]): Dictionary
200- of required fields default values to merge into query parameters if missing.
201- rest_numeric_enums (bool): Whether to encode enums as integers.
202234
203- Returns:
204- Tuple[Dict[str, Any], Optional[str], Dict[str, Any]]: A tuple containing:
205- - The raw transcoded request dictionary (containing keys like 'uri', 'method').
206- - The serialized request body JSON string, or None if no body.
207- - The query parameters dictionary.
208- """
209- if request is None :
210- raise TypeError ("request cannot be None" )
211-
212- # Convert proto-plus message to its underlying protobuf message if needed
213- pb_request = getattr (request , "_pb" , request )
214-
215- transcoded_request = path_template .transcode (http_options , pb_request )
216-
217- body_json = None
218- if transcoded_request .get ("body" ) is not None :
219- body_json = json_format .MessageToJson (
220- transcoded_request ["body" ],
221- use_integers_for_enums = rest_numeric_enums ,
222- )
223-
224- query_params_json = {}
225- if transcoded_request .get ("query_params" ) is not None :
226- query_params_json = json .loads (
227- json_format .MessageToJson (
228- transcoded_request ["query_params" ],
229- use_integers_for_enums = rest_numeric_enums ,
235+ query_params_json = {}
236+ if transcoded_request .get ("query_params" ) is not None :
237+ query_params_json = json .loads (
238+ json_format .MessageToJson (
239+ transcoded_request ["query_params" ],
240+ use_integers_for_enums = rest_numeric_enums ,
241+ )
230242 )
231- )
232243
233- # If required_fields_default_values is provided, we merge default values for missing
234- # required fields into the query parameters.
235- if required_fields_default_values :
236- for k , v in required_fields_default_values .items ():
237- if k not in query_params_json :
238- query_params_json [k ] = v
244+ # If required_fields_default_values is provided, we merge default values for missing
245+ # required fields into the query parameters.
246+ if required_fields_default_values :
247+ for k , v in required_fields_default_values .items ():
248+ if k not in query_params_json :
249+ query_params_json [k ] = v
239250
240- if rest_numeric_enums :
241- query_params_json ["$alt" ] = "json;enum-encoding=int"
251+ if rest_numeric_enums :
252+ query_params_json ["$alt" ] = "json;enum-encoding=int"
242253
243- return transcoded_request , body_json , query_params_json
254+ return transcoded_request , body_json , query_params_json
0 commit comments