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: Upload new data to existing file id
  
  Default url_opts='erase=true' throws exceptions on parse errors and deletes upload.
  
  See File REST API for url_opts (file upload)
docstr_tok: ["Upload","new","data","to","existing","file","id","Default","url_opts='erase=true","'","throws","exceptions","on","parse","errors","and","deletes","upload",".","See","File","REST","API","for","url_opts","(","file","upload",")"]
code: def post_arrow(
      self, arr: pa.Table, file_id: str, url_opts: str = "erase=true"
  ) -> dict:
      """
      Upload new data to existing file id
  
      Default url_opts='erase=true' throws exceptions on parse errors and deletes upload.
  
      See File REST API for url_opts (file upload)
      """
  
      sub_path = f"api/v2/upload/files/{file_id}"
      tok = self.uploader.token
  
      res = self.uploader.post_arrow_generic(
          sub_path, tok, arr, url_opts
      )
  
      try:
          out = res.json()
          logger.debug("Server upload file response: %s", out)
          if not out["is_valid"]:
              if out["is_uploaded"]:
                  raise RuntimeError(
                      "Uploaded file contents but cannot parse (file_id still valid), see errors",
                      out["errors"],
                  )
              else:
                  raise RuntimeError(
                      "Erased uploaded file contents upon failure (file_id still valid), see errors",
                      out["errors"],
                  )
          return out
      except Exception as e:
          logger.error(
              "Failed uploading file: %s", res.text, exc_info=True
          )
          raise e
  
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 3 for calling the ArrowFileUploader obj's underlying member method code with example usage: obj.post_arrow(arr, file_id, url_opts) and returns: out