ट्विस्टेड कॉंच के साथ एक एसएफटीपी फ़ाइल स्थानांतरण करना कुछ अलग चरणों में शामिल है (ठीक है, यदि आप स्क्वांट करते हैं तो वे अलग हैं)। असल में, सबसे पहले आपको उस पर चल रहे एक एसएफटीपी उपप्रणाली के साथ एक चैनल के साथ एक कनेक्शन स्थापित करने की आवश्यकता है। वाह। फिर आप उस चैनल से जुड़े FileTransferClient इंस्टेंस के तरीकों का उपयोग कर सकते हैं जो आप जो भी एसएफटीपी ऑपरेशंस करना चाहते हैं उसे करने के लिए।
एसएसएच कनेक्शन सेट अप करने के लिए आवश्यक अनिवार्यता twisted.conch.client पैकेज में मॉड्यूल द्वारा प्रदान की गई API द्वारा आपके लिए देखभाल की जा सकती है। यहाँ एक समारोह है कि एक थोड़ा कम आश्चर्य की बात इंटरफ़ेस में twisted.conch.client.default.connect
की मामूली weirdness ऊपर लपेटता है:
from twisted.internet.defer import Deferred
from twisted.conch.scripts.cftp import ClientOptions
from twisted.conch.client.connect import connect
from twisted.conch.client.default import SSHUserAuthClient, verifyHostKey
def sftp(user, host, port):
options = ClientOptions()
options['host'] = host
options['port'] = port
conn = SFTPConnection()
conn._sftp = Deferred()
auth = SSHUserAuthClient(user, options, conn)
connect(host, port, options, verifyHostKey, auth)
return conn._sftp
यह समारोह एक उपयोगकर्ता नाम, होस्ट नाम (या IP पता), और पोर्ट नंबर लेता है और करने के लिए एक प्रमाणीकृत SSH कनेक्शन सेट दिए गए उपयोगकर्ता नाम से जुड़े खाते का उपयोग कर उस पते पर सर्वर।
दरअसल, यह उससे थोड़ा अधिक करता है, क्योंकि एसएफटीपी सेटअप यहां थोड़ा मिश्रित है। इस पल के लिए, SFTPConnection
और _sftp
को अनदेखा करें।
ClientOptions
मूल रूप से केवल एक फैंसी डिक्शनरी है जो connect
यह देखने में सक्षम होना चाहता है कि यह किससे कनेक्ट हो रहा है ताकि यह मेजबान कुंजी को सत्यापित कर सके।
SSHUserAuthClient
वह वस्तु है जो परिभाषित करती है कि प्रमाणीकरण कैसे होगा। यह वर्ग जानता है कि ~/.ssh
को देखने और स्थानीय एसएसएच एजेंट से बात करने जैसी सामान्य चीज़ों को कैसे आजमाएं। यदि आप बदलना चाहते हैं कि प्रमाणीकरण कैसे किया जाता है, तो यह ऑब्जेक्ट के साथ खेलने के लिए है। आप SSHUserAuthClient
उपखंड कर सकते हैं और getPassword
, getPublicKey
, getPrivateKey
, और/या signData
विधियों को ओवरराइड कर सकते हैं, या आप अपनी पूरी तरह से अलग वर्ग लिख सकते हैं जिसमें आपके पास जो भी प्रमाणीकरण तर्क है, वह है। यह देखने के लिए कार्यान्वयन पर एक नज़र डालें कि प्रमाणीकरण प्राप्त करने के लिए एसएसएच प्रोटोकॉल कार्यान्वयन किस तरीके पर कॉल करता है।
तो यह फ़ंक्शन एक एसएसएच कनेक्शन स्थापित करेगा और इसे प्रमाणित करेगा। ऐसा करने के बाद, SFTPConnection
उदाहरण खेल में आता है। ध्यान दें कि SSHUserAuthClient
एक तर्क के रूप में SFTPConnection
उदाहरण लेता है।एक बार प्रमाणीकरण सफल हो जाने पर, यह उस उदाहरण के कनेक्शन के नियंत्रण को बंद कर देता है। विशेष रूप से, उस उदाहरण में serviceStarted
कहा जाता है।
class SFTPConnection(SSHConnection):
def serviceStarted(self):
self.openChannel(SFTPSession())
बहुत ही सरल:: यहाँ SFTPConnection
वर्ग का पूरा कार्यान्वयन सब यह होता है खुला एक नया चैनल है। SFTPSession
उदाहरण यह उस नए चैनल के साथ बातचीत करने के लिए गुजरता है। यहाँ कैसे मैं SFTPSession
परिभाषित है:
class SFTPSession(SSHChannel):
name = 'session'
def channelOpen(self, whatever):
d = self.conn.sendRequest(
self, 'subsystem', NS('sftp'), wantReply=True)
d.addCallbacks(self._cbSFTP)
def _cbSFTP(self, result):
client = FileTransferClient()
client.makeConnection(self)
self.dataReceived = client.dataReceived
self.conn._sftp.callback(client)
SFTPConnection
साथ जैसा
, इस वर्ग के लिए एक विधि कहा जाता हो जाता है कि जब कनेक्शन इसके लिए तैयार है। इस मामले में, जब चैनल सफलतापूर्वक खोला जाता है, तो यह कहा जाता है, और विधि channelOpen
है।
अंत में, एसएफटीपी सबसिस्टम लॉन्च करने की आवश्यकताएं मौजूद हैं। तो channelOpen
उस उपप्रणाली को लॉन्च करने के लिए चैनल पर एक अनुरोध भेजता है। यह एक उत्तर मांगता है ताकि यह बता सके कि वह सफल रहा है (या असफल)। यह Deferred
पर कॉलबैक जोड़ता है, यह FileTransferClient
को अपने आप में हुक करने के लिए मिलता है।
FileTransferClient
उदाहरण वास्तव में कनेक्शन के इस चैनल पर चलने वाले बाइट्स को प्रारूपित और पार्स करेगा। दूसरे शब्दों में, यह का कार्यान्वयन केवल एसएफटीपी प्रोटोकॉल है। यह एसएसएच प्रोटोकॉल पर चल रहा है, जो इस उदाहरण के अन्य ऑब्जेक्ट्स का ख्याल रखता है। लेकिन जहां तक यह चिंतित है, यह dataReceived
विधि में बाइट प्राप्त करता है, उन्हें पार्स करता है और कॉलबैक के लिए डेटा भेजता है, और यह उन तरीकों की पेशकश करता है जो संरचित पायथन वस्तुओं को स्वीकार करते हैं, उन वस्तुओं को सही बाइट्स के रूप में स्वरूपित करते हैं, और उन्हें अपने परिवहन में लिखते हैं।
इनमें से कोई भी इसका उपयोग करने के लिए सीधे महत्वपूर्ण नहीं है, हालांकि। हालांकि, इसके साथ एसएफटीपी कार्यों को निष्पादित करने का उदाहरण देने से पहले, _sftp
विशेषता को कवर करें। यह इस नए जुड़े FileTransferClient
उदाहरण को किसी अन्य कोड के लिए उपलब्ध कराने के लिए मेरा कच्चा दृष्टिकोण है जो वास्तव में जानता है कि इसके साथ क्या किया जाए। एसएफटीपी सेटअप कोड को उस कोड से अलग करना जो वास्तव में एसएफटीपी कनेक्शन का उपयोग करता है, बाद वाले को बदलने के दौरान पूर्व का पुन: उपयोग करना आसान बनाता है।
तो Deferred
मैं sftp
में सेट FileTransferClient
_cbSFTP
में जुड़े हुए के साथ निकाल दिया जाता। और sftp
के फोन करने वाले मिल गया है कि Deferred
उन्हें लौटा ताकि कोड इस तरह कर सकते हैं: एक बाइट के लिए एक स्थानीय FileTransferClient
इंस्टेंस को जोड़ने के लिए सभी तरह से
def transfer(client):
d = client.makeDirectory('foobarbaz', {})
def cbDir(ignored):
print 'Made directory'
d.addCallback(cbDir)
return d
def main():
...
d = sftp(user, host, port)
d.addCallback(transfer)
तो सबसे पहले sftp
पूरे कनेक्शन सेट, स्ट्रीम जिसमें दूसरे छोर पर कुछ एसएसएच सर्वर का एसएफटीपी उपप्रणाली है, और फिर transfer
उस उदाहरण को लेता है और कुछ एसएफटीपी ऑपरेशन करने के लिए FileTransferClient
के तरीकों का उपयोग करके निर्देशिका बनाने के लिए इसका उपयोग करता है।
from sys import stdout
from twisted.python.log import startLogging, err
from twisted.internet import reactor
from twisted.internet.defer import Deferred
from twisted.conch.ssh.common import NS
from twisted.conch.scripts.cftp import ClientOptions
from twisted.conch.ssh.filetransfer import FileTransferClient
from twisted.conch.client.connect import connect
from twisted.conch.client.default import SSHUserAuthClient, verifyHostKey
from twisted.conch.ssh.connection import SSHConnection
from twisted.conch.ssh.channel import SSHChannel
class SFTPSession(SSHChannel):
name = 'session'
def channelOpen(self, whatever):
d = self.conn.sendRequest(
self, 'subsystem', NS('sftp'), wantReply=True)
d.addCallbacks(self._cbSFTP)
def _cbSFTP(self, result):
client = FileTransferClient()
client.makeConnection(self)
self.dataReceived = client.dataReceived
self.conn._sftp.callback(client)
class SFTPConnection(SSHConnection):
def serviceStarted(self):
self.openChannel(SFTPSession())
def sftp(user, host, port):
options = ClientOptions()
options['host'] = host
options['port'] = port
conn = SFTPConnection()
conn._sftp = Deferred()
auth = SSHUserAuthClient(user, options, conn)
connect(host, port, options, verifyHostKey, auth)
return conn._sftp
def transfer(client):
d = client.makeDirectory('foobarbaz', {})
def cbDir(ignored):
print 'Made directory'
d.addCallback(cbDir)
return d
def main():
startLogging(stdout)
user = 'exarkun'
host = 'localhost'
port = 22
d = sftp(user, host, port)
d.addCallback(transfer)
d.addErrback(err, "Problem with SFTP transfer")
d.addCallback(lambda ignored: reactor.stop())
reactor.run()
if __name__ == '__main__':
main()
makeDirectory
एक काफी सरल ऑपरेशन है:
यहां एक संपूर्ण कोड सूची है कि आप और कुछ SFTP सर्वर पर बनाई गई किसी निर्देशिका को देखने के लिए चलाने के लिए सक्षम होना चाहिए। makeDirectory
विधि Deferred
देता है जो निर्देशिका को बनाए जाने पर आग लगती है (या यदि ऐसा करने में कोई त्रुटि है)। फ़ाइल को स्थानांतरित करना थोड़ा अधिक शामिल है, क्योंकि अगर आप अपलोड करने के बजाए डाउनलोड कर रहे हैं तो आपको डेटा भेजने या परिभाषित करने के लिए डेटा को कैसे प्राप्त किया जाना चाहिए।
यदि आप FileTransferClient
के तरीकों के लिए दस्तावेज़ों को पढ़ते हैं, हालांकि, आपको यह देखना चाहिए कि वास्तविक फाइल स्थानांतरण के लिए, openFile
मुख्य रूप से ब्याज की है। यह आपको Deferred
देता है जो ISFTPFile प्रदाता के साथ आग लगती है। इस ऑब्जेक्ट में फ़ाइल सामग्री को पढ़ने और लिखने के तरीके हैं।
क्या आप समझा सकते हैं कि आप अधिक विशेष रूप से कैसे फंस गए हैं? जैसा कि आपका प्रश्न अब है, मैं इसका जवाब देने का एकमात्र तरीका एक पूर्ण कॉंच/एसएफटीपी ट्यूटोरियल लिखना चाहता हूं, जो एसओ पर 15 अंकों से अधिक काम करता है (कम से कम इस समय)। ;) लेकिन एक और विशिष्ट प्रश्न का एक आसान जवाब हो सकता है। –
@ जीन-पॉल अभी मैं _think_ मुझे t.c.s.f.FileTransferClient subclass करने की आवश्यकता है। मैं भी _think_ कि मुझे ऊपर से जुड़े उदाहरण के समान एक एसएसएच कनेक्शन खोलने की जरूरत है। मैं t.c.s.f.FileTransferClient और वास्तव में फ़ाइलों को कैसे स्थानांतरित करने के लिए ठीक से subclass करने के साथ अटक गया हूँ। एक पूर्ण उड़ा हुआ ट्यूटोरियल जरूरी नहीं है क्योंकि मुझे मुड़ने में दिलचस्पी है (यह मेरी पहली छोटी परियोजना थी) लेकिन दस्तावेज़ों के बारे में मुझे किस तरीके और कक्षाओं का उपयोग करना चाहिए या पढ़ना चाहिए या यहां तक कि एक साधारण-इश उदाहरण भी हो सकता है (मुझे मिला पढ़ने के लिए कड़ी मेहनत करने के लिए cftp.py) बहुत सराहना की जाएगी। – rymurr