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