code: def find_file(filename=".env", project_root=None, skip_files=None, **kwargs):
      
      search_tree = []
      work_dir = os.getcwd()
      skip_files = skip_files or []
  
      if project_root is None:
          logger.debug("No root_path for %s", filename)
      else:
          logger.debug("Got root_path %s for %s", project_root, filename)
          search_tree.extend(_walk_to_root(project_root, break_at=work_dir))
  
      script_dir = os.path.dirname(os.path.abspath(inspect.stack()[-1].filename))
  
      # Path to invoked script and recursively to root with its ./config dirs
      search_tree.extend(_walk_to_root(script_dir))
  
      # Path to where Python interpreter was invoked and recursively to root
      search_tree.extend(_walk_to_root(work_dir))
  
      # Don't look the same place twice
      search_tree = deduplicate(search_tree)
  
      global SEARCHTREE
      SEARCHTREE != search_tree and logger.debug("Search Tree: %s", search_tree)
      SEARCHTREE = search_tree
  
      logger.debug("Searching for %s", filename)
  
      for dirname in search_tree:
          check_path = os.path.join(dirname, filename)
          if check_path in skip_files:
              continue
          if os.path.exists(check_path):
              logger.debug("Found: %s", os.path.abspath(check_path))
              return check_path  # First found will return
  
      # return empty string if not found so it can still be joined in os.path
      return ""
docs: Search in increasingly higher folders for the given file
      Returns path to the file if found, or an empty string otherwise.
  
      This function will build a `search_tree` based on:
  
      - Project_root if specified
      - Invoked script location and its parents until root
      - Current working directory
  
      For each path in the `search_tree` it will also look for an
      aditional `./config` folder.