Python 中的 SFTP?(平台独立)

2025-01-22 08:45:00
admin
原创
76
摘要:问题描述:我正在开发一个简单的工具,可以将文件传输到硬编码位置,密码也是硬编码的。我是 Python 新手,但多亏了 ftplib,这很容易:import ftplib info= ('someuser', 'password') #hard-coded def putfile(file, site...

问题描述:

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

再次感谢!


解决方案 1:

Paramiko支持 SFTP。我用过它,也用过 Twisted。两者都各有用途,但你可能会发现从 Paramiko 开始更容易。

解决方案 2:

您应该检查 pysftp https://pypi.python.org/pypi/pysftp 它依赖于 paramiko,但将最常见的用例包装到仅几行代码中。

import pysftp
import sys

path = './THETARGETDIRECTORY/' + sys.argv[1]    #hard-coded
localpath = sys.argv[1]

host = "THEHOST.com"                    #hard-coded
password = "THEPASSWORD"                #hard-coded
username = "THEUSERNAME"                #hard-coded

with pysftp.Connection(host, username=username, password=password) as sftp:
    sftp.put(localpath, path)

print 'Upload done.'

解决方案 3:

这是使用 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 是一个易于使用的 sftp 模块,它利用了 paramiko 和 pycrypto。它为 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 的命令和信息请见此处。

解决方案 4:

如果你想要简单易用,你可能还想看看Fabric。它是一种自动化部署工具,类似于 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

您已经完成了!:)

解决方案 5:

fsspec是一个很好的选择,它提供了一个类似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()

还值得注意的是,fsspec 在实现中使用了 paramiko 。

解决方案 6:

使用 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)

解决方案 7:

Twisted可以帮助您完成工作,请查看其文档,其中有大量示例。此外,它是一款成熟的产品,背后有庞大的开发人员/用户社区。

解决方案 8:

Paramiko 太慢了。使用 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)

解决方案 9:

有很多答案提到了 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

解决方案 10:

PyFilesystem及其sshfs是一种选择。它在底层使用 Paramiko,并在顶层提供更好的独立于平台的接口。

import fs

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

或者

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

解决方案 11:

这是一个通用函数,它将把任何给定的 sftp url 下载到指定路径

from urllib.parse import urlparse
import paramiko

url = 'sftp://username:password@hostname/filepath.txt'

def sftp_download(url, dest):
    url = urlparse(url)
    with paramiko.Transport((url.hostname, 22)) as transport:
        transport.connect(None,url.username,url.password)
        with paramiko.SFTPClient.from_transport(transport) as sftp:
            sftp.get(url.path, dest)

使用

sftp_download(url, "/tmp/filepath.txt")
相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   1565  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1354  
  信创国产芯片作为信息技术创新的核心领域,对于推动国家自主可控生态建设具有至关重要的意义。在全球科技竞争日益激烈的背景下,实现信息技术的自主可控,摆脱对国外技术的依赖,已成为保障国家信息安全和产业可持续发展的关键。国产芯片作为信创产业的基石,其发展水平直接影响着整个信创生态的构建与完善。通过不断提升国产芯片的技术实力、产...
国产信创系统   21  
  信创生态建设旨在实现信息技术领域的自主创新和安全可控,涵盖了从硬件到软件的全产业链。随着数字化转型的加速,信创生态建设的重要性日益凸显,它不仅关乎国家的信息安全,更是推动产业升级和经济高质量发展的关键力量。然而,在推进信创生态建设的过程中,面临着诸多复杂且严峻的挑战,需要深入剖析并寻找切实可行的解决方案。技术创新难题技...
信创操作系统   27  
  信创产业作为国家信息技术创新发展的重要领域,对于保障国家信息安全、推动产业升级具有关键意义。而国产芯片作为信创产业的核心基石,其研发进展备受关注。在信创国产芯片的研发征程中,面临着诸多复杂且艰巨的难点,这些难点犹如一道道关卡,阻碍着国产芯片的快速发展。然而,科研人员和相关企业并未退缩,积极探索并提出了一系列切实可行的解...
国产化替代产品目录   28  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用