1# Copyright 2019 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"""Client options class.
16
17Client options provide a consistent interface for user options to be defined
18across clients.
19
20You can pass a client options object to a client.
21
22.. code-block:: python
23
24 from google.api_core.client_options import ClientOptions
25 from google.cloud.vision_v1 import ImageAnnotatorClient
26
27 def get_client_cert():
28 # code to load client certificate and private key.
29 return client_cert_bytes, client_private_key_bytes
30
31 options = ClientOptions(api_endpoint="foo.googleapis.com",
32 client_cert_source=get_client_cert)
33
34 client = ImageAnnotatorClient(client_options=options)
35
36You can also pass a mapping object.
37
38.. code-block:: python
39
40 from google.cloud.vision_v1 import ImageAnnotatorClient
41
42 client = ImageAnnotatorClient(
43 client_options={
44 "api_endpoint": "foo.googleapis.com",
45 "client_cert_source" : get_client_cert
46 })
47
48
49"""
50
51from typing import Callable, Mapping, Optional, Sequence, Tuple
52import warnings
53
54from google.api_core import general_helpers
55
56
57class ClientOptions(object):
58 """Client Options used to set options on clients.
59
60 Args:
61 api_endpoint (Optional[str]): The desired API endpoint, e.g.,
62 compute.googleapis.com
63 client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): A callback
64 which returns client certificate bytes and private key bytes both in
65 PEM format. ``client_cert_source`` and ``client_encrypted_cert_source``
66 are mutually exclusive.
67 client_encrypted_cert_source (Optional[Callable[[], Tuple[str, str, bytes]]]):
68 A callback which returns client certificate file path, encrypted
69 private key file path, and the passphrase bytes.``client_cert_source``
70 and ``client_encrypted_cert_source`` are mutually exclusive.
71 quota_project_id (Optional[str]): A project name that a client's
72 quota belongs to.
73 credentials_file (Optional[str]): Deprecated. A path to a file storing credentials.
74 ``credentials_file` and ``api_key`` are mutually exclusive. This argument will be
75 removed in the next major version of `google-api-core`.
76
77 .. warning::
78 Important: If you accept a credential configuration (credential JSON/File/Stream)
79 from an external source for authentication to Google Cloud Platform, you must
80 validate it before providing it to any Google API or client library. Providing an
81 unvalidated credential configuration to Google APIs or libraries can compromise
82 the security of your systems and data. For more information, refer to
83 `Validate credential configurations from external sources`_.
84
85 .. _Validate credential configurations from external sources:
86
87 https://cloud.google.com/docs/authentication/external/externally-sourced-credentials
88 scopes (Optional[Sequence[str]]): OAuth access token override scopes.
89 api_key (Optional[str]): Google API key. ``credentials_file`` and
90 ``api_key`` are mutually exclusive.
91 api_audience (Optional[str]): The intended audience for the API calls
92 to the service that will be set when using certain 3rd party
93 authentication flows. Audience is typically a resource identifier.
94 If not set, the service endpoint value will be used as a default.
95 An example of a valid ``api_audience`` is: "https://language.googleapis.com".
96 universe_domain (Optional[str]): The desired universe domain. This must match
97 the one in credentials. If not set, the default universe domain is
98 `googleapis.com`. If both `api_endpoint` and `universe_domain` are set,
99 then `api_endpoint` is used as the service endpoint. If `api_endpoint` is
100 not specified, the format will be `{service}.{universe_domain}`.
101
102 Raises:
103 ValueError: If both ``client_cert_source`` and ``client_encrypted_cert_source``
104 are provided, or both ``credentials_file`` and ``api_key`` are provided.
105 """
106
107 def __init__(
108 self,
109 api_endpoint: Optional[str] = None,
110 client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None,
111 client_encrypted_cert_source: Optional[
112 Callable[[], Tuple[str, str, bytes]]
113 ] = None,
114 quota_project_id: Optional[str] = None,
115 credentials_file: Optional[str] = None,
116 scopes: Optional[Sequence[str]] = None,
117 api_key: Optional[str] = None,
118 api_audience: Optional[str] = None,
119 universe_domain: Optional[str] = None,
120 ):
121 if credentials_file is not None:
122 warnings.warn(general_helpers._CREDENTIALS_FILE_WARNING, DeprecationWarning)
123
124 if client_cert_source and client_encrypted_cert_source:
125 raise ValueError(
126 "client_cert_source and client_encrypted_cert_source are mutually exclusive"
127 )
128 if api_key and credentials_file:
129 raise ValueError("api_key and credentials_file are mutually exclusive")
130 self.api_endpoint = api_endpoint
131 self.client_cert_source = client_cert_source
132 self.client_encrypted_cert_source = client_encrypted_cert_source
133 self.quota_project_id = quota_project_id
134 self.credentials_file = credentials_file
135 self.scopes = scopes
136 self.api_key = api_key
137 self.api_audience = api_audience
138 self.universe_domain = universe_domain
139
140 def __repr__(self) -> str:
141 return "ClientOptions: " + repr(self.__dict__)
142
143
144def from_dict(options: Mapping[str, object]) -> ClientOptions:
145 """Construct a client options object from a mapping object.
146
147 Args:
148 options (collections.abc.Mapping): A mapping object with client options.
149 See the docstring for ClientOptions for details on valid arguments.
150 """
151
152 client_options = ClientOptions()
153
154 for key, value in options.items():
155 if hasattr(client_options, key):
156 setattr(client_options, key, value)
157 else:
158 raise ValueError("ClientOptions does not accept an option '" + key + "'")
159
160 return client_options