docstr: Fetches the screenshot, computes the thumbnail and caches the result
  
  :param user: If no user is given will use the current context
  :param cache: The cache to keep the thumbnail payload
  :param window_size: The window size from which will process the thumb
  :param thumb_size: The final thumbnail size
  :param force: Will force the computation even if it's already cached
  :return: Image payload
docstr_tok: ["Fetches","the","screenshot",",","computes","the","thumbnail","and","caches","the","result",":","param","user",":","If","no","user","is","given","will","use","the","current","context",":","param","cache",":","The","cache","to","keep","the","thumbnail","payload",":","param","window_size",":","The","window","size","from","which","will","process","the","thumb",":","param","thumb_size",":","The","final","thumbnail","size",":","param","force",":","Will","force","the","computation","even","if","it","'s","already","cached",":","return",":","Image","payload"]
code: def compute_and_cache(  # pylint: disable=too-many-arguments
      self,
      user: User = None,
      window_size: WindowSize | None = None,
      thumb_size: WindowSize | None = None,
      cache: Cache = None,
      force: bool = True,
  ) -> bytes | None:
      """
      Fetches the screenshot, computes the thumbnail and caches the result
  
      :param user: If no user is given will use the current context
      :param cache: The cache to keep the thumbnail payload
      :param window_size: The window size from which will process the thumb
      :param thumb_size: The final thumbnail size
      :param force: Will force the computation even if it's already cached
      :return: Image payload
      """
      cache_key = self.cache_key(window_size, thumb_size)
      window_size = window_size or self.window_size
      thumb_size = thumb_size or self.thumb_size
      if not force and cache and cache.get(cache_key):
          logger.info("Thumb already cached, skipping...")
          return None
      logger.info("Processing url for thumbnail: %s", cache_key)
  
      payload = None
  
      # Assuming all sorts of things can go wrong with Selenium
      try:
          payload = self.get_screenshot(
              user=user, window_size=window_size
          )
      except Exception as ex:  # pylint: disable=broad-except
          logger.warning(
              "Failed at generating thumbnail %s", ex, exc_info=True
          )
  
      if payload and window_size != thumb_size:
          try:
              payload = self.resize_image(
                  payload, thumb_size=thumb_size
              )
          except Exception as ex:  # pylint: disable=broad-except
              logger.warning(
                  "Failed at resizing thumbnail %s", ex, exc_info=True
              )
              payload = None
  
      if payload:
          logger.info("Caching thumbnail: %s", cache_key)
          cache.set(cache_key, payload)
          logger.info("Done caching thumbnail")
      return payload
  
imports: from __future__ import annotations
  import logging
  from io import BytesIO
  from typing import TYPE_CHECKING
  from flask import current_app
  from superset import feature_flag_manager
  from superset.utils.hashing import md5_sha_from_dict
  from superset.utils.urls import modify_url_query
  from superset.utils.webdriver import ChartStandaloneMode, DashboardStandaloneMode, WebDriver, WebDriverPlaywright, WebDriverSelenium, WindowSize
label_desc: Use image node_id 8 for calling the BaseScreenshot obj's underlying member method code with example usage: obj.compute_and_cache(user, window_size, thumb_size, cache, force) and returns: payload, None