views:

4248

answers:

5

I'm working on a simple tool that transfers files to a hard-coded location with the password also hard-coded. I'm a python novice, but thanks to ftplib, it was easy:

import ftplib

info= ('someuser', 'password')    #hard-coded

def putfile(file, site, dir, user=(), verbose=True):
    """
    upload a file by ftp to a site/directory
    login hard-coded, binary transfer
    """
    if verbose: print 'Uploading', file
    local = open(file, 'rb')    
    remote = ftplib.FTP(site)   
    remote.login(*user)         
    remote.cwd(dir)
    remote.storbinary('STOR ' + file, local, 1024)
    remote.quit()
    local.close()
    if verbose: print 'Upload done.'

if __name__ == '__main__':
    site = 'somewhere.com'            #hard-coded
    dir = './uploads/'                #hard-coded
    import sys, getpass
    putfile(sys.argv[1], site, dir, user=info)

The problem is that I can't find any library that supports sFTP. What's the normal way to do something like this securely?

Edit: Thanks to the answers here, I've gotten it working with Paramiko and this was the syntax.

import paramiko

host = "THEHOST.com"                    #hard-coded
port = 22
transport = paramiko.Transport((host, port))

password = "THEPASSWORD"                #hard-coded
username = "THEUSERNAME"                #hard-coded
transport.connect(username = username, password = password)

sftp = paramiko.SFTPClient.from_transport(transport)

import sys
path = './THETARGETDIRECTORY/' + sys.argv[1]    #hard-coded
localpath = sys.argv[1]
sftp.put(localpath, path)

sftp.close()
transport.close()
print 'Upload done.'

Thanks again!

+2  A: 

Twisted can help you with what you are doing, check out their documentation, there are plenty of examples. Also it is a mature product with a big developer/user community behind it.

+16  A: 

Paramiko supports SFTP. I've used it, and I've used Twisted. Both have their place, but you might find it easier to start with Paramiko.

Brian Clapper
yepp, paramiko is the way to go (super easy to use), its a bit tricky to find the windows package of pycrypto which is a dependency.
Mauli
Thank you. It took me a while to figure out how to install the package due to the lack of installation instructions in the readme but it was exactly what I needed!
Mark Wilbur
+2  A: 

I'd stick with a pure Python solution, but it's not true that there aren't Windows ssh options. Cygwin has one, for example, and there are plenty more.

Daniel
Thank you for the advice. I've updated the question to clarify what I meant.
Mark Wilbur
A: 

I'm trying to modify your code to accept globbing of file names i.e. glob.glob("*.txt)

I'm failing. Below is all I have changed. Any clues would help.

localpath = glob.glob(sys.argv[1]) for each in localpath: sftp.put(localpath, path)

sftp.close() transport.close() print 'Upload done.'

Fabric supports globbing for local filenames. See my answer: http://stackoverflow.com/questions/432385/sftp-in-python-platform-independent/1866984#1866984
hopla
+2  A: 

If you want easy and simple, you might also want to look at Fabric. It's an automated deployment tool like Ruby's Capistrano, but simpler and ofcourse for Python. It's build on top of Paramiko.

You might not want to do 'automated deployment' but Fabric would suit your use case perfectly none the less. To show you how simple Fabric is: the fab file and command for your script would look like this (not tested, but 99% sure it will work):

fab_putfile.py:

from fabric.api import *

env.hosts = ['THEHOST.com']
env.user = 'THEUSER'
env.password = 'THEPASSWORD'

def put_file(file):
    put(file, './THETARGETDIRECTORY/') # it's copied into the target directory

Then run the file with the fab command:

fab -f fab_putfile.py put_file:file=./path/to/my/file

And your done! :)

hopla