class_docstr: Implement file API with focus on Arrow support
  
  Memoization in this class is based on reference equality, while plotter is based on hash.
  That means the plotter resolves different-identity value matches, so by the time ArrowFileUploader compares,
  identities are unified for faster reference-based checks.
  
  Example: Upload files with per-session memoization
      uploader : ArrowUploader
      arr : pa.Table
      afu = ArrowFileUploader(uploader)
  
      file1_id = afu.create_and_post_file(arr)[0]
      file2_id = afu.create_and_post_file(arr)[0]
  
      assert file1_id == file2_id # memoizes by default (memory-safe: weak refs)
  
  Example: Explicitly create a file and upload data for it
      uploader : ArrowUploader
      arr : pa.Table
      afu = ArrowFileUploader(uploader)
  
      file1_id = afu.create_file()
      afu.post_arrow(arr, file_id)
  
      file2_id = afu.create_file()
      afu.post_arrow(arr, file_id)
  
      assert file1_id != file2_id
class_docstr_tok: ["Implement","file","API","with","focus","on","Arrow","support","Memoization","in","this","class","is","based","on","reference","equality",",","while","plotter","is","based","on","hash",".","That","means","the","plotter","resolves","different-identity","value","matches",",","so","by","the","time","ArrowFileUploader","compares",",","identities","are","unified","for","faster","reference-based","checks",".","Example",":","Upload","files","with","per-session","memoization","uploader",":","ArrowUploader","arr",":","pa.Table","afu","=","ArrowFileUploader","(","uploader",")","file1_id","=","afu.create_and_post_file","(","arr",")","[","0","]","file2_id","=","afu.create_and_post_file","(","arr",")","[","0","]","assert","file1_id","==","file2_id","#","memoizes","by","default","(","memory-safe",":","weak","refs",")","Example",":","Explicitly","create","a","file","and","upload","data","for","it","uploader",":","ArrowUploader","arr",":","pa.Table","afu","=","ArrowFileUploader","(","uploader",")","file1_id","=","afu.create_file","(",")","afu.post_arrow","(","arr",",","file_id",")","file2_id","=","afu.create_file","(",")","afu.post_arrow","(","arr",",","file_id",")","assert","file1_id","!","=","file2_id"]
docstr: Create file and upload data for it.
  
  Default upload_url_opts='erase=true' throws exceptions on parse errors and deletes upload.
  
  Default memoize=True skips uploading 'arr' when previously uploaded in current session
  
  See File REST API for file_opts (file create) and upload_url_opts (file upload)
docstr_tok: ["Create","file","and","upload","data","for","it",".","Default","upload_url_opts='erase=true","'","throws","exceptions","on","parse","errors","and","deletes","upload",".","Default","memoize=True","skips","uploading","'arr","'","when","previously","uploaded","in","current","session","See","File","REST","API","for","file_opts","(","file","create",")","and","upload_url_opts","(","file","upload",")"]
code: def create_and_post_file(
      self,
      arr: pa.Table,
      file_id: Optional[str] = None,
      file_opts: dict = {},
      upload_url_opts: str = "erase=true",
      memoize: bool = True,
  ) -> Tuple[str, dict]:
      """
      Create file and upload data for it.
  
      Default upload_url_opts='erase=true' throws exceptions on parse errors and deletes upload.
  
      Default memoize=True skips uploading 'arr' when previously uploaded in current session
  
      See File REST API for file_opts (file create) and upload_url_opts (file upload)
      """
  
      if memoize:
          # FIXME if pa.Table was hashable, could do direct set/get map
          wrapped_table: WrappedTable
          val: MemoizedFileUpload
          for wrapped_table, val in DF_TO_FILE_ID_CACHE.items():
              if wrapped_table.arr is arr:
                  logger.debug(
                      "arrow->file_id memoization hit: %s", val.file_id
                  )
                  return val.file_id, val.output
          logger.debug(
              "arrow->file_id memoization miss (of %s)",
              len(DF_TO_FILE_ID_CACHE),
          )
  
      if file_id is None:
          file_id = self.create_file(file_opts)
  
      resp = self.post_arrow(arr, file_id, upload_url_opts)
      out = MemoizedFileUpload(file_id, resp)
  
      if memoize:
          wrapped = WrappedTable(arr)
          cache_arr(wrapped)
          DF_TO_FILE_ID_CACHE[wrapped] = out
          logger.debug("Memoized arrow->file_id %s", file_id)
  
      return out.file_id, out.output
  
file_path: pygraphistry/graphistry/ArrowFileUploader.py
imports: import pyarrow, requests, sys
  from functools import lru_cache
  from typing import Any, Tuple, Optional
  from weakref import WeakKeyDictionary
  from .util import setup_logger
label_desc: Use image node_id 4 for calling the ArrowFileUploader obj's underlying member method code with example usage: obj.create_and_post_file(arr, file_id, file_opts, upload_url_opts, memoize) and returns: out,  out, val,  val