docstr: Given a response from the Perspective server, resolve the Future
  with the response or an exception.
docstr_tok: ["Given","a","response","from","the","Perspective","server",",","resolve","the","Future","with","the","response","or","an","exception","."]
code: def _handle(self, msg):
      """Given a response from the Perspective server, resolve the Future
      with the response or an exception."""
      if not msg.get("data"):
          return
  
      handler = self._handlers.get(msg["data"].get("id"))
      if handler:
          future = handler.get("future", None)
          keep_alive = handler.get("keep_alive", False)
  
          if keep_alive and handler.get("callback_id"):
              # Must look up callback function and execute it, and then
              # return without re-setting the result of the Future.
              callback = self._callback_id_cache.get(
                  handler["callback_id"]
              )
              data = msg["data"]["data"]
              if data and isinstance(data, dict):
                  callback(**data)
              elif data:
                  callback(data)
              else:
                  callback()
              return
          elif future:
              if msg["data"].get("error"):
                  future.set_exception(
                      PerspectiveError(msg["data"]["error"])
                  )
              else:
                  cmd = handler.get("cmd", None)
  
                  if cmd == "view":
                      future.set_result(
                          PerspectiveViewProxy(
                              self, msg["data"]["data"]
                          )
                      )
                  elif cmd == "table":
                      future.set_result(
                          PerspectiveTableProxy(
                              self, msg["data"]["data"]
                          )
                      )
                  else:
                      future.set_result(msg["data"]["data"])
  
          if not keep_alive:
              del self._handlers[msg["data"]["id"]]
  
file_path: perspective/python/perspective/perspective/client/base.py
imports: import asyncio
  from random import random
  from ..core.exception import PerspectiveError
  from .table_api import PerspectiveTableProxy
  from .table_api import table
  from .view_api import PerspectiveViewProxy
label_desc: Use image node_id 3 for calling the PerspectiveClient obj's underlying member method code with example usage: obj._handle(msg) without return types