code: def run(self):
      if self._log_path is not None:
          print(f"Find logs at: {self._log_path}")
      for sync_item in self._sync_list:
          (
              tb_event_files,
              tb_logdirs,
              tb_root,
          ) = self._find_tfevent_files(sync_item)
          if os.path.isdir(sync_item):
              files = os.listdir(sync_item)
              filtered_files = list(
                  filter(lambda f: f.endswith(WANDB_SUFFIX), files)
              )
              if tb_root is None and (
                  check_and_warn_old(files) or len(filtered_files) != 1
              ):
                  print(f"Skipping directory: {sync_item}")
                  continue
              if len(filtered_files) > 0:
                  sync_item = os.path.join(sync_item, filtered_files[0])
          sync_tb = self._setup_tensorboard(
              tb_root, tb_logdirs, tb_event_files, sync_item
          )
          # If we're syncing tensorboard, let's use a tmp dir for images etc.
          root_dir = (
              TMPDIR.name if sync_tb else os.path.dirname(sync_item)
          )
  
          # When appending we are allowing a possible resume, ie the run
          # doesnt have to exist already
          resume = "allow" if self._append else None
  
          sm = sender.SendManager.setup(root_dir, resume=resume)
          if sync_tb:
              self._send_tensorboard(tb_root, tb_logdirs, sm)
              continue
  
          ds = datastore.DataStore()
          try:
              ds.open_for_scan(sync_item)
          except AssertionError as e:
              print(
                  f".wandb file is empty ({e}), skipping: {sync_item}"
              )
              continue
  
          # save exit for final send
          exit_pb = None
          finished = False
          shown = False
          while True:
              data = self._robust_scan(ds)
              if data is None:
                  break
              pb, exit_pb, cont = self._parse_pb(data, exit_pb)
              if exit_pb is not None:
                  finished = True
              if cont:
                  continue
              sm.send(pb)
              # send any records that were added in previous send
              while not sm._record_q.empty():
                  data = sm._record_q.get(block=True)
                  sm.send(data)
  
              if pb.control.req_resp:
                  result = sm._result_q.get(block=True)
                  result_type = result.WhichOneof("result_type")
                  if not shown and result_type == "run_result":
                      r = result.run_result.run
                      # TODO(jhr): hardcode until we have settings in sync
                      url = "{}/{}/{}/runs/{}".format(
                          self._app_url,
                          url_quote(r.entity),
                          url_quote(r.project),
                          url_quote(r.run_id),
                      )
                      print("Syncing: %s ... " % url, end="")
                      sys.stdout.flush()
                      shown = True
          sm.finish()
          # Only mark synced if the run actually finished
          if self._mark_synced and not self._view and finished:
              synced_file = f"{sync_item}{SYNCED_SUFFIX}"
              with open(synced_file, "w"):
                  pass
          print("done.")
  
imports: import datetime
  import fnmatch
  import os
  import queue
  import sys
  import tempfile
  import threading
  import time
  from typing import List, Optional
  from urllib.parse import quote
  import wandb
  from wandb.proto import wandb_internal_pb2
  from wandb.sdk.interface.interface_queue import InterfaceQueue
  from wandb.sdk.internal import context, datastore, handler, sender, tb_watcher
  from wandb.sdk.internal.settings_static import SettingsStatic
  from wandb.sdk.lib import filesystem
  from wandb.util import check_and_warn_old
label_desc: Use image node_id 7 for calling the SyncThread obj's underlying member method code with example usage: obj.run() without return types