class_docstr: Base class for the entire OO interface in Kubric.
  All objects, materials, lights, and cameras inherit from Asset.
  
  An assets have a UID, is hashable, have traits that can be observed (by external objects),
  support inserting keyframes for certain traits, and track linked (external) objects.
  
  Traits:
    name: The basename used to create uids (defaults to __class__.name)
    uid: an unique identifier auto-generated from self.name (e.g. "name", "name.001" , ...)
    background: TODO(klausg)
    metadata: TODO(klausg)
class_docstr_tok: ["Base","class","for","the","entire","OO","interface","in","Kubric",".","All","objects",",","materials",",","lights",",","and","cameras","inherit","from","Asset",".","An","assets","have","a","UID",",","is","hashable",",","have","traits","that","can","be","observed","(","by","external","objects",")",",","support","inserting","keyframes","for","certain","traits",",","and","track","linked","(","external",")","objects",".","Traits",":","name",":","The","basename","used","to","create","uids","(","defaults","to","__class__.name",")","uid",":","an","unique","identifier","auto-generated","from","self.name","(","e.g",".","``","name","''",",","``","name.001","''",",","...",")","background",":","TODO","(","klausg",")","metadata",":","TODO","(","klausg",")"]
code: def get_value_at(self, name, frame, interpolation="linear"):
      if name not in self.keyframes:
          # no animation data found, try retrieving static value
          return getattr(self, name)
      keyframes = self.keyframes[name]
  
      if frame in keyframes:
          return keyframes[frame]
  
      available_frames = sorted(keyframes.keys())
      right_idx = np.searchsorted(available_frames, frame)
      if right_idx == 0:
          return keyframes[available_frames[0]]
      if right_idx == len(available_frames):
          return keyframes[available_frames[-1]]
      left_frame, right_frame = (
          available_frames[right_idx - 1],
          available_frames[right_idx],
      )
  
      if interpolation == "const":
          return keyframes[left_frame]
      elif interpolation == "nearest":
          if abs(frame - left_frame) <= abs(frame - right_frame):
              return keyframes[left_frame]
          else:
              return keyframes[right_frame]
      elif interpolation == "linear":
          mixing = (frame - left_frame) / (right_frame - left_frame)
          left_val = np.array(keyframes[left_frame])
          right_val = np.array(keyframes[right_frame])
          return (1 - mixing) * left_val + mixing * right_val
  
imports: import collections
  import contextlib
  import munch
  import numpy
  import traitlets
  from kubric.utils import next_global_count
label_desc: Use image node_id 6 for calling the Asset obj's underlying member method code with example usage: obj.get_value_at(name, frame, interpolation) and returns: getattr, keyframes, keyframes, keyframes, keyframes, keyframes, keyframes, unknown