class_docstr: Hook for Google Cloud Spanner APIs.
  
  All the methods in the hook where project_id is used must be called with
  keyword arguments rather than positional.
class_docstr_tok: ["Hook","for","Google","Cloud","Spanner","APIs",".","All","the","methods","in","the","hook","where","project_id","is","used","must","be","called","with","keyword","arguments","rather","than","positional","."]
docstr: Provides a client for interacting with the Cloud Spanner API.
  
  :param project_id: The ID of the Google Cloud project.
  :return: Client
docstr_tok: ["Provides","a","client","for","interacting","with","the","Cloud","Spanner","API",".",":","param","project_id",":","The","ID","of","the","Google","Cloud","project",".",":","return",":","Client"]
code: def _get_client(self, project_id: str) -> Client:
      """
      Provides a client for interacting with the Cloud Spanner API.
  
      :param project_id: The ID of the Google Cloud project.
      :return: Client
      """
      if not self._client:
          self._client = Client(
              project=project_id,
              credentials=self.get_credentials(),
              client_info=CLIENT_INFO,
          )
      return self._client
  
imports: from __future__ import annotations
  from typing import TYPE_CHECKING, Callable, NamedTuple, Sequence
  from google.api_core.exceptions import AlreadyExists, GoogleAPICallError
  from google.cloud.spanner_v1.client import Client
  from sqlalchemy import create_engine
  from airflow.exceptions import AirflowException
  from airflow.providers.common.sql.hooks.sql import DbApiHook
  from airflow.providers.google.common.consts import CLIENT_INFO
  from airflow.providers.google.common.hooks.base_google import GoogleBaseHook, get_field
label_desc: Use image node_id 2 for calling the SpannerHook obj's underlying member method code with example usage: obj._get_client(project_id) and returns: self