class_docstr: Have one place to retrieve data from Yahoo API in order to ease caching and speed up operations.
  Singleton means one session one cookie shared by all threads.
class_docstr_tok: ["Have","one","place","to","retrieve","data","from","Yahoo","API","in","order","to","ease","caching","and","speed","up","operations",".","Singleton","means","one","session","one","cookie","shared","by","all","threads","."]
code: def get(
      self,
      url,
      user_agent_headers=None,
      params=None,
      proxy=None,
      timeout=30,
  ):
      # Important: treat input arguments as immutable.
  
      if len(url) > 200:
          utils.get_yf_logger().debug(f"url={url[:200]}...")
      else:
          utils.get_yf_logger().debug(f"url={url}")
      utils.get_yf_logger().debug(f"params={params}")
      proxy = self._get_proxy(proxy)
  
      if params is None:
          params = {}
      if "crumb" in params:
          raise Exception(
              "Don't manually add 'crumb' to params dict, let data.py handle it"
          )
  
      cookie, crumb, strategy = self._get_cookie_and_crumb()
      if crumb is not None:
          crumbs = {"crumb": crumb}
      else:
          crumbs = {}
      if strategy == "basic" and cookie is not None:
          # Basic cookie strategy adds cookie to GET parameters
          cookies = {cookie.name: cookie.value}
      else:
          cookies = None
  
      request_args = {
          "url": url,
          "params": {**params, **crumbs},
          "cookies": cookies,
          "proxies": proxy,
          "timeout": timeout,
          "headers": user_agent_headers or self.user_agent_headers,
      }
      response = self._session.get(**request_args)
      utils.get_yf_logger().debug(
          f"response code={response.status_code}"
      )
      if response.status_code >= 400:
          # Retry with other cookie strategy
          if strategy == "basic":
              self._set_cookie_strategy("csrf")
          else:
              self._set_cookie_strategy("basic")
          cookie, crumb, strategy = self._get_cookie_and_crumb(
              proxy, timeout
          )
          request_args["params"]["crumb"] = crumb
          if strategy == "basic":
              request_args["cookies"] = {cookie.name: cookie.value}
          response = self._session.get(**request_args)
          utils.get_yf_logger().debug(
              f"response code={response.status_code}"
          )
  
      return response
  
imports: import functools
  from functools import lru_cache
  import requests
  from bs4 import BeautifulSoup
  import datetime
  from frozendict import frozendict
  from .None import utils, cache
  import threading
label_desc: Use image node_id 14 for calling the YfData obj's underlying member method code with example usage: obj.get(url, user_agent_headers, params, proxy, timeout) and returns: response