class_docstr: General interaction with gRPC servers.
  
  :param grpc_conn_id: The connection ID to use when fetching connection info.
  :param interceptors: a list of gRPC interceptor objects which would be applied
      to the connected gRPC channel. None by default.
      Each interceptor should based on or extends the four
      official gRPC interceptors, eg, UnaryUnaryClientInterceptor,
      UnaryStreamClientInterceptor, StreamUnaryClientInterceptor,
      StreamStreamClientInterceptor.
  :param custom_connection_func: The customized connection function to return gRPC channel.
      A callable that accepts the connection as its only arg.
class_docstr_tok: ["General","interaction","with","gRPC","servers",".",":","param","grpc_conn_id",":","The","connection","ID","to","use","when","fetching","connection","info",".",":","param","interceptors",":","a","list","of","gRPC","interceptor","objects","which","would","be","applied","to","the","connected","gRPC","channel",".","None","by","default",".","Each","interceptor","should","based","on","or","extends","the","four","official","gRPC","interceptors",",","eg",",","UnaryUnaryClientInterceptor",",","UnaryStreamClientInterceptor",",","StreamUnaryClientInterceptor",",","StreamStreamClientInterceptor",".",":","param","custom_connection_func",":","The","customized","connection","function","to","return","gRPC","channel",".","A","callable","that","accepts","the","connection","as","its","only","arg","."]
docstr: Call gRPC function and yield response to caller.
docstr_tok: ["Call","gRPC","function","and","yield","response","to","caller","."]
code: def run(
      self,
      stub_class: Callable,
      call_func: str,
      streaming: bool = False,
      data: dict | None = None,
  ) -> Generator:
      """Call gRPC function and yield response to caller."""
      if data is None:
          data = {}
      with self.get_conn() as channel:
          stub = stub_class(channel)
          try:
              rpc_func = getattr(stub, call_func)
              response = rpc_func(**data)
              if not streaming:
                  yield response
              else:
                  yield from response
          except grpc.RpcError as ex:
              self.log.exception(
                  "Error occurred when calling the grpc service: %s, method: %s \
                      status code: %s, error details: %s",
                  stub.__class__.__name__,
                  call_func,
                  ex.code(),
                  ex.details(),
              )
              raise ex
  
file_path: airflow/airflow/providers/grpc/hooks/grpc.py
imports: from __future__ import annotations
  from typing import Any, Callable, Generator
  import grpc
  from google import auth
  from google.auth import jwt
  from google.auth.transport import grpc, requests
  from airflow.exceptions import AirflowConfigException
  from airflow.hooks.base import BaseHook
label_desc: Use image node_id 4 for calling the GrpcHook obj's underlying member method code with example usage: obj.run(stub_class, call_func, streaming, data) without return types