None

SFTP from Python

February 10, 2010

I had a need to pull some files off a remote server using SFTP. Previously, I've relied on using certificates for password-less login, but with this being a server I didn't have control over, I needed to use the password.

It turns out there is a python library called Paramiko which can do just this.

Installation

You'll need to install both pycrypto and paramiko. Pycrypto is available at http://www.amk.ca/python/code/crypto.html and installed fine on windows, but didn't work on Ubuntu, failing with a compile error from GCC:

src/hash_template.c:29: error: expected specifier-qualifier-list before 'PyObject_HEAD'
-snip-
error: Setup script exited with error: command 'gcc' failed with exit status 1

This was due to the fact that the python headers weren't installed. This can be fixed on Ubuntu/Debian by:

# apt-get install python-dev

Once that problem was solved, the install for pycrypto worked fine:

# python setup.py install

Next up, installing Paramiko:

# python setup.py install

Checking Installation

Spin up python and try and import paramiko:

$ python
Python 2.6.4 (r264:75706, Dec  7 2009, 18:43:55)
[GCC 4.4.1] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import paramiko
/usr/local/lib/python2.6/dist-packages/Crypto/Hash/SHA.py:6: 
DeprecationWarning: the sha module is deprecated; use the hashlib module instead
  from sha import *
/usr/local/lib/python2.6/dist-packages/Crypto/Hash/MD5.py:6: 
DeprecationWarning: the md5  module is deprecated; use hashlib instead
  from md5 import *
>>>

All was fine apart from some deprecated modules in python 2.6.

Connecting using SFTP

First we setup a log file

paramiko.util.log_to_file('/tmp/paramiko.log')

Next, we specify the host to connect to

host = 'example.co.uk'
port = 22
transport = paramiko.Transport((host, port))

Then, time for some security

password = 'myPassword'
username = 'myUsername'
transport.connect(username = username, password = password)

Next, we create an SFTP connection

sftp = paramiko.SFTPClient.from_transport(transport)

Then we specify the file to get (you can also do a put) and get it:

filepath = '/home/path/to/remote/file/index.html'
localpath = '/home/path/to/local/file/downloaded.html'
sftp.get(filepath, localpath)

Finally, we need to close the connection

sftp.close()
transport.close()

References

  • http://commandline.org.uk/python/sftp-python/
  • http://www.lag.net/paramiko/
  • http://www.amk.ca/python/code/crypto.html