title: Python retry to open the file
body: <p>What is the best practice to try to open the file and retry after n seconds?</p>
  
  <p>Currently, I do:</p>
  
  <pre><code>import os
  from os import path
  import shutil
  
  dir_path = path.abspath(path.join("foo", "bar"))
  destination_path = path.abspath(path.join("foo", "dest_dir"))
  
  for f in dir_path:
      try:
          # try to open the file if the file isn't used any longer
          file_opened = open(f, 'r')
          # move the file on successful opening
          shutil.move(file_opened, destination_path)
          file_opened.close()
      except IOError:
          return False
  </code></pre>
  
  <p>So, at the moment I do not handle the exception. I think about creation of extra function to open the file and recall the function on excepth with time.sleep(n)</p>
  
  <p>However, I am sure there must be something else ... </p>
  
  <p>I do not use </p>
  
  <pre><code>with open(f, 'rb') as file_opened: 
      do whatever` 
  </code></pre>
  
  <p>EDIT:</p>
  
  <p>One process creates the file and I want Python process to move the file once I am sure the file writting / creation is completed. So, I have added shutil.move in the above code to show the whole situation.</p>
  
  <p>EDIT: </p>
  
  <p>Please find below the code I have developed to solve the problem. I ended with writing own custom solution to handle it:</p>
  
  <pre><code>import os
  from os import path
  import psutil
  from retry import retry
  import shutil
  from subprocess import check_output,Popen, PIPE
  import glob
  import time
  
  
  class FileHandler:
      def __init__(self, fn_source, dir_source):
          self.file_source_name = fn_source
          self.file_source_path = path.join(dir_source, self.file_source_name)
          self.dir_dest_path = path.join(dir_source, "test")
          self.file_dest_path = path.join(self.dir_dest_path, self.file_source_name)
  
      def check_file(self):
          if os.path.exists(self.file_source_path):
              try:
                  os.rename(self.file_source_path, self.file_source_path)
                  print("file renamed")
                  return True
              except:
                  print("can not rename the file..retrying")
                  time.sleep(1)
                  self.check_file()
          else:
              print("source file does not exist...retrying")
              time.sleep(5)
              self.check_file()
  
      def check_destination(self):
          if os.path.exists(self.file_source_path) and not os.path.exists(self.file_dest_path):
              return True
          elif os.path.exists(self.file_source_path) and os.path.exists(self.file_dest_path):
              try:
                  print(self.file_dest_path, self.file_source_name)
                  os.remove(self.file_dest_path)
                  return True
              except Exception as e:
                  print("can not remove the file..retrying")
                  time.sleep(5)
                  self.check_destination()
  
      def move_file(self):
          if self.check_destination():
              print(self.file_source_path)
              shutil.move(self.file_source_path, self.file_dest_path)
              print("moved", str(self.file_source_path))
              return True
          else:
              print("can not move the file..retrying")
              time.sleep(1)
              self.move_file()
  
      def file_ops(self):
          if self.check_file():
              self.move_file()
          else:
              print("source does not exist")
              time.sleep(1)
              self.file_ops()
          return True
  
  
  def each_file_ops(fn, dir_source):
      fh = FileHandler(fn, dir_source)
      return fh.file_ops()
  
  
  def main(dir_source):
      dir_files = glob.glob(path.join(dir_source, '*.txt'))
      if dir_files:
          [each_file_ops(f, dir_source) for f in dir_files]
      else:
          print("source dir is empty")
          time.sleep(1)
          main(dir_source)
  
  
  if __name__ == '__main__':
      main(path.join(""))
  </code></pre>