Problem mit XML-RPC über Proxy mit Python 3.2.2

Sockets, TCP/IP, (XML-)RPC und ähnliche Themen gehören in dieses Forum
Antworten
_thomas
User
Beiträge: 3
Registriert: Mittwoch 4. Januar 2012, 17:31

Hallo Leute,

ich bin relativ neu und unerfahren im Umgang mit Python. Ich habe eine Frage zum Wechsel auf Python 3 und hoffe ihr könnt mir helfen.
Ich will einen XML-RPC Client schreiben. Mit Python 2.7.2 funktionert das alles auch schon super. Damit das Skript möglichst lange unverändert laufen kann und da ich eh von Grund auf neu anfange, wollte ich es nun gleich für Python 3.2.2 schreiben. Da kriege ich aber einen Fehler, wenn ich über einen Proxy gehen will, bzw. ProxiedTransport nutze.
Das passiert mir allerdings auch mit dem Code aus der Python 3 Doku:
http://docs.python.org/py3k/library/xml ... rver-usage

Code: Alles auswählen

import xmlrpc.client, http.client

class ProxiedTransport(xmlrpc.client.Transport):
    def set_proxy(self, proxy):
        self.proxy = proxy
    def make_connection(self, host):
        self.realhost = host
        h = http.client.HTTP(self.proxy)
        return h
    def send_request(self, connection, handler, request_body):
        connection.putrequest("POST", 'http://%s%s' % (self.realhost, handler))
    def send_host(self, connection, host):
        connection.putheader('Host', self.realhost)

p = ProxiedTransport()
p.set_proxy('proxy-server:8080')
server = xmlrpc.client.Server('http://time.xmlrpc.com/RPC2', transport=p)
print(server.currentTime.getCurrentTime())
Ergibt:

Code: Alles auswählen

Traceback (most recent call last):
  File "D:\(...)\my-xmlrpc-client.py", line 18, in <module>
    print(server.currentTime.getCurrentTime())
  File "C:\Python32\lib\xmlrpc\client.py", line 1095, in __call__
    return self.__send(self.__name, args)
  File "C:\Python32\lib\xmlrpc\client.py", line 1423, in __request
    verbose=self.__verbose
  File "C:\Python32\lib\xmlrpc\client.py", line 1136, in request
    return self.single_request(host, handler, request_body, verbose)
  File "C:\Python32\lib\xmlrpc\client.py", line 1147, in single_request
    http_conn = self.send_request(host, handler, request_body, verbose)
TypeError: send_request() takes exactly 4 positional arguments (5 given)
Da haut scheinbar ein Aufruf innerhalb der Libarys nicht hin oder sehe ich das falsch?
Liegt der Fehler überhaupt an mir? Ich hoffe ihr könnt mir helfen und mir erklären was da los ist. ...und was meine Optionen sind.

Gruß und schon mal Danke!
Thomas
Zuletzt geändert von _thomas am Donnerstag 5. Januar 2012, 12:16, insgesamt 1-mal geändert.
deets

Der Fehler liegt schon an dir - offensichtlich hat sich die API geaendert, und es gibt fuer die send_request-methode ein weiteres Argument - verbose.

Damit das funktioniert fuer beide Python-Varianten, koenntest du die Signatur von send_request in deinem Code um ein

Code: Alles auswählen

def send_request(self, host, handler, body, verbose=False):
      ...
erweitern - und das verbose einfach ignorieren.
_thomas
User
Beiträge: 3
Registriert: Mittwoch 4. Januar 2012, 17:31

Ok, Danke!
Das bringt mich schon mal einen Schritt weiter. ...leider nur bis zur nächsten Fehlermeldung.
Jetzt kriege ich:

Code: Alles auswählen

Traceback (most recent call last):
  File "D:\(...)\my-xmlrpc-client.py", line 19, in <module>
    print(server.currentTime.getCurrentTime())
  File "C:\Python32\lib\xmlrpc\client.py", line 1095, in __call__
    return self.__send(self.__name, args)
  File "C:\Python32\lib\xmlrpc\client.py", line 1423, in __request
    verbose=self.__verbose
  File "C:\Python32\lib\xmlrpc\client.py", line 1136, in request
    return self.single_request(host, handler, request_body, verbose)
  File "C:\Python32\lib\xmlrpc\client.py", line 1147, in single_request
    http_conn = self.send_request(host, handler, request_body, verbose)
  File "D:\(...)\my-xmlrpc-client.py", line 12, in send_request
    connection.putrequest("POST", 'http://%s%s' % (self.realhost, handler))
AttributeError: 'str' object has no attribute 'putrequest'
Alles was jetzt kommt, ist Rumgebastel von mir, kann also vollkommener Quatsch sein.
Er bekommt als connection scheinbar einen String, also habe ich send_request geändert zu:

Code: Alles auswählen

    def send_request(self, host, handler, request_body, verbose=False):
        connection = self.make_connection(host)
        connection.putrequest("POST", 'http://%s%s' % (self.realhost, handler))
Antwort:

Code: Alles auswählen

Traceback (most recent call last):
  File "D:\(...)\my-xmlrpc-client.py", line 19, in <module>
    print(server.currentTime.getCurrentTime())
  File "C:\Python32\lib\xmlrpc\client.py", line 1095, in __call__
    return self.__send(self.__name, args)
  File "C:\Python32\lib\xmlrpc\client.py", line 1423, in __request
    verbose=self.__verbose
  File "C:\Python32\lib\xmlrpc\client.py", line 1136, in request
    return self.single_request(host, handler, request_body, verbose)
  File "C:\Python32\lib\xmlrpc\client.py", line 1147, in single_request
    http_conn = self.send_request(host, handler, request_body, verbose)
  File "D:\(...)\my-xmlrpc-client.py", line 11, in send_request
    connection = self.make_connection(host)
  File "D:\(...)\my-xmlrpc-client.py", line 8, in make_connection
    h = http.client.HTTP(self.proxy)
AttributeError: 'module' object has no attribute 'HTTP'
Also habe ich make_connection geändert und mein Code sieht so aus:

Code: Alles auswählen

import xmlrpc.client, http.client

class ProxiedTransport(xmlrpc.client.Transport):
    def set_proxy(self, proxy):
        self.proxy = proxy
    def make_connection(self, host):
        self.realhost = host
        h = http.client.HTTPConnection(self.proxy)
        return h
    def send_request(self, host, handler, request_body, verbose=False):
        connection = self.make_connection(host)
        connection.putrequest("POST", 'http://%s%s' % (self.realhost, handler))
    def send_host(self, connection, host):
        connection.putheader('Host', self.realhost)

p = ProxiedTransport()
p.set_proxy('proxy-server:8080')
server = xmlrpc.client.Server('http://time.xmlrpc.com/RPC2', transport=p)
print(server.currentTime.getCurrentTime())
Antwort:

Code: Alles auswählen

Traceback (most recent call last):
  File "D:\(...)\my-xmlrpc-client.py", line 19, in <module>
    print(server.currentTime.getCurrentTime())
  File "C:\Python32\lib\xmlrpc\client.py", line 1095, in __call__
    return self.__send(self.__name, args)
  File "C:\Python32\lib\xmlrpc\client.py", line 1423, in __request
    verbose=self.__verbose
  File "C:\Python32\lib\xmlrpc\client.py", line 1136, in request
    return self.single_request(host, handler, request_body, verbose)
  File "C:\Python32\lib\xmlrpc\client.py", line 1148, in single_request
    resp = http_conn.getresponse()
AttributeError: 'NoneType' object has no attribute 'getresponse'
Kann es sein, dass es einfach noch keine gute Idee ist schon Python 3.2.2 zu verwenden, wenn der Code aus der Doku nicht läuft (und ich zu wenig Ahnung habe)?

Gruß, Thomas
deets

Du hast send_request falsch implementiert, das muss die connection auch zurueckgeben -das tust du aber nicht.
_thomas
User
Beiträge: 3
Registriert: Mittwoch 4. Januar 2012, 17:31

jap, außerdem hat

Code: Alles auswählen

self.send_content(connection, request_body)
gefehlt.

Korrekt ist also:

Code: Alles auswählen

import xmlrpc.client, http.client

class ProxiedTransport(xmlrpc.client.Transport):
    def set_proxy(self, proxy):
        self.proxy = proxy
    def make_connection(self, host):
        self.realhost = host
        h = http.client.HTTPConnection(self.proxy)
        return h
    def send_request(self, host, handler, request_body, verbose=False):
        connection = self.make_connection(host)
        connection.putrequest("POST", 'http://%s%s' % (self.realhost, handler))
        self.send_content(connection, request_body)
        return connection

p = ProxiedTransport()
p.set_proxy('proxy-server:8080')
server = xmlrpc.client.Server('http://time.xmlrpc.com/RPC2', transport=p)
print(server.currentTime.getCurrentTime())
Hab im Internet einfach nicht gefunden wie ich mit Python 3 korrekt über einen Proxy gehe.
Also danke für deine Hilfe! So läuft's jetzt.

Gruß, Thomas
Antworten