google-maps-routeoptimization 0.2.0__tar.gz → 0.3.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. {google_maps_routeoptimization-0.2.0/google_maps_routeoptimization.egg-info → google_maps_routeoptimization-0.3.0}/PKG-INFO +1 -1
  2. {google_maps_routeoptimization-0.2.0 → google_maps_routeoptimization-0.3.0}/google/maps/routeoptimization/gapic_version.py +1 -1
  3. google_maps_routeoptimization-0.3.0/google/maps/routeoptimization_v1/__init__.py +201 -0
  4. {google_maps_routeoptimization-0.2.0 → google_maps_routeoptimization-0.3.0}/google/maps/routeoptimization_v1/gapic_version.py +1 -1
  5. {google_maps_routeoptimization-0.2.0 → google_maps_routeoptimization-0.3.0}/google/maps/routeoptimization_v1/services/route_optimization/client.py +32 -14
  6. {google_maps_routeoptimization-0.2.0 → google_maps_routeoptimization-0.3.0/google_maps_routeoptimization.egg-info}/PKG-INFO +1 -1
  7. {google_maps_routeoptimization-0.2.0 → google_maps_routeoptimization-0.3.0}/tests/unit/gapic/routeoptimization_v1/test_route_optimization.py +226 -29
  8. google_maps_routeoptimization-0.2.0/google/maps/routeoptimization_v1/__init__.py +0 -97
  9. {google_maps_routeoptimization-0.2.0 → google_maps_routeoptimization-0.3.0}/LICENSE +0 -0
  10. {google_maps_routeoptimization-0.2.0 → google_maps_routeoptimization-0.3.0}/MANIFEST.in +0 -0
  11. {google_maps_routeoptimization-0.2.0 → google_maps_routeoptimization-0.3.0}/README.rst +0 -0
  12. {google_maps_routeoptimization-0.2.0 → google_maps_routeoptimization-0.3.0}/google/maps/routeoptimization/__init__.py +0 -0
  13. {google_maps_routeoptimization-0.2.0 → google_maps_routeoptimization-0.3.0}/google/maps/routeoptimization/py.typed +0 -0
  14. {google_maps_routeoptimization-0.2.0 → google_maps_routeoptimization-0.3.0}/google/maps/routeoptimization_v1/gapic_metadata.json +0 -0
  15. {google_maps_routeoptimization-0.2.0 → google_maps_routeoptimization-0.3.0}/google/maps/routeoptimization_v1/py.typed +0 -0
  16. {google_maps_routeoptimization-0.2.0 → google_maps_routeoptimization-0.3.0}/google/maps/routeoptimization_v1/services/__init__.py +0 -0
  17. {google_maps_routeoptimization-0.2.0 → google_maps_routeoptimization-0.3.0}/google/maps/routeoptimization_v1/services/route_optimization/__init__.py +0 -0
  18. {google_maps_routeoptimization-0.2.0 → google_maps_routeoptimization-0.3.0}/google/maps/routeoptimization_v1/services/route_optimization/async_client.py +0 -0
  19. {google_maps_routeoptimization-0.2.0 → google_maps_routeoptimization-0.3.0}/google/maps/routeoptimization_v1/services/route_optimization/transports/__init__.py +0 -0
  20. {google_maps_routeoptimization-0.2.0 → google_maps_routeoptimization-0.3.0}/google/maps/routeoptimization_v1/services/route_optimization/transports/base.py +0 -0
  21. {google_maps_routeoptimization-0.2.0 → google_maps_routeoptimization-0.3.0}/google/maps/routeoptimization_v1/services/route_optimization/transports/grpc.py +0 -0
  22. {google_maps_routeoptimization-0.2.0 → google_maps_routeoptimization-0.3.0}/google/maps/routeoptimization_v1/services/route_optimization/transports/grpc_asyncio.py +0 -0
  23. {google_maps_routeoptimization-0.2.0 → google_maps_routeoptimization-0.3.0}/google/maps/routeoptimization_v1/services/route_optimization/transports/rest.py +0 -0
  24. {google_maps_routeoptimization-0.2.0 → google_maps_routeoptimization-0.3.0}/google/maps/routeoptimization_v1/services/route_optimization/transports/rest_base.py +0 -0
  25. {google_maps_routeoptimization-0.2.0 → google_maps_routeoptimization-0.3.0}/google/maps/routeoptimization_v1/types/__init__.py +0 -0
  26. {google_maps_routeoptimization-0.2.0 → google_maps_routeoptimization-0.3.0}/google/maps/routeoptimization_v1/types/route_optimization_service.py +0 -0
  27. {google_maps_routeoptimization-0.2.0 → google_maps_routeoptimization-0.3.0}/google_maps_routeoptimization.egg-info/SOURCES.txt +0 -0
  28. {google_maps_routeoptimization-0.2.0 → google_maps_routeoptimization-0.3.0}/google_maps_routeoptimization.egg-info/dependency_links.txt +0 -0
  29. {google_maps_routeoptimization-0.2.0 → google_maps_routeoptimization-0.3.0}/google_maps_routeoptimization.egg-info/not-zip-safe +0 -0
  30. {google_maps_routeoptimization-0.2.0 → google_maps_routeoptimization-0.3.0}/google_maps_routeoptimization.egg-info/requires.txt +0 -0
  31. {google_maps_routeoptimization-0.2.0 → google_maps_routeoptimization-0.3.0}/google_maps_routeoptimization.egg-info/top_level.txt +0 -0
  32. {google_maps_routeoptimization-0.2.0 → google_maps_routeoptimization-0.3.0}/setup.cfg +0 -0
  33. {google_maps_routeoptimization-0.2.0 → google_maps_routeoptimization-0.3.0}/setup.py +0 -0
  34. {google_maps_routeoptimization-0.2.0 → google_maps_routeoptimization-0.3.0}/tests/__init__.py +0 -0
  35. {google_maps_routeoptimization-0.2.0 → google_maps_routeoptimization-0.3.0}/tests/unit/__init__.py +0 -0
  36. {google_maps_routeoptimization-0.2.0 → google_maps_routeoptimization-0.3.0}/tests/unit/gapic/__init__.py +0 -0
  37. {google_maps_routeoptimization-0.2.0 → google_maps_routeoptimization-0.3.0}/tests/unit/gapic/routeoptimization_v1/__init__.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: google-maps-routeoptimization
3
- Version: 0.2.0
3
+ Version: 0.3.0
4
4
  Summary: Google Maps Routeoptimization API client library
5
5
  Home-page: https://github.com/googleapis/google-cloud-python/tree/main/packages/google-maps-routeoptimization
6
6
  Author: Google LLC
@@ -13,4 +13,4 @@
13
13
  # See the License for the specific language governing permissions and
14
14
  # limitations under the License.
15
15
  #
16
- __version__ = "0.2.0" # {x-release-please-version}
16
+ __version__ = "0.3.0" # {x-release-please-version}
@@ -0,0 +1,201 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Copyright 2025 Google LLC
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #
16
+ import sys
17
+
18
+ import google.api_core as api_core
19
+
20
+ from google.maps.routeoptimization_v1 import gapic_version as package_version
21
+
22
+ __version__ = package_version.__version__
23
+
24
+ if sys.version_info >= (3, 8): # pragma: NO COVER
25
+ from importlib import metadata
26
+ else: # pragma: NO COVER
27
+ # TODO(https://github.com/googleapis/python-api-core/issues/835): Remove
28
+ # this code path once we drop support for Python 3.7
29
+ import importlib_metadata as metadata
30
+
31
+ from .services.route_optimization import (
32
+ RouteOptimizationAsyncClient,
33
+ RouteOptimizationClient,
34
+ )
35
+ from .types.route_optimization_service import (
36
+ AggregatedMetrics,
37
+ BatchOptimizeToursMetadata,
38
+ BatchOptimizeToursRequest,
39
+ BatchOptimizeToursResponse,
40
+ BreakRule,
41
+ DataFormat,
42
+ DistanceLimit,
43
+ GcsDestination,
44
+ GcsSource,
45
+ InjectedSolutionConstraint,
46
+ InputConfig,
47
+ Location,
48
+ OptimizeToursLongRunningMetadata,
49
+ OptimizeToursRequest,
50
+ OptimizeToursResponse,
51
+ OptimizeToursUriMetadata,
52
+ OptimizeToursUriRequest,
53
+ OptimizeToursUriResponse,
54
+ OptimizeToursValidationError,
55
+ OutputConfig,
56
+ RouteModifiers,
57
+ Shipment,
58
+ ShipmentModel,
59
+ ShipmentRoute,
60
+ ShipmentTypeIncompatibility,
61
+ ShipmentTypeRequirement,
62
+ SkippedShipment,
63
+ TimeWindow,
64
+ TransitionAttributes,
65
+ Uri,
66
+ Vehicle,
67
+ VehicleFullness,
68
+ Waypoint,
69
+ )
70
+
71
+ if hasattr(api_core, "check_python_version") and hasattr(
72
+ api_core, "check_dependency_versions"
73
+ ): # pragma: NO COVER
74
+ api_core.check_python_version("google.maps.routeoptimization_v1") # type: ignore
75
+ api_core.check_dependency_versions("google.maps.routeoptimization_v1") # type: ignore
76
+ else: # pragma: NO COVER
77
+ # An older version of api_core is installed which does not define the
78
+ # functions above. We do equivalent checks manually.
79
+ try:
80
+ import sys
81
+ import warnings
82
+
83
+ _py_version_str = sys.version.split()[0]
84
+ _package_label = "google.maps.routeoptimization_v1"
85
+ if sys.version_info < (3, 9):
86
+ warnings.warn(
87
+ "You are using a non-supported Python version "
88
+ + f"({_py_version_str}). Google will not post any further "
89
+ + f"updates to {_package_label} supporting this Python version. "
90
+ + "Please upgrade to the latest Python version, or at "
91
+ + f"least to Python 3.9, and then update {_package_label}.",
92
+ FutureWarning,
93
+ )
94
+ if sys.version_info[:2] == (3, 9):
95
+ warnings.warn(
96
+ f"You are using a Python version ({_py_version_str}) "
97
+ + f"which Google will stop supporting in {_package_label} in "
98
+ + "January 2026. Please "
99
+ + "upgrade to the latest Python version, or at "
100
+ + "least to Python 3.10, before then, and "
101
+ + f"then update {_package_label}.",
102
+ FutureWarning,
103
+ )
104
+
105
+ def parse_version_to_tuple(version_string: str):
106
+ """Safely converts a semantic version string to a comparable tuple of integers.
107
+ Example: "4.25.8" -> (4, 25, 8)
108
+ Ignores non-numeric parts and handles common version formats.
109
+ Args:
110
+ version_string: Version string in the format "x.y.z" or "x.y.z<suffix>"
111
+ Returns:
112
+ Tuple of integers for the parsed version string.
113
+ """
114
+ parts = []
115
+ for part in version_string.split("."):
116
+ try:
117
+ parts.append(int(part))
118
+ except ValueError:
119
+ # If it's a non-numeric part (e.g., '1.0.0b1' -> 'b1'), stop here.
120
+ # This is a simplification compared to 'packaging.parse_version', but sufficient
121
+ # for comparing strictly numeric semantic versions.
122
+ break
123
+ return tuple(parts)
124
+
125
+ def _get_version(dependency_name):
126
+ try:
127
+ version_string: str = metadata.version(dependency_name)
128
+ parsed_version = parse_version_to_tuple(version_string)
129
+ return (parsed_version, version_string)
130
+ except Exception:
131
+ # Catch exceptions from metadata.version() (e.g., PackageNotFoundError)
132
+ # or errors during parse_version_to_tuple
133
+ return (None, "--")
134
+
135
+ _dependency_package = "google.protobuf"
136
+ _next_supported_version = "4.25.8"
137
+ _next_supported_version_tuple = (4, 25, 8)
138
+ _recommendation = " (we recommend 6.x)"
139
+ (_version_used, _version_used_string) = _get_version(_dependency_package)
140
+ if _version_used and _version_used < _next_supported_version_tuple:
141
+ warnings.warn(
142
+ f"Package {_package_label} depends on "
143
+ + f"{_dependency_package}, currently installed at version "
144
+ + f"{_version_used_string}. Future updates to "
145
+ + f"{_package_label} will require {_dependency_package} at "
146
+ + f"version {_next_supported_version} or higher{_recommendation}."
147
+ + " Please ensure "
148
+ + "that either (a) your Python environment doesn't pin the "
149
+ + f"version of {_dependency_package}, so that updates to "
150
+ + f"{_package_label} can require the higher version, or "
151
+ + "(b) you manually update your Python environment to use at "
152
+ + f"least version {_next_supported_version} of "
153
+ + f"{_dependency_package}.",
154
+ FutureWarning,
155
+ )
156
+ except Exception:
157
+ warnings.warn(
158
+ "Could not determine the version of Python "
159
+ + "currently being used. To continue receiving "
160
+ + "updates for {_package_label}, ensure you are "
161
+ + "using a supported version of Python; see "
162
+ + "https://devguide.python.org/versions/"
163
+ )
164
+
165
+ __all__ = (
166
+ "RouteOptimizationAsyncClient",
167
+ "AggregatedMetrics",
168
+ "BatchOptimizeToursMetadata",
169
+ "BatchOptimizeToursRequest",
170
+ "BatchOptimizeToursResponse",
171
+ "BreakRule",
172
+ "DataFormat",
173
+ "DistanceLimit",
174
+ "GcsDestination",
175
+ "GcsSource",
176
+ "InjectedSolutionConstraint",
177
+ "InputConfig",
178
+ "Location",
179
+ "OptimizeToursLongRunningMetadata",
180
+ "OptimizeToursRequest",
181
+ "OptimizeToursResponse",
182
+ "OptimizeToursUriMetadata",
183
+ "OptimizeToursUriRequest",
184
+ "OptimizeToursUriResponse",
185
+ "OptimizeToursValidationError",
186
+ "OutputConfig",
187
+ "RouteModifiers",
188
+ "RouteOptimizationClient",
189
+ "Shipment",
190
+ "ShipmentModel",
191
+ "ShipmentRoute",
192
+ "ShipmentTypeIncompatibility",
193
+ "ShipmentTypeRequirement",
194
+ "SkippedShipment",
195
+ "TimeWindow",
196
+ "TransitionAttributes",
197
+ "Uri",
198
+ "Vehicle",
199
+ "VehicleFullness",
200
+ "Waypoint",
201
+ )
@@ -13,4 +13,4 @@
13
13
  # See the License for the specific language governing permissions and
14
14
  # limitations under the License.
15
15
  #
16
- __version__ = "0.2.0" # {x-release-please-version}
16
+ __version__ = "0.3.0" # {x-release-please-version}
@@ -174,6 +174,34 @@ class RouteOptimizationClient(metaclass=RouteOptimizationClientMeta):
174
174
  _DEFAULT_ENDPOINT_TEMPLATE = "routeoptimization.{UNIVERSE_DOMAIN}"
175
175
  _DEFAULT_UNIVERSE = "googleapis.com"
176
176
 
177
+ @staticmethod
178
+ def _use_client_cert_effective():
179
+ """Returns whether client certificate should be used for mTLS if the
180
+ google-auth version supports should_use_client_cert automatic mTLS enablement.
181
+
182
+ Alternatively, read from the GOOGLE_API_USE_CLIENT_CERTIFICATE env var.
183
+
184
+ Returns:
185
+ bool: whether client certificate should be used for mTLS
186
+ Raises:
187
+ ValueError: (If using a version of google-auth without should_use_client_cert and
188
+ GOOGLE_API_USE_CLIENT_CERTIFICATE is set to an unexpected value.)
189
+ """
190
+ # check if google-auth version supports should_use_client_cert for automatic mTLS enablement
191
+ if hasattr(mtls, "should_use_client_cert"): # pragma: NO COVER
192
+ return mtls.should_use_client_cert()
193
+ else: # pragma: NO COVER
194
+ # if unsupported, fallback to reading from env var
195
+ use_client_cert_str = os.getenv(
196
+ "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false"
197
+ ).lower()
198
+ if use_client_cert_str not in ("true", "false"):
199
+ raise ValueError(
200
+ "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be"
201
+ " either `true` or `false`"
202
+ )
203
+ return use_client_cert_str == "true"
204
+
177
205
  @classmethod
178
206
  def from_service_account_info(cls, info: dict, *args, **kwargs):
179
207
  """Creates an instance of this client using the provided credentials
@@ -339,12 +367,8 @@ class RouteOptimizationClient(metaclass=RouteOptimizationClientMeta):
339
367
  )
340
368
  if client_options is None:
341
369
  client_options = client_options_lib.ClientOptions()
342
- use_client_cert = os.getenv("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false")
370
+ use_client_cert = RouteOptimizationClient._use_client_cert_effective()
343
371
  use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto")
344
- if use_client_cert not in ("true", "false"):
345
- raise ValueError(
346
- "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`"
347
- )
348
372
  if use_mtls_endpoint not in ("auto", "never", "always"):
349
373
  raise MutualTLSChannelError(
350
374
  "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`"
@@ -352,7 +376,7 @@ class RouteOptimizationClient(metaclass=RouteOptimizationClientMeta):
352
376
 
353
377
  # Figure out the client cert source to use.
354
378
  client_cert_source = None
355
- if use_client_cert == "true":
379
+ if use_client_cert:
356
380
  if client_options.client_cert_source:
357
381
  client_cert_source = client_options.client_cert_source
358
382
  elif mtls.has_default_client_cert_source():
@@ -384,20 +408,14 @@ class RouteOptimizationClient(metaclass=RouteOptimizationClientMeta):
384
408
  google.auth.exceptions.MutualTLSChannelError: If GOOGLE_API_USE_MTLS_ENDPOINT
385
409
  is not any of ["auto", "never", "always"].
386
410
  """
387
- use_client_cert = os.getenv(
388
- "GOOGLE_API_USE_CLIENT_CERTIFICATE", "false"
389
- ).lower()
411
+ use_client_cert = RouteOptimizationClient._use_client_cert_effective()
390
412
  use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto").lower()
391
413
  universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN")
392
- if use_client_cert not in ("true", "false"):
393
- raise ValueError(
394
- "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`"
395
- )
396
414
  if use_mtls_endpoint not in ("auto", "never", "always"):
397
415
  raise MutualTLSChannelError(
398
416
  "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`"
399
417
  )
400
- return use_client_cert == "true", use_mtls_endpoint, universe_domain_env
418
+ return use_client_cert, use_mtls_endpoint, universe_domain_env
401
419
 
402
420
  @staticmethod
403
421
  def _get_client_cert_source(provided_cert_source, use_cert_flag):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: google-maps-routeoptimization
3
- Version: 0.2.0
3
+ Version: 0.3.0
4
4
  Summary: Google Maps Routeoptimization API client library
5
5
  Home-page: https://github.com/googleapis/google-cloud-python/tree/main/packages/google-maps-routeoptimization
6
6
  Author: Google LLC
@@ -174,12 +174,19 @@ def test__read_environment_variables():
174
174
  with mock.patch.dict(
175
175
  os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"}
176
176
  ):
177
- with pytest.raises(ValueError) as excinfo:
178
- RouteOptimizationClient._read_environment_variables()
179
- assert (
180
- str(excinfo.value)
181
- == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`"
182
- )
177
+ if not hasattr(google.auth.transport.mtls, "should_use_client_cert"):
178
+ with pytest.raises(ValueError) as excinfo:
179
+ RouteOptimizationClient._read_environment_variables()
180
+ assert (
181
+ str(excinfo.value)
182
+ == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`"
183
+ )
184
+ else:
185
+ assert RouteOptimizationClient._read_environment_variables() == (
186
+ False,
187
+ "auto",
188
+ None,
189
+ )
183
190
 
184
191
  with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}):
185
192
  assert RouteOptimizationClient._read_environment_variables() == (
@@ -218,6 +225,105 @@ def test__read_environment_variables():
218
225
  )
219
226
 
220
227
 
228
+ def test_use_client_cert_effective():
229
+ # Test case 1: Test when `should_use_client_cert` returns True.
230
+ # We mock the `should_use_client_cert` function to simulate a scenario where
231
+ # the google-auth library supports automatic mTLS and determines that a
232
+ # client certificate should be used.
233
+ if hasattr(google.auth.transport.mtls, "should_use_client_cert"):
234
+ with mock.patch(
235
+ "google.auth.transport.mtls.should_use_client_cert", return_value=True
236
+ ):
237
+ assert RouteOptimizationClient._use_client_cert_effective() is True
238
+
239
+ # Test case 2: Test when `should_use_client_cert` returns False.
240
+ # We mock the `should_use_client_cert` function to simulate a scenario where
241
+ # the google-auth library supports automatic mTLS and determines that a
242
+ # client certificate should NOT be used.
243
+ if hasattr(google.auth.transport.mtls, "should_use_client_cert"):
244
+ with mock.patch(
245
+ "google.auth.transport.mtls.should_use_client_cert", return_value=False
246
+ ):
247
+ assert RouteOptimizationClient._use_client_cert_effective() is False
248
+
249
+ # Test case 3: Test when `should_use_client_cert` is unavailable and the
250
+ # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is set to "true".
251
+ if not hasattr(google.auth.transport.mtls, "should_use_client_cert"):
252
+ with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "true"}):
253
+ assert RouteOptimizationClient._use_client_cert_effective() is True
254
+
255
+ # Test case 4: Test when `should_use_client_cert` is unavailable and the
256
+ # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is set to "false".
257
+ if not hasattr(google.auth.transport.mtls, "should_use_client_cert"):
258
+ with mock.patch.dict(
259
+ os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "false"}
260
+ ):
261
+ assert RouteOptimizationClient._use_client_cert_effective() is False
262
+
263
+ # Test case 5: Test when `should_use_client_cert` is unavailable and the
264
+ # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is set to "True".
265
+ if not hasattr(google.auth.transport.mtls, "should_use_client_cert"):
266
+ with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "True"}):
267
+ assert RouteOptimizationClient._use_client_cert_effective() is True
268
+
269
+ # Test case 6: Test when `should_use_client_cert` is unavailable and the
270
+ # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is set to "False".
271
+ if not hasattr(google.auth.transport.mtls, "should_use_client_cert"):
272
+ with mock.patch.dict(
273
+ os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "False"}
274
+ ):
275
+ assert RouteOptimizationClient._use_client_cert_effective() is False
276
+
277
+ # Test case 7: Test when `should_use_client_cert` is unavailable and the
278
+ # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is set to "TRUE".
279
+ if not hasattr(google.auth.transport.mtls, "should_use_client_cert"):
280
+ with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "TRUE"}):
281
+ assert RouteOptimizationClient._use_client_cert_effective() is True
282
+
283
+ # Test case 8: Test when `should_use_client_cert` is unavailable and the
284
+ # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is set to "FALSE".
285
+ if not hasattr(google.auth.transport.mtls, "should_use_client_cert"):
286
+ with mock.patch.dict(
287
+ os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "FALSE"}
288
+ ):
289
+ assert RouteOptimizationClient._use_client_cert_effective() is False
290
+
291
+ # Test case 9: Test when `should_use_client_cert` is unavailable and the
292
+ # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is not set.
293
+ # In this case, the method should return False, which is the default value.
294
+ if not hasattr(google.auth.transport.mtls, "should_use_client_cert"):
295
+ with mock.patch.dict(os.environ, clear=True):
296
+ assert RouteOptimizationClient._use_client_cert_effective() is False
297
+
298
+ # Test case 10: Test when `should_use_client_cert` is unavailable and the
299
+ # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is set to an invalid value.
300
+ # The method should raise a ValueError as the environment variable must be either
301
+ # "true" or "false".
302
+ if not hasattr(google.auth.transport.mtls, "should_use_client_cert"):
303
+ with mock.patch.dict(
304
+ os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "unsupported"}
305
+ ):
306
+ with pytest.raises(ValueError):
307
+ RouteOptimizationClient._use_client_cert_effective()
308
+
309
+ # Test case 11: Test when `should_use_client_cert` is available and the
310
+ # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is set to an invalid value.
311
+ # The method should return False as the environment variable is set to an invalid value.
312
+ if hasattr(google.auth.transport.mtls, "should_use_client_cert"):
313
+ with mock.patch.dict(
314
+ os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "unsupported"}
315
+ ):
316
+ assert RouteOptimizationClient._use_client_cert_effective() is False
317
+
318
+ # Test case 12: Test when `should_use_client_cert` is available and the
319
+ # `GOOGLE_API_USE_CLIENT_CERTIFICATE` environment variable is unset. Also,
320
+ # the GOOGLE_API_CONFIG environment variable is unset.
321
+ if hasattr(google.auth.transport.mtls, "should_use_client_cert"):
322
+ with mock.patch.dict(os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": ""}):
323
+ with mock.patch.dict(os.environ, {"GOOGLE_API_CERTIFICATE_CONFIG": ""}):
324
+ assert RouteOptimizationClient._use_client_cert_effective() is False
325
+
326
+
221
327
  def test__get_client_cert_source():
222
328
  mock_provided_cert_source = mock.Mock()
223
329
  mock_default_cert_source = mock.Mock()
@@ -591,17 +697,6 @@ def test_route_optimization_client_client_options(
591
697
  == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`"
592
698
  )
593
699
 
594
- # Check the case GOOGLE_API_USE_CLIENT_CERTIFICATE has unsupported value.
595
- with mock.patch.dict(
596
- os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"}
597
- ):
598
- with pytest.raises(ValueError) as excinfo:
599
- client = client_class(transport=transport_name)
600
- assert (
601
- str(excinfo.value)
602
- == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`"
603
- )
604
-
605
700
  # Check the case quota_project_id is provided
606
701
  options = client_options.ClientOptions(quota_project_id="octopus")
607
702
  with mock.patch.object(transport_class, "__init__") as patched:
@@ -837,6 +932,119 @@ def test_route_optimization_client_get_mtls_endpoint_and_cert_source(client_clas
837
932
  assert api_endpoint == mock_api_endpoint
838
933
  assert cert_source is None
839
934
 
935
+ # Test the case GOOGLE_API_USE_CLIENT_CERTIFICATE is "Unsupported".
936
+ with mock.patch.dict(
937
+ os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"}
938
+ ):
939
+ if hasattr(google.auth.transport.mtls, "should_use_client_cert"):
940
+ mock_client_cert_source = mock.Mock()
941
+ mock_api_endpoint = "foo"
942
+ options = client_options.ClientOptions(
943
+ client_cert_source=mock_client_cert_source,
944
+ api_endpoint=mock_api_endpoint,
945
+ )
946
+ api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source(
947
+ options
948
+ )
949
+ assert api_endpoint == mock_api_endpoint
950
+ assert cert_source is None
951
+
952
+ # Test cases for mTLS enablement when GOOGLE_API_USE_CLIENT_CERTIFICATE is unset.
953
+ test_cases = [
954
+ (
955
+ # With workloads present in config, mTLS is enabled.
956
+ {
957
+ "version": 1,
958
+ "cert_configs": {
959
+ "workload": {
960
+ "cert_path": "path/to/cert/file",
961
+ "key_path": "path/to/key/file",
962
+ }
963
+ },
964
+ },
965
+ mock_client_cert_source,
966
+ ),
967
+ (
968
+ # With workloads not present in config, mTLS is disabled.
969
+ {
970
+ "version": 1,
971
+ "cert_configs": {},
972
+ },
973
+ None,
974
+ ),
975
+ ]
976
+ if hasattr(google.auth.transport.mtls, "should_use_client_cert"):
977
+ for config_data, expected_cert_source in test_cases:
978
+ env = os.environ.copy()
979
+ env.pop("GOOGLE_API_USE_CLIENT_CERTIFICATE", None)
980
+ with mock.patch.dict(os.environ, env, clear=True):
981
+ config_filename = "mock_certificate_config.json"
982
+ config_file_content = json.dumps(config_data)
983
+ m = mock.mock_open(read_data=config_file_content)
984
+ with mock.patch("builtins.open", m):
985
+ with mock.patch.dict(
986
+ os.environ, {"GOOGLE_API_CERTIFICATE_CONFIG": config_filename}
987
+ ):
988
+ mock_api_endpoint = "foo"
989
+ options = client_options.ClientOptions(
990
+ client_cert_source=mock_client_cert_source,
991
+ api_endpoint=mock_api_endpoint,
992
+ )
993
+ (
994
+ api_endpoint,
995
+ cert_source,
996
+ ) = client_class.get_mtls_endpoint_and_cert_source(options)
997
+ assert api_endpoint == mock_api_endpoint
998
+ assert cert_source is expected_cert_source
999
+
1000
+ # Test cases for mTLS enablement when GOOGLE_API_USE_CLIENT_CERTIFICATE is unset(empty).
1001
+ test_cases = [
1002
+ (
1003
+ # With workloads present in config, mTLS is enabled.
1004
+ {
1005
+ "version": 1,
1006
+ "cert_configs": {
1007
+ "workload": {
1008
+ "cert_path": "path/to/cert/file",
1009
+ "key_path": "path/to/key/file",
1010
+ }
1011
+ },
1012
+ },
1013
+ mock_client_cert_source,
1014
+ ),
1015
+ (
1016
+ # With workloads not present in config, mTLS is disabled.
1017
+ {
1018
+ "version": 1,
1019
+ "cert_configs": {},
1020
+ },
1021
+ None,
1022
+ ),
1023
+ ]
1024
+ if hasattr(google.auth.transport.mtls, "should_use_client_cert"):
1025
+ for config_data, expected_cert_source in test_cases:
1026
+ env = os.environ.copy()
1027
+ env.pop("GOOGLE_API_USE_CLIENT_CERTIFICATE", "")
1028
+ with mock.patch.dict(os.environ, env, clear=True):
1029
+ config_filename = "mock_certificate_config.json"
1030
+ config_file_content = json.dumps(config_data)
1031
+ m = mock.mock_open(read_data=config_file_content)
1032
+ with mock.patch("builtins.open", m):
1033
+ with mock.patch.dict(
1034
+ os.environ, {"GOOGLE_API_CERTIFICATE_CONFIG": config_filename}
1035
+ ):
1036
+ mock_api_endpoint = "foo"
1037
+ options = client_options.ClientOptions(
1038
+ client_cert_source=mock_client_cert_source,
1039
+ api_endpoint=mock_api_endpoint,
1040
+ )
1041
+ (
1042
+ api_endpoint,
1043
+ cert_source,
1044
+ ) = client_class.get_mtls_endpoint_and_cert_source(options)
1045
+ assert api_endpoint == mock_api_endpoint
1046
+ assert cert_source is expected_cert_source
1047
+
840
1048
  # Test the case GOOGLE_API_USE_MTLS_ENDPOINT is "never".
841
1049
  with mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "never"}):
842
1050
  api_endpoint, cert_source = client_class.get_mtls_endpoint_and_cert_source()
@@ -887,18 +1095,6 @@ def test_route_optimization_client_get_mtls_endpoint_and_cert_source(client_clas
887
1095
  == "Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` must be `never`, `auto` or `always`"
888
1096
  )
889
1097
 
890
- # Check the case GOOGLE_API_USE_CLIENT_CERTIFICATE has unsupported value.
891
- with mock.patch.dict(
892
- os.environ, {"GOOGLE_API_USE_CLIENT_CERTIFICATE": "Unsupported"}
893
- ):
894
- with pytest.raises(ValueError) as excinfo:
895
- client_class.get_mtls_endpoint_and_cert_source()
896
-
897
- assert (
898
- str(excinfo.value)
899
- == "Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` must be either `true` or `false`"
900
- )
901
-
902
1098
 
903
1099
  @pytest.mark.parametrize(
904
1100
  "client_class", [RouteOptimizationClient, RouteOptimizationAsyncClient]
@@ -4050,6 +4246,7 @@ def test_route_optimization_grpc_asyncio_transport_channel():
4050
4246
 
4051
4247
  # Remove this test when deprecated arguments (api_mtls_endpoint, client_cert_source) are
4052
4248
  # removed from grpc/grpc_asyncio transport constructor.
4249
+ @pytest.mark.filterwarnings("ignore::FutureWarning")
4053
4250
  @pytest.mark.parametrize(
4054
4251
  "transport_class",
4055
4252
  [
@@ -1,97 +0,0 @@
1
- # -*- coding: utf-8 -*-
2
- # Copyright 2025 Google LLC
3
- #
4
- # Licensed under the Apache License, Version 2.0 (the "License");
5
- # you may not use this file except in compliance with the License.
6
- # You may obtain a copy of the License at
7
- #
8
- # http://www.apache.org/licenses/LICENSE-2.0
9
- #
10
- # Unless required by applicable law or agreed to in writing, software
11
- # distributed under the License is distributed on an "AS IS" BASIS,
12
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
- # See the License for the specific language governing permissions and
14
- # limitations under the License.
15
- #
16
- from google.maps.routeoptimization_v1 import gapic_version as package_version
17
-
18
- __version__ = package_version.__version__
19
-
20
-
21
- from .services.route_optimization import (
22
- RouteOptimizationAsyncClient,
23
- RouteOptimizationClient,
24
- )
25
- from .types.route_optimization_service import (
26
- AggregatedMetrics,
27
- BatchOptimizeToursMetadata,
28
- BatchOptimizeToursRequest,
29
- BatchOptimizeToursResponse,
30
- BreakRule,
31
- DataFormat,
32
- DistanceLimit,
33
- GcsDestination,
34
- GcsSource,
35
- InjectedSolutionConstraint,
36
- InputConfig,
37
- Location,
38
- OptimizeToursLongRunningMetadata,
39
- OptimizeToursRequest,
40
- OptimizeToursResponse,
41
- OptimizeToursUriMetadata,
42
- OptimizeToursUriRequest,
43
- OptimizeToursUriResponse,
44
- OptimizeToursValidationError,
45
- OutputConfig,
46
- RouteModifiers,
47
- Shipment,
48
- ShipmentModel,
49
- ShipmentRoute,
50
- ShipmentTypeIncompatibility,
51
- ShipmentTypeRequirement,
52
- SkippedShipment,
53
- TimeWindow,
54
- TransitionAttributes,
55
- Uri,
56
- Vehicle,
57
- VehicleFullness,
58
- Waypoint,
59
- )
60
-
61
- __all__ = (
62
- "RouteOptimizationAsyncClient",
63
- "AggregatedMetrics",
64
- "BatchOptimizeToursMetadata",
65
- "BatchOptimizeToursRequest",
66
- "BatchOptimizeToursResponse",
67
- "BreakRule",
68
- "DataFormat",
69
- "DistanceLimit",
70
- "GcsDestination",
71
- "GcsSource",
72
- "InjectedSolutionConstraint",
73
- "InputConfig",
74
- "Location",
75
- "OptimizeToursLongRunningMetadata",
76
- "OptimizeToursRequest",
77
- "OptimizeToursResponse",
78
- "OptimizeToursUriMetadata",
79
- "OptimizeToursUriRequest",
80
- "OptimizeToursUriResponse",
81
- "OptimizeToursValidationError",
82
- "OutputConfig",
83
- "RouteModifiers",
84
- "RouteOptimizationClient",
85
- "Shipment",
86
- "ShipmentModel",
87
- "ShipmentRoute",
88
- "ShipmentTypeIncompatibility",
89
- "ShipmentTypeRequirement",
90
- "SkippedShipment",
91
- "TimeWindow",
92
- "TransitionAttributes",
93
- "Uri",
94
- "Vehicle",
95
- "VehicleFullness",
96
- "Waypoint",
97
- )