[Twisted-Python] call XMLRPC

joel tremblet bingopitts at gmail.com
Mon Apr 16 20:38:26 MDT 2012


Hi

I started to learn Twisted with the O'Reilly Book Twisted Network
Programming Essentials
I want to do a daemon to listen on port
- when a correct sentence is received, the daemon must to check by querying a
server XML_RPC
- if the answer from  XML_RPC is 1, the  HTTP answer will be OK else NOT
FOUND

I adapted the basic example HttpEchoProtocol.py

from twisted.protocols import basic
from twisted.web.xmlrpc import Proxy
from twisted.internet import protocol, reactor
import pdb

KEYS_ADDR="192.168.0.254"
KEYS_PORT=2101

# URL of the XML-RPC server
 OF_XMLRPC_URL="http://127.0.0.1/xmlRpc.rpc.php"
# HTTP Port from which the OF client contact the service
SERVICE_PORT=4080
# url sent  for test: localhost:4080/?sessid=dddddd&key=1&resource=2

class HttpProtocol(basic.LineReceiver):

    def __init__(self):
        self.lines      = []
        self.answer     = "HTTP/1.0 200 No value"
        self.gotRequest = False
        self.proxy      = Proxy(OF_XMLRPC_URL)

    def xmlRpcResponse(self, value):
        self.xmlRpc = value
        if self.xmlRpc == 1:
            self.answer = "HTTP/1.0 200 OK"
            print "xmlRpc : ",self.xmlRpc
        else:
            self.answer = "HTTP/1.0 406 Invalid key"
        self.xmlRpc = 0

    def xmlRpcError(self, error):
        self.answer = "HTTP/1.0 405 NOT FOUND"
        print "Error"

    def lineReceived(self, line):
        self.lines.append(line)
        if not line and not self.gotRequest:
            text = self.lines[0]
            startText = text.find("sessid")
            if startText>0 :
                endText = text.find("HTTP")
                text=text[startText:endText]
                data = text.split("&")
                sessionId = data[0][data[0].find("=")+1:]
                keyId = int(data[1][data[1].find("=")+1:])
                resourceId = int(data[2][data[2].find("=")+1:])
                self.proxy.callRemote('checkCommand', sessionId,
keyId).addCallbacks(self.xmlRpcResponse, self.xmlRpcError)
            self.sendResponse()
            self.gotRequest = True

    def sendResponse(self):
        responseBody = self.answer
        self.sendLine(self.answer)
        self.sendLine("Content-Type: text/plain")
        self.sendLine("Content-Length: %i" % len(responseBody))
        self.sendLine("")
        self.transport.write(responseBody)
        self.transport.loseConnection()

factory = protocol.ServerFactory()
factory.protocol = HttpProtocol
reactor.listenTCP(SERVICE_PORT, factory)
reactor.run()

XML_RPC answer is correctly  received ("xmlRpc :  1") but the HTTP answer
is always "HTTP/1.0 200 No value" (first initialization)

I tried a other example, based on requesthandler,py

from twisted.web.xmlrpc import Proxy
from twisted.web import http
from twisted.web.xmlrpc import Proxy
from twisted.internet import reactor
import pdb


# HTTP Port from which the OF client contact OpenKeys service
SERVICE_PORT=4080

# URL of the XML-RPC server
OF_XMLRPC_URL="http://127.0.0.1/openkeys.rpc.php"

class MyRequestHandler(http.Request):

    xmlRpc = 0
    def xmlRpcResponse(self, value):
        self.xmlRpc = value
        print repr(value)
        if self.xmlRpc == 1:
           self.setResponseCode(http.OK)
           self.write("<h1>OK</h1>")
        else:
            self.setResponseCode(http.NOT_ALLOWED)
            self.write("<h1>Invalid key</h1>.")
        self.xmlRpc = 0
        self.finish()

    def xmlRpcError(self, error):
        print 'error', error
        self.setResponseCode(http.NOT_FOUND)
        self.write("<h1>Not Found</h1>")
        self.xmlRpc = 0
        self.finish()

    def process(self):
        self.setHeader('Content-Type', 'text/html')
        data = self.args
        if 'sessid' in data:
            sessionId  = data['sessid'][0]
            keyId      = data["key"][0]
            resourceId = data["resource"][0]
            print "session = ", sessionId
            print "key = ", keyId
            print "resource = ", resourceId
            proxy.callRemote('checkCommand', sessionId,
keyId).addCallbacks(self.xmlRpcResponse, self.xmlRpcError)
        else:
            print "data = ", data
            self.setResponseCode(http.NOT_FOUND)
            self.write("<h1>Not Found</h1>Sorry, no such page.")
            self.finish()

class MyHttp(http.HTTPChannel):
    requestFactory = MyRequestHandler

class MyHttpFactory(http.HTTPFactory):
    protocol = MyHttp

proxy  = Proxy(OF_XMLRPC_URL)
reactor.listenTCP(SERVICE_PORT, MyHttpFactory())
reactor.run()

But in this case an error occur

error [Failure instance: Traceback: <class 'xmlrpclib.Fault'>: <Fault
-32602: 's
erver error. invalid method parameters'>
C:\python27\lib\site-packages\twisted\internet\posixbase.py:263:_disconnectSelec
table
C:\python27\lib\site-packages\twisted\internet\tcp.py:433:connectionLost
C:\python27\lib\site-packages\twisted\internet\tcp.py:277:connectionLost
C:\python27\lib\site-packages\twisted\web\xmlrpc.py:373:connectionLost
--- <exception caught here> ---
C:\python27\lib\site-packages\twisted\web\xmlrpc.py:444:parseResponse
C:\python27\lib\xmlrpclib.py:1137:loads
C:\python27\lib\xmlrpclib.py:793:close
]

I try to declare the Proxy(OF_XMLRPC_URL) differently, without success

Where is my mistake ....
Thanks
Bingo
-------------- next part --------------
An HTML attachment was scrubbed...
URL: </pipermail/twisted-python/attachments/20120416/ccd9813a/attachment.html>


More information about the Twisted-Python mailing list