code: def get_cache(self, key, **kwargs):
      import boto3, botocore
  
      try:
          print_verbose(f"Get S3 Cache: key: {key}")
          # Download the data from S3
          cached_response = self.s3_client.get_object(
              Bucket=self.bucket_name, Key=key
          )
  
          if cached_response != None:
              # cached_response is in `b{} convert it to ModelResponse
              cached_response = (
                  cached_response["Body"].read().decode("utf-8")
              )  # Convert bytes to string
              try:
                  cached_response = json.loads(
                      cached_response
                  )  # Convert string to dictionary
              except Exception as e:
                  cached_response = ast.literal_eval(cached_response)
          if type(cached_response) is not dict:
              cached_response = dict(cached_response)
          print_verbose(
              f"Got S3 Cache: key: {key}, cached_response {cached_response}. Type Response {type(cached_response)}"
          )
  
          return cached_response
      except botocore.exceptions.ClientError as e:
          if e.response["Error"]["Code"] == "NoSuchKey":
              print_verbose(
                  f"S3 Cache: The specified key '{key}' does not exist in the S3 bucket."
              )
              return None
  
      except Exception as e:
          # NON blocking - notify users S3 is throwing an exception
          traceback.print_exc()
          print_verbose(
              f"S3 Caching: get_cache() - Got exception from S3: {e}"
          )
  
imports: import litellm
  import time, logging
  import json, traceback, ast, hashlib
  from typing import Optional, Literal, List, Union, Any
  from openai._models import BaseModel
label_desc: Use image node_id 3 for calling the S3Cache obj's underlying member method code with example usage: obj.get_cache(key) and returns: cached_response, None