我正在开发一个简单的工具,可以将文件传输到一个硬编码的位置,密码也是硬编码的。我是一个python新手,但多亏了ftplib,它很容易:

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)

问题是我找不到任何支持sFTP的库。要安全地做这样的事情,正常的方法是什么?

编辑:感谢这里的答案,我已经得到了它与Paramiko工作,这是语法。

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.'

再次感谢!


当前回答

如果你想要简单,你可能还想看看面料。它是一个像Ruby的Capistrano一样的自动部署工具,但是更简单,当然对于Python来说。它建在Paramiko之上。

您可能不想进行“自动部署”,但Fabric仍然非常适合您的用例。为了向您展示Fabric有多简单:脚本的fab文件和命令看起来像这样(未经测试,但99%确定它可以工作):

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

然后使用fab命令运行该文件:

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

这样就完成了!:)

其他回答

下面是一个使用pysftp和私钥的示例。

import pysftp

def upload_file(file_path):

    private_key = "~/.ssh/your-key.pem"  # can use password keyword in Connection instead
    srv = pysftp.Connection(host="your-host", username="user-name", private_key=private_key)
    srv.chdir('/var/web/public_files/media/uploads')  # change directory on remote server
    srv.put(file_path)  # To download a file, replace put with get
    srv.close()  # Close connection

Pysftp是一个使用paramiko和pycrypto的易于使用的SFTP模块。它为sftp提供了一个简单的接口。你可以用pysftp做的其他事情非常有用:

data = srv.listdir()  # Get the directory and file listing in a list
srv.get(file_path)  # Download a file from remote server
srv.execute('pwd') # Execute a command on the server

这里有更多关于PySFTP的命令。

Paramiko支持SFTP。我用过,也用过扭曲。两者都有各自的位置,但您可能会发现从Paramiko开始更容易。

用RSA密钥,然后参考这里

代码片段:

import pysftp
import paramiko
from base64 import decodebytes

keydata = b"""AAAAB3NzaC1yc2EAAAADAQABAAABAQDl""" 
key = paramiko.RSAKey(data=decodebytes(keydata)) 
cnopts = pysftp.CnOpts()
cnopts.hostkeys.add(host, 'ssh-rsa', key)


with pysftp.Connection(host=host, username=username, password=password, cnopts=cnopts) as sftp:   
  with sftp.cd(directory):
    sftp.put(file_to_sent_to_ftp)

帕拉米柯太慢了。使用subprocess和shell,下面是一个例子:

remote_file_name = "filename"
remotedir = "/remote/dir"
localpath = "/local/file/dir"
    ftp_cmd_p = """
    #!/bin/sh
    lftp -u username,password sftp://ip:port <<EOF
    cd {remotedir}
    lcd {localpath}
    get {filename}
    EOF
    """
subprocess.call(ftp_cmd_p.format(remotedir=remotedir,
                                 localpath=localpath,
                                 filename=remote_file_name 
                                 ), 
                shell=True, stdout=sys.stdout, stderr=sys.stderr)

如果你想要简单,你可能还想看看面料。它是一个像Ruby的Capistrano一样的自动部署工具,但是更简单,当然对于Python来说。它建在Paramiko之上。

您可能不想进行“自动部署”,但Fabric仍然非常适合您的用例。为了向您展示Fabric有多简单:脚本的fab文件和命令看起来像这样(未经测试,但99%确定它可以工作):

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

然后使用fab命令运行该文件:

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

这样就完成了!:)