03402885f5a969d18fa2ac4b56348196

the goal is to be able to export the SftpSClient class ('from sendfile import SftpSClient') from another script that uses ConfigParser to define the actual variables (hostname, protocol, etc.) currently i get a name (scope) error with pycurl, but both ftplib and paramiko work just fine.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
#!/usr/bin/env python
# #########################
# # $Id: sendfile.py,v 1.4 2008/03/19 11:59:52 dhylton Exp $
# # $Log:  $
# #########################

import time
import os
import sys
#import paramiko
#import ftplib
#import pycurl

class SftpSClient (object):
    def __init__(self, protocol, hostname, hostport, username, password, source_path, dest_path):

        self.protocol = protocol
        self.hostname = hostname
        self.hostport = hostport
        self.username = username
        self.password = password
        self.source_path = source_path
        self.dest_path = dest_path

        if self.protocol == "sftp":
            import paramiko
            self.client = paramiko.SSHClient()
            self.client.load_system_host_keys()
        elif self.protocol == "ftps":
            import pycurl
            self.client = pycurl.Curl()
        else: #self.protocol == "ftp":
            import ftplib
            self.client = ftplib.FTP()

    def xfer(self, source_file, dest_file=None):
        if not dest_file: dest_file = source_file
        source = os.path.join(self.source_path, source_file)
        dest   = os.path.join(self.dest_path,   dest_file)

        if self.protocol == "sftp":
            if not self.hostport: self.hostport = 22
            self.client.connect(self.hostname, self.hostport, self.username, self.password)
            sftp_client = self.client.open_sftp()
            sftp_client.put(source, dest)
            sftp_client.close()
        elif self.protocol == "ftps":
            if not self.hostport: self.hostport = 990
            userpwd = '%s:%s' % (self.username, self.password)
            infile = open(source, 'rb')
            self.client.setopt(pycurl.URL, 'ftp://%s:%d/%s' % (self.hostname, self.hostport, dest))
            self.client.setopt(pycurl.FTP_SSL, 1)
            self.client.setopt(pycurl.FTPSSLAUTH, 1)
            self.client.setopt(pycurl.SSL_VERIFYHOST, 1)
            self.client.setopt(pycurl.SSL_VERIFYPEER, 1)
            self.client.setopt(pycurl.USERPWD, userpwd)
            self.client.setopt(pycurl.READDATA, infile)
            self.client.setopt(pycurl.UPLOAD, 1)
            self.client.perform()
            infile.close()
        else: #self.protocol == "ftp":
            if not self.hostport: self.hostport = 21
            self.client.connect(self.hostname, self.hostport)
            self.client.login(user=self.username, passwd=self.password)
            self.client.set_pasv(False)
            infile = open(source, 'rb')
            self.client.storbinary('STOR ' + dest, infile)
            infile.close()


def main():

    hostname = 'localhost'
    username = 'snark'
    password = 'Bgt54rfv'
    source_path = 'lo cal'
    source_file = "test file'132"
    dest_file = "remote test file'133"

    print 'testing ftp'
    protocol = 'ftp'
    hostport = None
    start = time.time()
    dest_path = '%s/re mote' % (protocol)
    p = SftpSClient(protocol, hostname, hostport, username, password, source_path, dest_path)
    p.xfer(source_file, dest_file)
    elapsedtime = time.time() - start
    print 'elapsed time:', elapsedtime

    print 'testing ftps'
    protocol = 'ftps'
    hostport = 990
    start = time.time()
    dest_path = '%s/re mote' % (protocol)
    p = SftpSClient(protocol, hostname, hostport, username, password, source_path, dest_path)
    p.xfer(source_file, dest_file)
    elapsedtime = time.time() - start
    print 'elapsed time:', elapsedtime

    print 'testing sftp'
    protocol = 'sftp'
    hostport = 22
    start = time.time()
    dest_path = '%s/re mote' % (protocol)
    p = SftpSClient(protocol, hostname, hostport, username, password, source_path, dest_path)
    p.xfer(source_file, dest_file)
    elapsedtime = time.time() - start
    print 'elapsed time:', elapsedtime


if __name__ == '__main__': main()

Refactorings

No refactoring yet !

6869f98aa6911b0f9f13468ccca24813

Simon Law

March 19, 2008, March 19, 2008 17:06, permalink

No rating. Login to rate!

That's because pycurl is only defined in SftpSClient.__init__().

Here, it makes more sense for you to use a factory make SftpSClient.__init__() construct a good delegate object, that knows how to configure itself, instead of trying to keep state in SftpSClient.protocol.

03402885f5a969d18fa2ac4b56348196

dhylton.myopenid.com

March 19, 2008, March 19, 2008 17:13, permalink

No rating. Login to rate!

why does this not apply to paramiko and ftplib?

could you (please) show an example of your recommendation?

6869f98aa6911b0f9f13468ccca24813

Simon Law

March 20, 2008, March 20, 2008 00:02, permalink

No rating. Login to rate!

You use pycurl outside of its imported scope.

Here is an example implementation that uses a delegate.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
import time
import os
import sys

class SftpSClient(object):
    def __init__(self, protocol, hostname, hostport, username, password,
                 source_path, dest_path):
        if protocol == "sftp":
            self.delegate = ParamikoClient(protocol, hostname, hostport,
                                           username, password,
                                           source_path, dest_path)
        elif protocol == "ftps":
            self.delegate = PycurlClient(protocol, hostname, hostport,
                                         username, password,
                                         source_path, dest_path)
        else: #self.protocol == "ftp":
            self.delegate = FtpClient(protocol, hostname, hostport,
                                      username, password,
                                      source_path, dest_path)

    def _setup(self, protocol, hostname, hostport, username, password,
               source_path, dest_path):
        self.protocol = protocol
        self.hostname = hostname
        self.hostport = hostport
        self.username = username
        self.password = password
        self.source_path = source_path
        self.dest_path = dest_path

    def _xfer(self, source_file, dest_file):
        if not dest_file:
            dest_file = source_file
        source = os.path.join(self.source_path, source_file)
        dest = os.path.join(self.dest_path, dest_file)
        return (source, dest)

    def xfer(self, source_file, dest_file):
        self.delegate.xfer(*args, **kwargs)


class ParamikoClient(SftpSClient):
    def __init__(self, *args, **kwargs):
        self._setup(*args, **kwargs)
        self.paramiko = __import__("paramiko")
        self.client = self.paramiko.SSHClient()
        self.client.load_system_host_keys()

    def xfer(self, source_file, dest_file):
        source, dest = self._xfer(source_file, dest_file)
        if not self.hostport:
            self.hostport = 22
        self.client.connect(self.hostname, self.hostport,
                            self.username, self.password)
        sftp_client = self.client.open_sftp()
        sftp_client.put(source, dest)
        sftp_client.close()


class PycurlClient(SftpSClient):
    def __init__(self, *args, **kwargs):
        self._setup(*args, **kwargs)
        self.pycurl = __import__("pycurl")
        self.client = self.pycurl.Curl()

    def xfer(self, source_file, dest_file):
        source, dest = self._xfer(source_file, dest_file)
        if not self.hostport:
            self.hostport = 990
        userpwd = '%s:%s' % (self.username, self.password)
        infile = open(source, 'rb')
        self.client.setopt(self.pycurl.URL,
                           'ftp://%s:%d/%s' % (self.hostname, self.hostport,
                                               dest))
        self.client.setopt(self.pycurl.FTP_SSL, 1)
        self.client.setopt(self.pycurl.FTPSSLAUTH, 1)
        self.client.setopt(self.pycurl.SSL_VERIFYHOST, 1)
        self.client.setopt(self.pycurl.SSL_VERIFYPEER, 1)
        self.client.setopt(self.pycurl.USERPWD, userpwd)
        self.client.setopt(self.pycurl.READDATA, infile)
        self.client.setopt(self.pycurl.UPLOAD, 1)
        self.client.perform()
        infile.close()


class FtpClient(SftpSClient):
    def __init__(self, *args, **kwargs):
        self._setup(*args, **kwargs)
        self.ftplib = __import__("ftplib")
        self.client = self.ftplib.FTP()

    def xfer(self, source_file, dest_file):
        source, dest = self._xfer(source_file, dest_file)
        if not self.hostport:
            self.hostport = 21
        self.client.connect(self.hostname, self.hostport)
        self.client.login(user=self.username, passwd=self.password)
        self.client.set_pasv(False)
        infile = open(source, 'rb')
        self.client.storbinary('STOR ' + dest, infile)
        infile.close()


def main():
    hostname = 'localhost'
    username = 'snark'
    password = 'Bgt54rfv'
    source_path = 'lo cal'
    source_file = "test file'132"
    dest_file = "remote test file'133"

    print 'testing ftp'
    protocol = 'ftp'
    hostport = None
    start = time.time()
    dest_path = '%s/re mote' % (protocol)
    p = SftpSClient(protocol, hostname, hostport, username, password,
                    source_path, dest_path)
    p.xfer(source_file, dest_file)
    elapsedtime = time.time() - start
    print 'elapsed time:', elapsedtime

    print 'testing ftps'
    protocol = 'ftps'
    hostport = 990
    start = time.time()
    dest_path = '%s/re mote' % (protocol)
    p = SftpSClient(protocol, hostname, hostport, username, password,
                    source_path, dest_path)
    p.xfer(source_file, dest_file)
    elapsedtime = time.time() - start
    print 'elapsed time:', elapsedtime

    print 'testing sftp'
    protocol = 'sftp'
    hostport = 22
    start = time.time()
    dest_path = '%s/re mote' % (protocol)
    p = SftpSClient(protocol, hostname, hostport, username, password,
                    source_path, dest_path)
    p.xfer(source_file, dest_file)
    elapsedtime = time.time() - start
    print 'elapsed time:', elapsedtime


if __name__ == '__main__':
    main()

Your refactoring





Format Copy from initial code

or Cancel