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# 
    16import inspect 
    17import json 
    18import pickle 
    19import logging as std_logging 
    20import warnings 
    21from typing import Awaitable, Callable, Dict, Optional, Sequence, Tuple, Union 
    22 
    23from google.api_core import gapic_v1 
    24from google.api_core import grpc_helpers_async 
    25from google.api_core import exceptions as core_exceptions 
    26from google.api_core import retry_async as retries 
    27from google.auth import credentials as ga_credentials  # type: ignore 
    28from google.auth.transport.grpc import SslCredentials  # type: ignore 
    29from google.protobuf.json_format import MessageToJson 
    30import google.protobuf.message 
    31 
    32import grpc  # type: ignore 
    33import proto  # type: ignore 
    34from grpc.experimental import aio  # type: ignore 
    35 
    36from google.cloud.logging_v2.types import logging 
    37from google.longrunning import operations_pb2  # type: ignore 
    38from google.protobuf import empty_pb2  # type: ignore 
    39from .base import LoggingServiceV2Transport, DEFAULT_CLIENT_INFO 
    40from .grpc import LoggingServiceV2GrpcTransport 
    41 
    42try: 
    43    from google.api_core import client_logging  # type: ignore 
    44 
    45    CLIENT_LOGGING_SUPPORTED = True  # pragma: NO COVER 
    46except ImportError:  # pragma: NO COVER 
    47    CLIENT_LOGGING_SUPPORTED = False 
    48 
    49_LOGGER = std_logging.getLogger(__name__) 
    50 
    51 
    52class _LoggingClientAIOInterceptor( 
    53    grpc.aio.UnaryUnaryClientInterceptor 
    54):  # pragma: NO COVER 
    55    async def intercept_unary_unary(self, continuation, client_call_details, request): 
    56        logging_enabled = CLIENT_LOGGING_SUPPORTED and _LOGGER.isEnabledFor( 
    57            std_logging.DEBUG 
    58        ) 
    59        if logging_enabled:  # pragma: NO COVER 
    60            request_metadata = client_call_details.metadata 
    61            if isinstance(request, proto.Message): 
    62                request_payload = type(request).to_json(request) 
    63            elif isinstance(request, google.protobuf.message.Message): 
    64                request_payload = MessageToJson(request) 
    65            else: 
    66                request_payload = f"{type(request).__name__}: {pickle.dumps(request)}" 
    67 
    68            request_metadata = { 
    69                key: value.decode("utf-8") if isinstance(value, bytes) else value 
    70                for key, value in request_metadata 
    71            } 
    72            grpc_request = { 
    73                "payload": request_payload, 
    74                "requestMethod": "grpc", 
    75                "metadata": dict(request_metadata), 
    76            } 
    77            _LOGGER.debug( 
    78                f"Sending request for {client_call_details.method}", 
    79                extra={ 
    80                    "serviceName": "google.logging.v2.LoggingServiceV2", 
    81                    "rpcName": str(client_call_details.method), 
    82                    "request": grpc_request, 
    83                    "metadata": grpc_request["metadata"], 
    84                }, 
    85            ) 
    86        response = await continuation(client_call_details, request) 
    87        if logging_enabled:  # pragma: NO COVER 
    88            response_metadata = await response.trailing_metadata() 
    89            # Convert gRPC metadata `<class 'grpc.aio._metadata.Metadata'>` to list of tuples 
    90            metadata = ( 
    91                dict([(k, str(v)) for k, v in response_metadata]) 
    92                if response_metadata 
    93                else None 
    94            ) 
    95            result = await response 
    96            if isinstance(result, proto.Message): 
    97                response_payload = type(result).to_json(result) 
    98            elif isinstance(result, google.protobuf.message.Message): 
    99                response_payload = MessageToJson(result) 
    100            else: 
    101                response_payload = f"{type(result).__name__}: {pickle.dumps(result)}" 
    102            grpc_response = { 
    103                "payload": response_payload, 
    104                "metadata": metadata, 
    105                "status": "OK", 
    106            } 
    107            _LOGGER.debug( 
    108                f"Received response to rpc {client_call_details.method}.", 
    109                extra={ 
    110                    "serviceName": "google.logging.v2.LoggingServiceV2", 
    111                    "rpcName": str(client_call_details.method), 
    112                    "response": grpc_response, 
    113                    "metadata": grpc_response["metadata"], 
    114                }, 
    115            ) 
    116        return response 
    117 
    118 
    119class LoggingServiceV2GrpcAsyncIOTransport(LoggingServiceV2Transport): 
    120    """gRPC AsyncIO backend transport for LoggingServiceV2. 
    121 
    122    Service for ingesting and querying logs. 
    123 
    124    This class defines the same methods as the primary client, so the 
    125    primary client can load the underlying transport implementation 
    126    and call it. 
    127 
    128    It sends protocol buffers over the wire using gRPC (which is built on 
    129    top of HTTP/2); the ``grpcio`` package must be installed. 
    130    """ 
    131 
    132    _grpc_channel: aio.Channel 
    133    _stubs: Dict[str, Callable] = {} 
    134 
    135    @classmethod 
    136    def create_channel( 
    137        cls, 
    138        host: str = "logging.googleapis.com", 
    139        credentials: Optional[ga_credentials.Credentials] = None, 
    140        credentials_file: Optional[str] = None, 
    141        scopes: Optional[Sequence[str]] = None, 
    142        quota_project_id: Optional[str] = None, 
    143        **kwargs, 
    144    ) -> aio.Channel: 
    145        """Create and return a gRPC AsyncIO channel object. 
    146        Args: 
    147            host (Optional[str]): The host for the channel to use. 
    148            credentials (Optional[~.Credentials]): The 
    149                authorization credentials to attach to requests. These 
    150                credentials identify this application to the service. If 
    151                none are specified, the client will attempt to ascertain 
    152                the credentials from the environment. 
    153            credentials_file (Optional[str]): A file with credentials that can 
    154                be loaded with :func:`google.auth.load_credentials_from_file`. 
    155            scopes (Optional[Sequence[str]]): A optional list of scopes needed for this 
    156                service. These are only used when credentials are not specified and 
    157                are passed to :func:`google.auth.default`. 
    158            quota_project_id (Optional[str]): An optional project to use for billing 
    159                and quota. 
    160            kwargs (Optional[dict]): Keyword arguments, which are passed to the 
    161                channel creation. 
    162        Returns: 
    163            aio.Channel: A gRPC AsyncIO channel object. 
    164        """ 
    165 
    166        return grpc_helpers_async.create_channel( 
    167            host, 
    168            credentials=credentials, 
    169            credentials_file=credentials_file, 
    170            quota_project_id=quota_project_id, 
    171            default_scopes=cls.AUTH_SCOPES, 
    172            scopes=scopes, 
    173            default_host=cls.DEFAULT_HOST, 
    174            **kwargs, 
    175        ) 
    176 
    177    def __init__( 
    178        self, 
    179        *, 
    180        host: str = "logging.googleapis.com", 
    181        credentials: Optional[ga_credentials.Credentials] = None, 
    182        credentials_file: Optional[str] = None, 
    183        scopes: Optional[Sequence[str]] = None, 
    184        channel: Optional[Union[aio.Channel, Callable[..., aio.Channel]]] = None, 
    185        api_mtls_endpoint: Optional[str] = None, 
    186        client_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]] = None, 
    187        ssl_channel_credentials: Optional[grpc.ChannelCredentials] = None, 
    188        client_cert_source_for_mtls: Optional[Callable[[], Tuple[bytes, bytes]]] = None, 
    189        quota_project_id: Optional[str] = None, 
    190        client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, 
    191        always_use_jwt_access: Optional[bool] = False, 
    192        api_audience: Optional[str] = None, 
    193    ) -> None: 
    194        """Instantiate the transport. 
    195 
    196        Args: 
    197            host (Optional[str]): 
    198                 The hostname to connect to (default: 'logging.googleapis.com'). 
    199            credentials (Optional[google.auth.credentials.Credentials]): The 
    200                authorization credentials to attach to requests. These 
    201                credentials identify the application to the service; if none 
    202                are specified, the client will attempt to ascertain the 
    203                credentials from the environment. 
    204                This argument is ignored if a ``channel`` instance is provided. 
    205            credentials_file (Optional[str]): A file with credentials that can 
    206                be loaded with :func:`google.auth.load_credentials_from_file`. 
    207                This argument is ignored if a ``channel`` instance is provided. 
    208            scopes (Optional[Sequence[str]]): A optional list of scopes needed for this 
    209                service. These are only used when credentials are not specified and 
    210                are passed to :func:`google.auth.default`. 
    211            channel (Optional[Union[aio.Channel, Callable[..., aio.Channel]]]): 
    212                A ``Channel`` instance through which to make calls, or a Callable 
    213                that constructs and returns one. If set to None, ``self.create_channel`` 
    214                is used to create the channel. If a Callable is given, it will be called 
    215                with the same arguments as used in ``self.create_channel``. 
    216            api_mtls_endpoint (Optional[str]): Deprecated. The mutual TLS endpoint. 
    217                If provided, it overrides the ``host`` argument and tries to create 
    218                a mutual TLS channel with client SSL credentials from 
    219                ``client_cert_source`` or application default SSL credentials. 
    220            client_cert_source (Optional[Callable[[], Tuple[bytes, bytes]]]): 
    221                Deprecated. A callback to provide client SSL certificate bytes and 
    222                private key bytes, both in PEM format. It is ignored if 
    223                ``api_mtls_endpoint`` is None. 
    224            ssl_channel_credentials (grpc.ChannelCredentials): SSL credentials 
    225                for the grpc channel. It is ignored if a ``channel`` instance is provided. 
    226            client_cert_source_for_mtls (Optional[Callable[[], Tuple[bytes, bytes]]]): 
    227                A callback to provide client certificate bytes and private key bytes, 
    228                both in PEM format. It is used to configure a mutual TLS channel. It is 
    229                ignored if a ``channel`` instance or ``ssl_channel_credentials`` is provided. 
    230            quota_project_id (Optional[str]): An optional project to use for billing 
    231                and quota. 
    232            client_info (google.api_core.gapic_v1.client_info.ClientInfo): 
    233                The client info used to send a user-agent string along with 
    234                API requests. If ``None``, then default info will be used. 
    235                Generally, you only need to set this if you're developing 
    236                your own client library. 
    237            always_use_jwt_access (Optional[bool]): Whether self signed JWT should 
    238                be used for service account credentials. 
    239 
    240        Raises: 
    241            google.auth.exceptions.MutualTlsChannelError: If mutual TLS transport 
    242              creation failed for any reason. 
    243          google.api_core.exceptions.DuplicateCredentialArgs: If both ``credentials`` 
    244              and ``credentials_file`` are passed. 
    245        """ 
    246        self._grpc_channel = None 
    247        self._ssl_channel_credentials = ssl_channel_credentials 
    248        self._stubs: Dict[str, Callable] = {} 
    249 
    250        if api_mtls_endpoint: 
    251            warnings.warn("api_mtls_endpoint is deprecated", DeprecationWarning) 
    252        if client_cert_source: 
    253            warnings.warn("client_cert_source is deprecated", DeprecationWarning) 
    254 
    255        if isinstance(channel, aio.Channel): 
    256            # Ignore credentials if a channel was passed. 
    257            credentials = None 
    258            self._ignore_credentials = True 
    259            # If a channel was explicitly provided, set it. 
    260            self._grpc_channel = channel 
    261            self._ssl_channel_credentials = None 
    262        else: 
    263            if api_mtls_endpoint: 
    264                host = api_mtls_endpoint 
    265 
    266                # Create SSL credentials with client_cert_source or application 
    267                # default SSL credentials. 
    268                if client_cert_source: 
    269                    cert, key = client_cert_source() 
    270                    self._ssl_channel_credentials = grpc.ssl_channel_credentials( 
    271                        certificate_chain=cert, private_key=key 
    272                    ) 
    273                else: 
    274                    self._ssl_channel_credentials = SslCredentials().ssl_credentials 
    275 
    276            else: 
    277                if client_cert_source_for_mtls and not ssl_channel_credentials: 
    278                    cert, key = client_cert_source_for_mtls() 
    279                    self._ssl_channel_credentials = grpc.ssl_channel_credentials( 
    280                        certificate_chain=cert, private_key=key 
    281                    ) 
    282 
    283        # The base transport sets the host, credentials and scopes 
    284        super().__init__( 
    285            host=host, 
    286            credentials=credentials, 
    287            credentials_file=credentials_file, 
    288            scopes=scopes, 
    289            quota_project_id=quota_project_id, 
    290            client_info=client_info, 
    291            always_use_jwt_access=always_use_jwt_access, 
    292            api_audience=api_audience, 
    293        ) 
    294 
    295        if not self._grpc_channel: 
    296            # initialize with the provided callable or the default channel 
    297            channel_init = channel or type(self).create_channel 
    298            self._grpc_channel = channel_init( 
    299                self._host, 
    300                # use the credentials which are saved 
    301                credentials=self._credentials, 
    302                # Set ``credentials_file`` to ``None`` here as 
    303                # the credentials that we saved earlier should be used. 
    304                credentials_file=None, 
    305                scopes=self._scopes, 
    306                ssl_credentials=self._ssl_channel_credentials, 
    307                quota_project_id=quota_project_id, 
    308                options=[ 
    309                    ("grpc.max_send_message_length", -1), 
    310                    ("grpc.max_receive_message_length", -1), 
    311                ], 
    312            ) 
    313 
    314        self._interceptor = _LoggingClientAIOInterceptor() 
    315        self._grpc_channel._unary_unary_interceptors.append(self._interceptor) 
    316        self._logged_channel = self._grpc_channel 
    317        self._wrap_with_kind = ( 
    318            "kind" in inspect.signature(gapic_v1.method_async.wrap_method).parameters 
    319        ) 
    320        # Wrap messages. This must be done after self._logged_channel exists 
    321        self._prep_wrapped_messages(client_info) 
    322 
    323    @property 
    324    def grpc_channel(self) -> aio.Channel: 
    325        """Create the channel designed to connect to this service. 
    326 
    327        This property caches on the instance; repeated calls return 
    328        the same channel. 
    329        """ 
    330        # Return the channel from cache. 
    331        return self._grpc_channel 
    332 
    333    @property 
    334    def delete_log( 
    335        self, 
    336    ) -> Callable[[logging.DeleteLogRequest], Awaitable[empty_pb2.Empty]]: 
    337        r"""Return a callable for the delete log method over gRPC. 
    338 
    339        Deletes all the log entries in a log for the \_Default Log 
    340        Bucket. The log reappears if it receives new entries. Log 
    341        entries written shortly before the delete operation might not be 
    342        deleted. Entries received after the delete operation with a 
    343        timestamp before the operation will be deleted. 
    344 
    345        Returns: 
    346            Callable[[~.DeleteLogRequest], 
    347                    Awaitable[~.Empty]]: 
    348                A function that, when called, will call the underlying RPC 
    349                on the server. 
    350        """ 
    351        # Generate a "stub function" on-the-fly which will actually make 
    352        # the request. 
    353        # gRPC handles serialization and deserialization, so we just need 
    354        # to pass in the functions for each. 
    355        if "delete_log" not in self._stubs: 
    356            self._stubs["delete_log"] = self._logged_channel.unary_unary( 
    357                "/google.logging.v2.LoggingServiceV2/DeleteLog", 
    358                request_serializer=logging.DeleteLogRequest.serialize, 
    359                response_deserializer=empty_pb2.Empty.FromString, 
    360            ) 
    361        return self._stubs["delete_log"] 
    362 
    363    @property 
    364    def write_log_entries( 
    365        self, 
    366    ) -> Callable[ 
    367        [logging.WriteLogEntriesRequest], Awaitable[logging.WriteLogEntriesResponse] 
    368    ]: 
    369        r"""Return a callable for the write log entries method over gRPC. 
    370 
    371        Writes log entries to Logging. This API method is the 
    372        only way to send log entries to Logging. This method is 
    373        used, directly or indirectly, by the Logging agent 
    374        (fluentd) and all logging libraries configured to use 
    375        Logging. A single request may contain log entries for a 
    376        maximum of 1000 different resources (projects, 
    377        organizations, billing accounts or folders) 
    378 
    379        Returns: 
    380            Callable[[~.WriteLogEntriesRequest], 
    381                    Awaitable[~.WriteLogEntriesResponse]]: 
    382                A function that, when called, will call the underlying RPC 
    383                on the server. 
    384        """ 
    385        # Generate a "stub function" on-the-fly which will actually make 
    386        # the request. 
    387        # gRPC handles serialization and deserialization, so we just need 
    388        # to pass in the functions for each. 
    389        if "write_log_entries" not in self._stubs: 
    390            self._stubs["write_log_entries"] = self._logged_channel.unary_unary( 
    391                "/google.logging.v2.LoggingServiceV2/WriteLogEntries", 
    392                request_serializer=logging.WriteLogEntriesRequest.serialize, 
    393                response_deserializer=logging.WriteLogEntriesResponse.deserialize, 
    394            ) 
    395        return self._stubs["write_log_entries"] 
    396 
    397    @property 
    398    def list_log_entries( 
    399        self, 
    400    ) -> Callable[ 
    401        [logging.ListLogEntriesRequest], Awaitable[logging.ListLogEntriesResponse] 
    402    ]: 
    403        r"""Return a callable for the list log entries method over gRPC. 
    404 
    405        Lists log entries. Use this method to retrieve log entries that 
    406        originated from a project/folder/organization/billing account. 
    407        For ways to export log entries, see `Exporting 
    408        Logs <https://cloud.google.com/logging/docs/export>`__. 
    409 
    410        Returns: 
    411            Callable[[~.ListLogEntriesRequest], 
    412                    Awaitable[~.ListLogEntriesResponse]]: 
    413                A function that, when called, will call the underlying RPC 
    414                on the server. 
    415        """ 
    416        # Generate a "stub function" on-the-fly which will actually make 
    417        # the request. 
    418        # gRPC handles serialization and deserialization, so we just need 
    419        # to pass in the functions for each. 
    420        if "list_log_entries" not in self._stubs: 
    421            self._stubs["list_log_entries"] = self._logged_channel.unary_unary( 
    422                "/google.logging.v2.LoggingServiceV2/ListLogEntries", 
    423                request_serializer=logging.ListLogEntriesRequest.serialize, 
    424                response_deserializer=logging.ListLogEntriesResponse.deserialize, 
    425            ) 
    426        return self._stubs["list_log_entries"] 
    427 
    428    @property 
    429    def list_monitored_resource_descriptors( 
    430        self, 
    431    ) -> Callable[ 
    432        [logging.ListMonitoredResourceDescriptorsRequest], 
    433        Awaitable[logging.ListMonitoredResourceDescriptorsResponse], 
    434    ]: 
    435        r"""Return a callable for the list monitored resource 
    436        descriptors method over gRPC. 
    437 
    438        Lists the descriptors for monitored resource types 
    439        used by Logging. 
    440 
    441        Returns: 
    442            Callable[[~.ListMonitoredResourceDescriptorsRequest], 
    443                    Awaitable[~.ListMonitoredResourceDescriptorsResponse]]: 
    444                A function that, when called, will call the underlying RPC 
    445                on the server. 
    446        """ 
    447        # Generate a "stub function" on-the-fly which will actually make 
    448        # the request. 
    449        # gRPC handles serialization and deserialization, so we just need 
    450        # to pass in the functions for each. 
    451        if "list_monitored_resource_descriptors" not in self._stubs: 
    452            self._stubs[ 
    453                "list_monitored_resource_descriptors" 
    454            ] = self._logged_channel.unary_unary( 
    455                "/google.logging.v2.LoggingServiceV2/ListMonitoredResourceDescriptors", 
    456                request_serializer=logging.ListMonitoredResourceDescriptorsRequest.serialize, 
    457                response_deserializer=logging.ListMonitoredResourceDescriptorsResponse.deserialize, 
    458            ) 
    459        return self._stubs["list_monitored_resource_descriptors"] 
    460 
    461    @property 
    462    def list_logs( 
    463        self, 
    464    ) -> Callable[[logging.ListLogsRequest], Awaitable[logging.ListLogsResponse]]: 
    465        r"""Return a callable for the list logs method over gRPC. 
    466 
    467        Lists the logs in projects, organizations, folders, 
    468        or billing accounts. Only logs that have entries are 
    469        listed. 
    470 
    471        Returns: 
    472            Callable[[~.ListLogsRequest], 
    473                    Awaitable[~.ListLogsResponse]]: 
    474                A function that, when called, will call the underlying RPC 
    475                on the server. 
    476        """ 
    477        # Generate a "stub function" on-the-fly which will actually make 
    478        # the request. 
    479        # gRPC handles serialization and deserialization, so we just need 
    480        # to pass in the functions for each. 
    481        if "list_logs" not in self._stubs: 
    482            self._stubs["list_logs"] = self._logged_channel.unary_unary( 
    483                "/google.logging.v2.LoggingServiceV2/ListLogs", 
    484                request_serializer=logging.ListLogsRequest.serialize, 
    485                response_deserializer=logging.ListLogsResponse.deserialize, 
    486            ) 
    487        return self._stubs["list_logs"] 
    488 
    489    @property 
    490    def tail_log_entries( 
    491        self, 
    492    ) -> Callable[ 
    493        [logging.TailLogEntriesRequest], Awaitable[logging.TailLogEntriesResponse] 
    494    ]: 
    495        r"""Return a callable for the tail log entries method over gRPC. 
    496 
    497        Streaming read of log entries as they are ingested. 
    498        Until the stream is terminated, it will continue reading 
    499        logs. 
    500 
    501        Returns: 
    502            Callable[[~.TailLogEntriesRequest], 
    503                    Awaitable[~.TailLogEntriesResponse]]: 
    504                A function that, when called, will call the underlying RPC 
    505                on the server. 
    506        """ 
    507        # Generate a "stub function" on-the-fly which will actually make 
    508        # the request. 
    509        # gRPC handles serialization and deserialization, so we just need 
    510        # to pass in the functions for each. 
    511        if "tail_log_entries" not in self._stubs: 
    512            self._stubs["tail_log_entries"] = self._logged_channel.stream_stream( 
    513                "/google.logging.v2.LoggingServiceV2/TailLogEntries", 
    514                request_serializer=logging.TailLogEntriesRequest.serialize, 
    515                response_deserializer=logging.TailLogEntriesResponse.deserialize, 
    516            ) 
    517        return self._stubs["tail_log_entries"] 
    518 
    519    def _prep_wrapped_messages(self, client_info): 
    520        """Precompute the wrapped methods, overriding the base class method to use async wrappers.""" 
    521        self._wrapped_methods = { 
    522            self.delete_log: self._wrap_method( 
    523                self.delete_log, 
    524                default_retry=retries.AsyncRetry( 
    525                    initial=0.1, 
    526                    maximum=60.0, 
    527                    multiplier=1.3, 
    528                    predicate=retries.if_exception_type( 
    529                        core_exceptions.DeadlineExceeded, 
    530                        core_exceptions.InternalServerError, 
    531                        core_exceptions.ServiceUnavailable, 
    532                    ), 
    533                    deadline=60.0, 
    534                ), 
    535                default_timeout=60.0, 
    536                client_info=client_info, 
    537            ), 
    538            self.write_log_entries: self._wrap_method( 
    539                self.write_log_entries, 
    540                default_retry=retries.AsyncRetry( 
    541                    initial=0.1, 
    542                    maximum=60.0, 
    543                    multiplier=1.3, 
    544                    predicate=retries.if_exception_type( 
    545                        core_exceptions.DeadlineExceeded, 
    546                        core_exceptions.InternalServerError, 
    547                        core_exceptions.ServiceUnavailable, 
    548                    ), 
    549                    deadline=60.0, 
    550                ), 
    551                default_timeout=60.0, 
    552                client_info=client_info, 
    553            ), 
    554            self.list_log_entries: self._wrap_method( 
    555                self.list_log_entries, 
    556                default_retry=retries.AsyncRetry( 
    557                    initial=0.1, 
    558                    maximum=60.0, 
    559                    multiplier=1.3, 
    560                    predicate=retries.if_exception_type( 
    561                        core_exceptions.DeadlineExceeded, 
    562                        core_exceptions.InternalServerError, 
    563                        core_exceptions.ServiceUnavailable, 
    564                    ), 
    565                    deadline=60.0, 
    566                ), 
    567                default_timeout=60.0, 
    568                client_info=client_info, 
    569            ), 
    570            self.list_monitored_resource_descriptors: self._wrap_method( 
    571                self.list_monitored_resource_descriptors, 
    572                default_retry=retries.AsyncRetry( 
    573                    initial=0.1, 
    574                    maximum=60.0, 
    575                    multiplier=1.3, 
    576                    predicate=retries.if_exception_type( 
    577                        core_exceptions.DeadlineExceeded, 
    578                        core_exceptions.InternalServerError, 
    579                        core_exceptions.ServiceUnavailable, 
    580                    ), 
    581                    deadline=60.0, 
    582                ), 
    583                default_timeout=60.0, 
    584                client_info=client_info, 
    585            ), 
    586            self.list_logs: self._wrap_method( 
    587                self.list_logs, 
    588                default_retry=retries.AsyncRetry( 
    589                    initial=0.1, 
    590                    maximum=60.0, 
    591                    multiplier=1.3, 
    592                    predicate=retries.if_exception_type( 
    593                        core_exceptions.DeadlineExceeded, 
    594                        core_exceptions.InternalServerError, 
    595                        core_exceptions.ServiceUnavailable, 
    596                    ), 
    597                    deadline=60.0, 
    598                ), 
    599                default_timeout=60.0, 
    600                client_info=client_info, 
    601            ), 
    602            self.tail_log_entries: self._wrap_method( 
    603                self.tail_log_entries, 
    604                default_retry=retries.AsyncRetry( 
    605                    initial=0.1, 
    606                    maximum=60.0, 
    607                    multiplier=1.3, 
    608                    predicate=retries.if_exception_type( 
    609                        core_exceptions.DeadlineExceeded, 
    610                        core_exceptions.InternalServerError, 
    611                        core_exceptions.ServiceUnavailable, 
    612                    ), 
    613                    deadline=3600.0, 
    614                ), 
    615                default_timeout=3600.0, 
    616                client_info=client_info, 
    617            ), 
    618            self.cancel_operation: self._wrap_method( 
    619                self.cancel_operation, 
    620                default_timeout=None, 
    621                client_info=client_info, 
    622            ), 
    623            self.get_operation: self._wrap_method( 
    624                self.get_operation, 
    625                default_timeout=None, 
    626                client_info=client_info, 
    627            ), 
    628            self.list_operations: self._wrap_method( 
    629                self.list_operations, 
    630                default_timeout=None, 
    631                client_info=client_info, 
    632            ), 
    633        } 
    634 
    635    def _wrap_method(self, func, *args, **kwargs): 
    636        if self._wrap_with_kind:  # pragma: NO COVER 
    637            kwargs["kind"] = self.kind 
    638        return gapic_v1.method_async.wrap_method(func, *args, **kwargs) 
    639 
    640    def close(self): 
    641        return self._logged_channel.close() 
    642 
    643    @property 
    644    def kind(self) -> str: 
    645        return "grpc_asyncio" 
    646 
    647    @property 
    648    def cancel_operation( 
    649        self, 
    650    ) -> Callable[[operations_pb2.CancelOperationRequest], None]: 
    651        r"""Return a callable for the cancel_operation method over gRPC.""" 
    652        # Generate a "stub function" on-the-fly which will actually make 
    653        # the request. 
    654        # gRPC handles serialization and deserialization, so we just need 
    655        # to pass in the functions for each. 
    656        if "cancel_operation" not in self._stubs: 
    657            self._stubs["cancel_operation"] = self._logged_channel.unary_unary( 
    658                "/google.longrunning.Operations/CancelOperation", 
    659                request_serializer=operations_pb2.CancelOperationRequest.SerializeToString, 
    660                response_deserializer=None, 
    661            ) 
    662        return self._stubs["cancel_operation"] 
    663 
    664    @property 
    665    def get_operation( 
    666        self, 
    667    ) -> Callable[[operations_pb2.GetOperationRequest], operations_pb2.Operation]: 
    668        r"""Return a callable for the get_operation method over gRPC.""" 
    669        # Generate a "stub function" on-the-fly which will actually make 
    670        # the request. 
    671        # gRPC handles serialization and deserialization, so we just need 
    672        # to pass in the functions for each. 
    673        if "get_operation" not in self._stubs: 
    674            self._stubs["get_operation"] = self._logged_channel.unary_unary( 
    675                "/google.longrunning.Operations/GetOperation", 
    676                request_serializer=operations_pb2.GetOperationRequest.SerializeToString, 
    677                response_deserializer=operations_pb2.Operation.FromString, 
    678            ) 
    679        return self._stubs["get_operation"] 
    680 
    681    @property 
    682    def list_operations( 
    683        self, 
    684    ) -> Callable[ 
    685        [operations_pb2.ListOperationsRequest], operations_pb2.ListOperationsResponse 
    686    ]: 
    687        r"""Return a callable for the list_operations method over gRPC.""" 
    688        # Generate a "stub function" on-the-fly which will actually make 
    689        # the request. 
    690        # gRPC handles serialization and deserialization, so we just need 
    691        # to pass in the functions for each. 
    692        if "list_operations" not in self._stubs: 
    693            self._stubs["list_operations"] = self._logged_channel.unary_unary( 
    694                "/google.longrunning.Operations/ListOperations", 
    695                request_serializer=operations_pb2.ListOperationsRequest.SerializeToString, 
    696                response_deserializer=operations_pb2.ListOperationsResponse.FromString, 
    697            ) 
    698        return self._stubs["list_operations"] 
    699 
    700 
    701__all__ = ("LoggingServiceV2GrpcAsyncIOTransport",)