[2] | 1 | :mod:`SimpleXMLRPCServer` --- Basic XML-RPC server
|
---|
| 2 | ==================================================
|
---|
| 3 |
|
---|
| 4 | .. module:: SimpleXMLRPCServer
|
---|
| 5 | :synopsis: Basic XML-RPC server implementation.
|
---|
| 6 | .. moduleauthor:: Brian Quinlan <brianq@activestate.com>
|
---|
| 7 | .. sectionauthor:: Fred L. Drake, Jr. <fdrake@acm.org>
|
---|
| 8 |
|
---|
| 9 | .. note::
|
---|
| 10 | The :mod:`SimpleXMLRPCServer` module has been merged into
|
---|
[391] | 11 | :mod:`xmlrpc.server` in Python 3. The :term:`2to3` tool will automatically
|
---|
| 12 | adapt imports when converting your sources to Python 3.
|
---|
[2] | 13 |
|
---|
| 14 |
|
---|
| 15 | .. versionadded:: 2.2
|
---|
| 16 |
|
---|
[391] | 17 | **Source code:** :source:`Lib/SimpleXMLRPCServer.py`
|
---|
| 18 |
|
---|
| 19 | --------------
|
---|
| 20 |
|
---|
[2] | 21 | The :mod:`SimpleXMLRPCServer` module provides a basic server framework for
|
---|
| 22 | XML-RPC servers written in Python. Servers can either be free standing, using
|
---|
| 23 | :class:`SimpleXMLRPCServer`, or embedded in a CGI environment, using
|
---|
| 24 | :class:`CGIXMLRPCRequestHandler`.
|
---|
| 25 |
|
---|
| 26 |
|
---|
[391] | 27 | .. class:: SimpleXMLRPCServer(addr[, requestHandler[, logRequests[, allow_none[, encoding[, bind_and_activate]]]])
|
---|
[2] | 28 |
|
---|
| 29 | Create a new server instance. This class provides methods for registration of
|
---|
| 30 | functions that can be called by the XML-RPC protocol. The *requestHandler*
|
---|
| 31 | parameter should be a factory for request handler instances; it defaults to
|
---|
| 32 | :class:`SimpleXMLRPCRequestHandler`. The *addr* and *requestHandler* parameters
|
---|
| 33 | are passed to the :class:`SocketServer.TCPServer` constructor. If *logRequests*
|
---|
| 34 | is true (the default), requests will be logged; setting this parameter to false
|
---|
| 35 | will turn off logging. The *allow_none* and *encoding* parameters are passed
|
---|
| 36 | on to :mod:`xmlrpclib` and control the XML-RPC responses that will be returned
|
---|
| 37 | from the server. The *bind_and_activate* parameter controls whether
|
---|
| 38 | :meth:`server_bind` and :meth:`server_activate` are called immediately by the
|
---|
| 39 | constructor; it defaults to true. Setting it to false allows code to manipulate
|
---|
| 40 | the *allow_reuse_address* class variable before the address is bound.
|
---|
| 41 |
|
---|
| 42 | .. versionchanged:: 2.5
|
---|
| 43 | The *allow_none* and *encoding* parameters were added.
|
---|
| 44 |
|
---|
| 45 | .. versionchanged:: 2.6
|
---|
| 46 | The *bind_and_activate* parameter was added.
|
---|
| 47 |
|
---|
| 48 |
|
---|
| 49 | .. class:: CGIXMLRPCRequestHandler([allow_none[, encoding]])
|
---|
| 50 |
|
---|
| 51 | Create a new instance to handle XML-RPC requests in a CGI environment. The
|
---|
| 52 | *allow_none* and *encoding* parameters are passed on to :mod:`xmlrpclib` and
|
---|
| 53 | control the XML-RPC responses that will be returned from the server.
|
---|
| 54 |
|
---|
| 55 | .. versionadded:: 2.3
|
---|
| 56 |
|
---|
| 57 | .. versionchanged:: 2.5
|
---|
| 58 | The *allow_none* and *encoding* parameters were added.
|
---|
| 59 |
|
---|
| 60 |
|
---|
| 61 | .. class:: SimpleXMLRPCRequestHandler()
|
---|
| 62 |
|
---|
| 63 | Create a new request handler instance. This request handler supports ``POST``
|
---|
| 64 | requests and modifies logging so that the *logRequests* parameter to the
|
---|
| 65 | :class:`SimpleXMLRPCServer` constructor parameter is honored.
|
---|
| 66 |
|
---|
| 67 |
|
---|
| 68 | .. _simple-xmlrpc-servers:
|
---|
| 69 |
|
---|
| 70 | SimpleXMLRPCServer Objects
|
---|
| 71 | --------------------------
|
---|
| 72 |
|
---|
| 73 | The :class:`SimpleXMLRPCServer` class is based on
|
---|
| 74 | :class:`SocketServer.TCPServer` and provides a means of creating simple, stand
|
---|
| 75 | alone XML-RPC servers.
|
---|
| 76 |
|
---|
| 77 |
|
---|
| 78 | .. method:: SimpleXMLRPCServer.register_function(function[, name])
|
---|
| 79 |
|
---|
| 80 | Register a function that can respond to XML-RPC requests. If *name* is given,
|
---|
| 81 | it will be the method name associated with *function*, otherwise
|
---|
| 82 | ``function.__name__`` will be used. *name* can be either a normal or Unicode
|
---|
| 83 | string, and may contain characters not legal in Python identifiers, including
|
---|
| 84 | the period character.
|
---|
| 85 |
|
---|
| 86 |
|
---|
| 87 | .. method:: SimpleXMLRPCServer.register_instance(instance[, allow_dotted_names])
|
---|
| 88 |
|
---|
| 89 | Register an object which is used to expose method names which have not been
|
---|
| 90 | registered using :meth:`register_function`. If *instance* contains a
|
---|
| 91 | :meth:`_dispatch` method, it is called with the requested method name and the
|
---|
| 92 | parameters from the request. Its API is ``def _dispatch(self, method, params)``
|
---|
| 93 | (note that *params* does not represent a variable argument list). If it calls
|
---|
| 94 | an underlying function to perform its task, that function is called as
|
---|
| 95 | ``func(*params)``, expanding the parameter list. The return value from
|
---|
| 96 | :meth:`_dispatch` is returned to the client as the result. If *instance* does
|
---|
| 97 | not have a :meth:`_dispatch` method, it is searched for an attribute matching
|
---|
| 98 | the name of the requested method.
|
---|
| 99 |
|
---|
| 100 | If the optional *allow_dotted_names* argument is true and the instance does not
|
---|
| 101 | have a :meth:`_dispatch` method, then if the requested method name contains
|
---|
| 102 | periods, each component of the method name is searched for individually, with
|
---|
| 103 | the effect that a simple hierarchical search is performed. The value found from
|
---|
| 104 | this search is then called with the parameters from the request, and the return
|
---|
| 105 | value is passed back to the client.
|
---|
| 106 |
|
---|
| 107 | .. warning::
|
---|
| 108 |
|
---|
| 109 | Enabling the *allow_dotted_names* option allows intruders to access your
|
---|
| 110 | module's global variables and may allow intruders to execute arbitrary code on
|
---|
| 111 | your machine. Only use this option on a secure, closed network.
|
---|
| 112 |
|
---|
| 113 | .. versionchanged:: 2.3.5, 2.4.1
|
---|
| 114 | *allow_dotted_names* was added to plug a security hole; prior versions are
|
---|
| 115 | insecure.
|
---|
| 116 |
|
---|
| 117 |
|
---|
| 118 | .. method:: SimpleXMLRPCServer.register_introspection_functions()
|
---|
| 119 |
|
---|
| 120 | Registers the XML-RPC introspection functions ``system.listMethods``,
|
---|
| 121 | ``system.methodHelp`` and ``system.methodSignature``.
|
---|
| 122 |
|
---|
| 123 | .. versionadded:: 2.3
|
---|
| 124 |
|
---|
| 125 |
|
---|
| 126 | .. method:: SimpleXMLRPCServer.register_multicall_functions()
|
---|
| 127 |
|
---|
| 128 | Registers the XML-RPC multicall function system.multicall.
|
---|
| 129 |
|
---|
| 130 |
|
---|
| 131 | .. attribute:: SimpleXMLRPCRequestHandler.rpc_paths
|
---|
| 132 |
|
---|
| 133 | An attribute value that must be a tuple listing valid path portions of the URL
|
---|
| 134 | for receiving XML-RPC requests. Requests posted to other paths will result in a
|
---|
| 135 | 404 "no such page" HTTP error. If this tuple is empty, all paths will be
|
---|
| 136 | considered valid. The default value is ``('/', '/RPC2')``.
|
---|
| 137 |
|
---|
| 138 | .. versionadded:: 2.5
|
---|
| 139 |
|
---|
[391] | 140 | .. attribute:: SimpleXMLRPCRequestHandler.encode_threshold
|
---|
| 141 |
|
---|
| 142 | If this attribute is not ``None``, responses larger than this value
|
---|
| 143 | will be encoded using the *gzip* transfer encoding, if permitted by
|
---|
| 144 | the client. The default is ``1400`` which corresponds roughly
|
---|
| 145 | to a single TCP packet.
|
---|
| 146 |
|
---|
| 147 | .. versionadded:: 2.7
|
---|
| 148 |
|
---|
[2] | 149 | .. _simplexmlrpcserver-example:
|
---|
| 150 |
|
---|
| 151 | SimpleXMLRPCServer Example
|
---|
| 152 | ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
---|
| 153 | Server code::
|
---|
| 154 |
|
---|
| 155 | from SimpleXMLRPCServer import SimpleXMLRPCServer
|
---|
| 156 | from SimpleXMLRPCServer import SimpleXMLRPCRequestHandler
|
---|
| 157 |
|
---|
| 158 | # Restrict to a particular path.
|
---|
| 159 | class RequestHandler(SimpleXMLRPCRequestHandler):
|
---|
| 160 | rpc_paths = ('/RPC2',)
|
---|
| 161 |
|
---|
| 162 | # Create server
|
---|
| 163 | server = SimpleXMLRPCServer(("localhost", 8000),
|
---|
| 164 | requestHandler=RequestHandler)
|
---|
| 165 | server.register_introspection_functions()
|
---|
| 166 |
|
---|
| 167 | # Register pow() function; this will use the value of
|
---|
| 168 | # pow.__name__ as the name, which is just 'pow'.
|
---|
| 169 | server.register_function(pow)
|
---|
| 170 |
|
---|
| 171 | # Register a function under a different name
|
---|
| 172 | def adder_function(x,y):
|
---|
| 173 | return x + y
|
---|
| 174 | server.register_function(adder_function, 'add')
|
---|
| 175 |
|
---|
| 176 | # Register an instance; all the methods of the instance are
|
---|
| 177 | # published as XML-RPC methods (in this case, just 'div').
|
---|
| 178 | class MyFuncs:
|
---|
| 179 | def div(self, x, y):
|
---|
| 180 | return x // y
|
---|
| 181 |
|
---|
| 182 | server.register_instance(MyFuncs())
|
---|
| 183 |
|
---|
| 184 | # Run the server's main loop
|
---|
| 185 | server.serve_forever()
|
---|
| 186 |
|
---|
| 187 | The following client code will call the methods made available by the preceding
|
---|
| 188 | server::
|
---|
| 189 |
|
---|
| 190 | import xmlrpclib
|
---|
| 191 |
|
---|
| 192 | s = xmlrpclib.ServerProxy('http://localhost:8000')
|
---|
| 193 | print s.pow(2,3) # Returns 2**3 = 8
|
---|
| 194 | print s.add(2,3) # Returns 5
|
---|
| 195 | print s.div(5,2) # Returns 5//2 = 2
|
---|
| 196 |
|
---|
| 197 | # Print list of available methods
|
---|
| 198 | print s.system.listMethods()
|
---|
| 199 |
|
---|
| 200 |
|
---|
| 201 | CGIXMLRPCRequestHandler
|
---|
| 202 | -----------------------
|
---|
| 203 |
|
---|
| 204 | The :class:`CGIXMLRPCRequestHandler` class can be used to handle XML-RPC
|
---|
| 205 | requests sent to Python CGI scripts.
|
---|
| 206 |
|
---|
| 207 |
|
---|
| 208 | .. method:: CGIXMLRPCRequestHandler.register_function(function[, name])
|
---|
| 209 |
|
---|
| 210 | Register a function that can respond to XML-RPC requests. If *name* is given,
|
---|
| 211 | it will be the method name associated with function, otherwise
|
---|
| 212 | *function.__name__* will be used. *name* can be either a normal or Unicode
|
---|
| 213 | string, and may contain characters not legal in Python identifiers, including
|
---|
| 214 | the period character.
|
---|
| 215 |
|
---|
| 216 |
|
---|
| 217 | .. method:: CGIXMLRPCRequestHandler.register_instance(instance)
|
---|
| 218 |
|
---|
| 219 | Register an object which is used to expose method names which have not been
|
---|
| 220 | registered using :meth:`register_function`. If instance contains a
|
---|
| 221 | :meth:`_dispatch` method, it is called with the requested method name and the
|
---|
| 222 | parameters from the request; the return value is returned to the client as the
|
---|
| 223 | result. If instance does not have a :meth:`_dispatch` method, it is searched
|
---|
| 224 | for an attribute matching the name of the requested method; if the requested
|
---|
| 225 | method name contains periods, each component of the method name is searched for
|
---|
| 226 | individually, with the effect that a simple hierarchical search is performed.
|
---|
| 227 | The value found from this search is then called with the parameters from the
|
---|
| 228 | request, and the return value is passed back to the client.
|
---|
| 229 |
|
---|
| 230 |
|
---|
| 231 | .. method:: CGIXMLRPCRequestHandler.register_introspection_functions()
|
---|
| 232 |
|
---|
| 233 | Register the XML-RPC introspection functions ``system.listMethods``,
|
---|
| 234 | ``system.methodHelp`` and ``system.methodSignature``.
|
---|
| 235 |
|
---|
| 236 |
|
---|
| 237 | .. method:: CGIXMLRPCRequestHandler.register_multicall_functions()
|
---|
| 238 |
|
---|
| 239 | Register the XML-RPC multicall function ``system.multicall``.
|
---|
| 240 |
|
---|
| 241 |
|
---|
| 242 | .. method:: CGIXMLRPCRequestHandler.handle_request([request_text = None])
|
---|
| 243 |
|
---|
| 244 | Handle a XML-RPC request. If *request_text* is given, it should be the POST
|
---|
| 245 | data provided by the HTTP server, otherwise the contents of stdin will be used.
|
---|
| 246 |
|
---|
| 247 | Example::
|
---|
| 248 |
|
---|
| 249 | class MyFuncs:
|
---|
| 250 | def div(self, x, y) : return x // y
|
---|
| 251 |
|
---|
| 252 |
|
---|
| 253 | handler = CGIXMLRPCRequestHandler()
|
---|
| 254 | handler.register_function(pow)
|
---|
| 255 | handler.register_function(lambda x,y: x+y, 'add')
|
---|
| 256 | handler.register_introspection_functions()
|
---|
| 257 | handler.register_instance(MyFuncs())
|
---|
| 258 | handler.handle_request()
|
---|
| 259 |
|
---|