18

Paramiko's SFTPClient apparently does not have an exists method. This is my current implementation:

def rexists(sftp, path):
    """os.path.exists for paramiko's SCP object
    """
    try:
        sftp.stat(path)
    except IOError, e:
        if 'No such file' in str(e):
            return False
        raise
    else:
        return True

Is there a better way to do this? Checking for substring in Exception messages is pretty ugly and can be unreliable.

Sridhar Ratnakumar
  • 81,433
  • 63
  • 146
  • 187

3 Answers3

21

See the errno module for constants defining all those error codes. Also, it's a bit clearer to use the errno attribute of the exception than the expansion of the __init__ args, so I'd do this:

except IOError, e: # or "as" if you're using Python 3.0
  if e.errno == errno.ENOENT:
    ...
Matt Good
  • 3,027
  • 22
  • 15
  • This is probably the right way to do because stat() on a non existing file on a SFTP server via Paramiko will raise this particular exception with the errno.ENOENT error code: https://github.com/paramiko/paramiko/blob/master/paramiko/sftp_client.py#L722 – Devy Jun 17 '14 at 15:13
10

Paramiko literally raises FileNotFoundError

def sftp_exists(sftp, path):
    try:
        sftp.stat(path)
        return True
    except FileNotFoundError:
        return False
jslay
  • 479
  • 4
  • 9
6

There is no "exists" method defined for SFTP (not just paramiko), so your method is fine.

I think checking the errno is a little cleaner:

def rexists(sftp, path):
    """os.path.exists for paramiko's SCP object
    """
    try:
        sftp.stat(path)
    except IOError, e:
        if e[0] == 2:
            return False
        raise
    else:
        return True
JimB
  • 104,193
  • 13
  • 262
  • 255