我正在开发一个简单的工具,可以将文件传输到一个硬编码的位置,密码也是硬编码的。我是一个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.'

再次感谢!


当前回答

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

其他回答

Twisted可以帮助你做你正在做的事情,看看他们的文档,有很多例子。此外,它是一个成熟的产品,背后有一个庞大的开发者/用户社区。

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

带有sshfs的PyFilesystem是一个选项。它在引子下使用Paramiko,并在上面提供了一个更好的平台独立界面。

import fs

sf = fs.open_fs("sftp://[user[:password]@]host[:port]/[directory]")
sf.makedir('my_dir')

or

from fs.sshfs import SSHFS
sf = SSHFS(...

fspec是一个很好的选择,它提供了一个类似sftp实现的文件系统。

from fsspec.implementations.sftp import SFTPFileSystem
fs = SFTPFileSystem(host=host, username=username, password=password)

# list a directory
fs.ls("/")

# open a file
with fs.open(file_name) as file:
    content = file.read()

同样值得注意的是,fspec在实现中使用了paramiko。

有很多答案都提到了pysftp,因此,如果您想要一个围绕pysftp的上下文管理器包装器,这里有一个解决方案,它的代码更少,使用时看起来像下面这样

path = "sftp://user:p@ssw0rd@test.com/path/to/file.txt"

# Read a file
with open_sftp(path) as f:
    s = f.read() 
print s

# Write to a file
with open_sftp(path, mode='w') as f:
    f.write("Some content.") 

(更完整的)示例:http://www.prschmid.com/2016/09/simple-opensftp-context-manager-for.html

这个上下文管理器恰好有自动重试逻辑,以防止您第一次无法连接(令人惊讶的是,在生产环境中,这种情况发生的频率比您预期的要高……)

open_sftp的上下文管理器要点:https://gist.github.com/prschmid/80a19c22012e42d4d6e791c1e4eb8515