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 __init__(self, session=None):
      self._session = session or requests.Session()
  
      try:
          self._session.cache
      except AttributeError:
          # Not caching
          self._session_is_caching = False
      else:
          # Is caching. This is annoying.
          # Can't simply use a non-caching session to fetch cookie & crumb,
          # because then the caching-session won't have cookie.
          self._session_is_caching = True
          from requests_cache import DO_NOT_CACHE
  
          self._expire_after = DO_NOT_CACHE
      self._crumb = None
      self._cookie = None
      if self._session_is_caching and self._cookie is None:
          utils.print_once(
              "WARNING: cookie & crumb does not work well with requests_cache. Am experimenting with 'expire_after=DO_NOT_CACHE', but you need to help stress-test."
          )
  
      # Default to using 'basic' strategy
      self._cookie_strategy = "basic"
      # If it fails, then fallback method is 'csrf'
      # self._cookie_strategy = 'csrf'
  
      self._cookie_lock = threading.Lock()
  
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 1 to create a new YfData object  with example: obj = YfData(session)