سؤال
أنا أعمل على أداة بسيطة تنقل الملفات إلى موقع مشفر بكلمة مرور مشفرة أيضًا.أنا مبتدئ في لغة بايثون، ولكن بفضل 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.
نصائح أخرى
ويجب أن تحقق من 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.'
إذا كنت تريد سهلة وبسيطة، قد ترغب أيضا أن ننظر إلى نسيج . إنها أداة التوزيع الآلي مثل كابيسترانو روبي، ولكن أبسط وبالطبع لبيثون. انها بناء على رأس Paramiko.
وأنت قد لا تريد أن تفعل "نشر الآلي" ولكن نسيج تناسب حالة استخدامك أيا تماما أقل. لتبين لكم كيف نسيج بسيط هو: أن ملف القوات المسلحة البوروندية والأوامر لالسيناريو الخاص بك تبدو هذه (لم تختبر، ولكن 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 -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 .. الأشياء الأخرى التي يمكنك القيام به مع 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 هنا .
ملتوية يمكن أن تساعدك مع ما تقومون به، وتحقق من وثائقها، وهناك الكثير من الأمثلة . كما أنه من نتاج ناضج مع كبير في مجتمع المطورين / المستخدم وراء ذلك.
ويمكنك استخدام pexpect حدة
child = pexpect.spawn ('/usr/bin/sftp ' + user@ftp.site.com )
child.expect ('.* password:')
child.sendline (your_password)
child.expect ('sftp> ')
child.sendline ('dir')
child.expect ('sftp> ')
file_list = child.before
child.sendline ('bye')
وأنا لم تختبر هذا ولكن يجب أن تعمل
وParamiko بطيء جدا. استخدام فرعي أو جانبي وشركة شل، وهنا مثال:
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)
ومع RSA مفتاح ثم الرجوع هنا
مقتطف:
import pysftp
import paramiko
from base64 import decodebytes
keydata = b"""L+WsiL5VL51ecJi3LVjmblkAdUTU+xbmXmUArIU5+8N6ua76jO/+T"""
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)
هناك مجموعة من الإجابات التي تشير إلى 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