| Georg Brandl | 38eceaa | 2008-05-26 11:14:17 +0000 | [diff] [blame] | 1 | :mod:`xmlrpc.client` --- XML-RPC client access | 
|  | 2 | ============================================== | 
| Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 3 |  | 
| Georg Brandl | 38eceaa | 2008-05-26 11:14:17 +0000 | [diff] [blame] | 4 | .. module:: xmlrpc.client | 
| Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 5 | :synopsis: XML-RPC client access. | 
|  | 6 | .. moduleauthor:: Fredrik Lundh <fredrik@pythonware.com> | 
|  | 7 | .. sectionauthor:: Eric S. Raymond <esr@snark.thyrsus.com> | 
|  | 8 |  | 
|  | 9 |  | 
| Christian Heimes | 5b5e81c | 2007-12-31 16:14:33 +0000 | [diff] [blame] | 10 | .. XXX Not everything is documented yet.  It might be good to describe | 
| Florent Xicluna | 6166519 | 2011-11-15 20:53:25 +0100 | [diff] [blame] | 11 | Marshaller, Unmarshaller, getparser and Transport. | 
| Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 12 |  | 
| Raymond Hettinger | 3029aff | 2011-02-10 08:09:36 +0000 | [diff] [blame] | 13 | **Source code:** :source:`Lib/xmlrpc/client.py` | 
|  | 14 |  | 
|  | 15 | -------------- | 
|  | 16 |  | 
| Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 17 | XML-RPC is a Remote Procedure Call method that uses XML passed via HTTP as a | 
|  | 18 | transport.  With it, a client can call methods with parameters on a remote | 
|  | 19 | server (the server is named by a URI) and get back structured data.  This module | 
|  | 20 | supports writing XML-RPC client code; it handles all the details of translating | 
|  | 21 | between conformable Python objects and XML on the wire. | 
|  | 22 |  | 
|  | 23 |  | 
| Christian Heimes | 7380a67 | 2013-03-26 17:35:55 +0100 | [diff] [blame] | 24 | .. warning:: | 
|  | 25 |  | 
|  | 26 | The :mod:`xmlrpc.client` module is not secure against maliciously | 
|  | 27 | constructed data.  If you need to parse untrusted or unauthenticated data see | 
|  | 28 | :ref:`xml-vulnerabilities`. | 
|  | 29 |  | 
| Benjamin Peterson | 77a75b3 | 2014-10-13 11:54:50 -0400 | [diff] [blame] | 30 | .. warning:: | 
|  | 31 |  | 
| Benjamin Peterson | 9fc59c9 | 2014-10-19 10:47:49 -0400 | [diff] [blame] | 32 | In the case of https URIs, :mod:`xmlrpc.client` does not do any verification | 
| Benjamin Peterson | 77a75b3 | 2014-10-13 11:54:50 -0400 | [diff] [blame] | 33 | of the server's certificate. | 
|  | 34 |  | 
| Christian Heimes | 7380a67 | 2013-03-26 17:35:55 +0100 | [diff] [blame] | 35 |  | 
| Florent Xicluna | 6166519 | 2011-11-15 20:53:25 +0100 | [diff] [blame] | 36 | .. class:: ServerProxy(uri, transport=None, encoding=None, verbose=False, \ | 
|  | 37 | allow_none=False, use_datetime=False, \ | 
|  | 38 | use_builtin_types=False) | 
|  | 39 |  | 
|  | 40 | .. versionchanged:: 3.3 | 
|  | 41 | The *use_builtin_types* flag was added. | 
| Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 42 |  | 
|  | 43 | A :class:`ServerProxy` instance is an object that manages communication with a | 
|  | 44 | remote XML-RPC server.  The required first argument is a URI (Uniform Resource | 
|  | 45 | Indicator), and will normally be the URL of the server.  The optional second | 
|  | 46 | argument is a transport factory instance; by default it is an internal | 
|  | 47 | :class:`SafeTransport` instance for https: URLs and an internal HTTP | 
|  | 48 | :class:`Transport` instance otherwise.  The optional third argument is an | 
|  | 49 | encoding, by default UTF-8. The optional fourth argument is a debugging flag. | 
|  | 50 | If *allow_none* is true,  the Python constant ``None`` will be translated into | 
|  | 51 | XML; the default behaviour is for ``None`` to raise a :exc:`TypeError`. This is | 
|  | 52 | a commonly-used extension to the XML-RPC specification, but isn't supported by | 
|  | 53 | all clients and servers; see http://ontosys.com/xml-rpc/extensions.php for a | 
| Florent Xicluna | 6166519 | 2011-11-15 20:53:25 +0100 | [diff] [blame] | 54 | description.  The *use_builtin_types* flag can be used to cause date/time values | 
|  | 55 | to be presented as :class:`datetime.datetime` objects and binary data to be | 
|  | 56 | presented as :class:`bytes` objects; this flag is false by default. | 
|  | 57 | :class:`datetime.datetime` and :class:`bytes` objects may be passed to calls. | 
|  | 58 |  | 
|  | 59 | The obsolete *use_datetime* flag is similar to *use_builtin_types* but it | 
|  | 60 | applies only to date/time values. | 
| Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 61 |  | 
|  | 62 | Both the HTTP and HTTPS transports support the URL syntax extension for HTTP | 
|  | 63 | Basic Authentication: ``http://user:pass@host:port/path``.  The  ``user:pass`` | 
|  | 64 | portion will be base64-encoded as an HTTP 'Authorization' header, and sent to | 
|  | 65 | the remote server as part of the connection process when invoking an XML-RPC | 
|  | 66 | method.  You only need to use this if the remote server requires a Basic | 
|  | 67 | Authentication user and password. | 
|  | 68 |  | 
|  | 69 | The returned instance is a proxy object with methods that can be used to invoke | 
|  | 70 | corresponding RPC calls on the remote server.  If the remote server supports the | 
|  | 71 | introspection API, the proxy can also be used to query the remote server for the | 
|  | 72 | methods it supports (service discovery) and fetch other server-associated | 
|  | 73 | metadata. | 
|  | 74 |  | 
|  | 75 | :class:`ServerProxy` instance methods take Python basic types and objects as | 
|  | 76 | arguments and return Python basic types and classes.  Types that are conformable | 
|  | 77 | (e.g. that can be marshalled through XML), include the following (and except | 
|  | 78 | where noted, they are unmarshalled as the same Python type): | 
|  | 79 |  | 
| Georg Brandl | 44ea77b | 2013-03-28 13:28:44 +0100 | [diff] [blame] | 80 | .. tabularcolumns:: |l|L| | 
|  | 81 |  | 
| Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 82 | +---------------------------------+---------------------------------------------+ | 
|  | 83 | | Name                            | Meaning                                     | | 
|  | 84 | +=================================+=============================================+ | 
|  | 85 | | :const:`boolean`                | The :const:`True` and :const:`False`        | | 
|  | 86 | |                                 | constants                                   | | 
|  | 87 | +---------------------------------+---------------------------------------------+ | 
|  | 88 | | :const:`integers`               | Pass in directly                            | | 
|  | 89 | +---------------------------------+---------------------------------------------+ | 
|  | 90 | | :const:`floating-point numbers` | Pass in directly                            | | 
|  | 91 | +---------------------------------+---------------------------------------------+ | 
|  | 92 | | :const:`strings`                | Pass in directly                            | | 
|  | 93 | +---------------------------------+---------------------------------------------+ | 
|  | 94 | | :const:`arrays`                 | Any Python sequence type containing         | | 
|  | 95 | |                                 | conformable elements. Arrays are returned   | | 
|  | 96 | |                                 | as lists                                    | | 
|  | 97 | +---------------------------------+---------------------------------------------+ | 
|  | 98 | | :const:`structures`             | A Python dictionary. Keys must be strings,  | | 
|  | 99 | |                                 | values may be any conformable type. Objects | | 
|  | 100 | |                                 | of user-defined classes can be passed in;   | | 
|  | 101 | |                                 | only their *__dict__* attribute is          | | 
|  | 102 | |                                 | transmitted.                                | | 
|  | 103 | +---------------------------------+---------------------------------------------+ | 
| Florent Xicluna | 6166519 | 2011-11-15 20:53:25 +0100 | [diff] [blame] | 104 | | :const:`dates`                  | In seconds since the epoch.  Pass in an     | | 
|  | 105 | |                                 | instance of the :class:`DateTime` class or  | | 
| Christian Heimes | 05e8be1 | 2008-02-23 18:30:17 +0000 | [diff] [blame] | 106 | |                                 | a :class:`datetime.datetime` instance.      | | 
| Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 107 | +---------------------------------+---------------------------------------------+ | 
| Florent Xicluna | 6166519 | 2011-11-15 20:53:25 +0100 | [diff] [blame] | 108 | | :const:`binary data`            | Pass in an instance of the :class:`Binary`  | | 
|  | 109 | |                                 | wrapper class or a :class:`bytes` instance. | | 
| Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 110 | +---------------------------------+---------------------------------------------+ | 
|  | 111 |  | 
|  | 112 | This is the full set of data types supported by XML-RPC.  Method calls may also | 
|  | 113 | raise a special :exc:`Fault` instance, used to signal XML-RPC server errors, or | 
|  | 114 | :exc:`ProtocolError` used to signal an error in the HTTP/HTTPS transport layer. | 
|  | 115 | Both :exc:`Fault` and :exc:`ProtocolError` derive from a base class called | 
| Georg Brandl | 38eceaa | 2008-05-26 11:14:17 +0000 | [diff] [blame] | 116 | :exc:`Error`.  Note that the xmlrpc client module currently does not marshal | 
| Georg Brandl | 22b3431 | 2009-07-26 14:54:51 +0000 | [diff] [blame] | 117 | instances of subclasses of built-in types. | 
| Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 118 |  | 
|  | 119 | When passing strings, characters special to XML such as ``<``, ``>``, and ``&`` | 
|  | 120 | will be automatically escaped.  However, it's the caller's responsibility to | 
|  | 121 | ensure that the string is free of characters that aren't allowed in XML, such as | 
|  | 122 | the control characters with ASCII values between 0 and 31 (except, of course, | 
|  | 123 | tab, newline and carriage return); failing to do this will result in an XML-RPC | 
| Florent Xicluna | 6166519 | 2011-11-15 20:53:25 +0100 | [diff] [blame] | 124 | request that isn't well-formed XML.  If you have to pass arbitrary bytes | 
|  | 125 | via XML-RPC, use the :class:`bytes` class or the class:`Binary` wrapper class | 
|  | 126 | described below. | 
| Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 127 |  | 
|  | 128 | :class:`Server` is retained as an alias for :class:`ServerProxy` for backwards | 
|  | 129 | compatibility.  New code should use :class:`ServerProxy`. | 
|  | 130 |  | 
| Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 131 |  | 
|  | 132 | .. seealso:: | 
|  | 133 |  | 
|  | 134 | `XML-RPC HOWTO <http://www.tldp.org/HOWTO/XML-RPC-HOWTO/index.html>`_ | 
| Christian Heimes | a62da1d | 2008-01-12 19:39:10 +0000 | [diff] [blame] | 135 | A good description of XML-RPC operation and client software in several languages. | 
| Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 136 | Contains pretty much everything an XML-RPC client developer needs to know. | 
|  | 137 |  | 
| Christian Heimes | a62da1d | 2008-01-12 19:39:10 +0000 | [diff] [blame] | 138 | `XML-RPC Introspection <http://xmlrpc-c.sourceforge.net/introspection.html>`_ | 
|  | 139 | Describes the XML-RPC protocol extension for introspection. | 
| Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 140 |  | 
| Christian Heimes | 81ee3ef | 2008-05-04 22:42:01 +0000 | [diff] [blame] | 141 | `XML-RPC Specification <http://www.xmlrpc.com/spec>`_ | 
|  | 142 | The official specification. | 
|  | 143 |  | 
|  | 144 | `Unofficial XML-RPC Errata <http://effbot.org/zone/xmlrpc-errata.htm>`_ | 
|  | 145 | Fredrik Lundh's "unofficial errata, intended to clarify certain | 
|  | 146 | details in the XML-RPC specification, as well as hint at | 
|  | 147 | 'best practices' to use when designing your own XML-RPC | 
|  | 148 | implementations." | 
| Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 149 |  | 
|  | 150 | .. _serverproxy-objects: | 
|  | 151 |  | 
|  | 152 | ServerProxy Objects | 
|  | 153 | ------------------- | 
|  | 154 |  | 
|  | 155 | A :class:`ServerProxy` instance has a method corresponding to each remote | 
|  | 156 | procedure call accepted by the XML-RPC server.  Calling the method performs an | 
|  | 157 | RPC, dispatched by both name and argument signature (e.g. the same method name | 
|  | 158 | can be overloaded with multiple argument signatures).  The RPC finishes by | 
|  | 159 | returning a value, which may be either returned data in a conformant type or a | 
|  | 160 | :class:`Fault` or :class:`ProtocolError` object indicating an error. | 
|  | 161 |  | 
|  | 162 | Servers that support the XML introspection API support some common methods | 
| Senthil Kumaran | a6bac95 | 2011-07-04 11:28:30 -0700 | [diff] [blame] | 163 | grouped under the reserved :attr:`system` attribute: | 
| Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 164 |  | 
|  | 165 |  | 
|  | 166 | .. method:: ServerProxy.system.listMethods() | 
|  | 167 |  | 
|  | 168 | This method returns a list of strings, one for each (non-system) method | 
|  | 169 | supported by the XML-RPC server. | 
|  | 170 |  | 
|  | 171 |  | 
|  | 172 | .. method:: ServerProxy.system.methodSignature(name) | 
|  | 173 |  | 
|  | 174 | This method takes one parameter, the name of a method implemented by the XML-RPC | 
| Georg Brandl | 9460648 | 2009-05-04 20:46:44 +0000 | [diff] [blame] | 175 | server. It returns an array of possible signatures for this method. A signature | 
| Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 176 | is an array of types. The first of these types is the return type of the method, | 
|  | 177 | the rest are parameters. | 
|  | 178 |  | 
|  | 179 | Because multiple signatures (ie. overloading) is permitted, this method returns | 
|  | 180 | a list of signatures rather than a singleton. | 
|  | 181 |  | 
|  | 182 | Signatures themselves are restricted to the top level parameters expected by a | 
|  | 183 | method. For instance if a method expects one array of structs as a parameter, | 
|  | 184 | and it returns a string, its signature is simply "string, array". If it expects | 
|  | 185 | three integers and returns a string, its signature is "string, int, int, int". | 
|  | 186 |  | 
|  | 187 | If no signature is defined for the method, a non-array value is returned. In | 
|  | 188 | Python this means that the type of the returned  value will be something other | 
| Georg Brandl | 9460648 | 2009-05-04 20:46:44 +0000 | [diff] [blame] | 189 | than list. | 
| Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 190 |  | 
|  | 191 |  | 
|  | 192 | .. method:: ServerProxy.system.methodHelp(name) | 
|  | 193 |  | 
|  | 194 | This method takes one parameter, the name of a method implemented by the XML-RPC | 
|  | 195 | server.  It returns a documentation string describing the use of that method. If | 
|  | 196 | no such string is available, an empty string is returned. The documentation | 
|  | 197 | string may contain HTML markup. | 
|  | 198 |  | 
| Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 199 |  | 
| Christian Heimes | cbf3b5c | 2007-12-03 21:02:03 +0000 | [diff] [blame] | 200 | A working example follows. The server code:: | 
|  | 201 |  | 
| Georg Brandl | 38eceaa | 2008-05-26 11:14:17 +0000 | [diff] [blame] | 202 | from xmlrpc.server import SimpleXMLRPCServer | 
| Christian Heimes | cbf3b5c | 2007-12-03 21:02:03 +0000 | [diff] [blame] | 203 |  | 
|  | 204 | def is_even(n): | 
|  | 205 | return n%2 == 0 | 
|  | 206 |  | 
|  | 207 | server = SimpleXMLRPCServer(("localhost", 8000)) | 
| Georg Brandl | f694518 | 2008-02-01 11:56:49 +0000 | [diff] [blame] | 208 | print("Listening on port 8000...") | 
| Christian Heimes | cbf3b5c | 2007-12-03 21:02:03 +0000 | [diff] [blame] | 209 | server.register_function(is_even, "is_even") | 
|  | 210 | server.serve_forever() | 
|  | 211 |  | 
|  | 212 | The client code for the preceding server:: | 
|  | 213 |  | 
| Georg Brandl | 38eceaa | 2008-05-26 11:14:17 +0000 | [diff] [blame] | 214 | import xmlrpc.client | 
| Christian Heimes | cbf3b5c | 2007-12-03 21:02:03 +0000 | [diff] [blame] | 215 |  | 
| Georg Brandl | 38eceaa | 2008-05-26 11:14:17 +0000 | [diff] [blame] | 216 | proxy = xmlrpc.client.ServerProxy("http://localhost:8000/") | 
| Georg Brandl | f694518 | 2008-02-01 11:56:49 +0000 | [diff] [blame] | 217 | print("3 is even: %s" % str(proxy.is_even(3))) | 
|  | 218 | print("100 is even: %s" % str(proxy.is_even(100))) | 
| Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 219 |  | 
|  | 220 | .. _datetime-objects: | 
|  | 221 |  | 
|  | 222 | DateTime Objects | 
|  | 223 | ---------------- | 
|  | 224 |  | 
| Christian Heimes | 05e8be1 | 2008-02-23 18:30:17 +0000 | [diff] [blame] | 225 | This class may be initialized with seconds since the epoch, a time | 
|  | 226 | tuple, an ISO 8601 time/date string, or a :class:`datetime.datetime` | 
|  | 227 | instance.  It has the following methods, supported mainly for internal | 
|  | 228 | use by the marshalling/unmarshalling code: | 
| Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 229 |  | 
|  | 230 |  | 
|  | 231 | .. method:: DateTime.decode(string) | 
|  | 232 |  | 
|  | 233 | Accept a string as the instance's new time value. | 
|  | 234 |  | 
|  | 235 |  | 
|  | 236 | .. method:: DateTime.encode(out) | 
|  | 237 |  | 
|  | 238 | Write the XML-RPC encoding of this :class:`DateTime` item to the *out* stream | 
|  | 239 | object. | 
|  | 240 |  | 
| Georg Brandl | 05f5ab7 | 2008-09-24 09:11:47 +0000 | [diff] [blame] | 241 | It also supports certain of Python's built-in operators through rich comparison | 
| Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 242 | and :meth:`__repr__` methods. | 
|  | 243 |  | 
| Christian Heimes | cbf3b5c | 2007-12-03 21:02:03 +0000 | [diff] [blame] | 244 | A working example follows. The server code:: | 
|  | 245 |  | 
|  | 246 | import datetime | 
| Georg Brandl | 38eceaa | 2008-05-26 11:14:17 +0000 | [diff] [blame] | 247 | from xmlrpc.server import SimpleXMLRPCServer | 
|  | 248 | import xmlrpc.client | 
| Christian Heimes | cbf3b5c | 2007-12-03 21:02:03 +0000 | [diff] [blame] | 249 |  | 
|  | 250 | def today(): | 
|  | 251 | today = datetime.datetime.today() | 
| Georg Brandl | 38eceaa | 2008-05-26 11:14:17 +0000 | [diff] [blame] | 252 | return xmlrpc.client.DateTime(today) | 
| Christian Heimes | cbf3b5c | 2007-12-03 21:02:03 +0000 | [diff] [blame] | 253 |  | 
|  | 254 | server = SimpleXMLRPCServer(("localhost", 8000)) | 
| Georg Brandl | f694518 | 2008-02-01 11:56:49 +0000 | [diff] [blame] | 255 | print("Listening on port 8000...") | 
| Christian Heimes | cbf3b5c | 2007-12-03 21:02:03 +0000 | [diff] [blame] | 256 | server.register_function(today, "today") | 
|  | 257 | server.serve_forever() | 
|  | 258 |  | 
|  | 259 | The client code for the preceding server:: | 
|  | 260 |  | 
| Georg Brandl | 38eceaa | 2008-05-26 11:14:17 +0000 | [diff] [blame] | 261 | import xmlrpc.client | 
| Christian Heimes | cbf3b5c | 2007-12-03 21:02:03 +0000 | [diff] [blame] | 262 | import datetime | 
|  | 263 |  | 
| Georg Brandl | 38eceaa | 2008-05-26 11:14:17 +0000 | [diff] [blame] | 264 | proxy = xmlrpc.client.ServerProxy("http://localhost:8000/") | 
| Christian Heimes | cbf3b5c | 2007-12-03 21:02:03 +0000 | [diff] [blame] | 265 |  | 
|  | 266 | today = proxy.today() | 
|  | 267 | # convert the ISO8601 string to a datetime object | 
|  | 268 | converted = datetime.datetime.strptime(today.value, "%Y%m%dT%H:%M:%S") | 
| Georg Brandl | f694518 | 2008-02-01 11:56:49 +0000 | [diff] [blame] | 269 | print("Today: %s" % converted.strftime("%d.%m.%Y, %H:%M")) | 
| Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 270 |  | 
|  | 271 | .. _binary-objects: | 
|  | 272 |  | 
|  | 273 | Binary Objects | 
|  | 274 | -------------- | 
|  | 275 |  | 
| Florent Xicluna | 6166519 | 2011-11-15 20:53:25 +0100 | [diff] [blame] | 276 | This class may be initialized from bytes data (which may include NULs). The | 
| Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 277 | primary access to the content of a :class:`Binary` object is provided by an | 
|  | 278 | attribute: | 
|  | 279 |  | 
|  | 280 |  | 
|  | 281 | .. attribute:: Binary.data | 
|  | 282 |  | 
|  | 283 | The binary data encapsulated by the :class:`Binary` instance.  The data is | 
| Florent Xicluna | 6166519 | 2011-11-15 20:53:25 +0100 | [diff] [blame] | 284 | provided as a :class:`bytes` object. | 
| Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 285 |  | 
|  | 286 | :class:`Binary` objects have the following methods, supported mainly for | 
|  | 287 | internal use by the marshalling/unmarshalling code: | 
|  | 288 |  | 
|  | 289 |  | 
| Florent Xicluna | 6166519 | 2011-11-15 20:53:25 +0100 | [diff] [blame] | 290 | .. method:: Binary.decode(bytes) | 
| Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 291 |  | 
| Florent Xicluna | 6166519 | 2011-11-15 20:53:25 +0100 | [diff] [blame] | 292 | Accept a base64 :class:`bytes` object and decode it as the instance's new data. | 
| Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 293 |  | 
|  | 294 |  | 
|  | 295 | .. method:: Binary.encode(out) | 
|  | 296 |  | 
|  | 297 | Write the XML-RPC base 64 encoding of this binary item to the out stream object. | 
|  | 298 |  | 
| Christian Heimes | 81ee3ef | 2008-05-04 22:42:01 +0000 | [diff] [blame] | 299 | The encoded data will have newlines every 76 characters as per | 
|  | 300 | `RFC 2045 section 6.8 <http://tools.ietf.org/html/rfc2045#section-6.8>`_, | 
|  | 301 | which was the de facto standard base64 specification when the | 
|  | 302 | XML-RPC spec was written. | 
|  | 303 |  | 
| Georg Brandl | 05f5ab7 | 2008-09-24 09:11:47 +0000 | [diff] [blame] | 304 | It also supports certain of Python's built-in operators through :meth:`__eq__` | 
|  | 305 | and :meth:`__ne__` methods. | 
| Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 306 |  | 
| Christian Heimes | cbf3b5c | 2007-12-03 21:02:03 +0000 | [diff] [blame] | 307 | Example usage of the binary objects.  We're going to transfer an image over | 
|  | 308 | XMLRPC:: | 
|  | 309 |  | 
| Georg Brandl | 38eceaa | 2008-05-26 11:14:17 +0000 | [diff] [blame] | 310 | from xmlrpc.server import SimpleXMLRPCServer | 
|  | 311 | import xmlrpc.client | 
| Christian Heimes | cbf3b5c | 2007-12-03 21:02:03 +0000 | [diff] [blame] | 312 |  | 
|  | 313 | def python_logo(): | 
| Victor Stinner | 757db83 | 2010-01-30 02:16:55 +0000 | [diff] [blame] | 314 | with open("python_logo.jpg", "rb") as handle: | 
|  | 315 | return xmlrpc.client.Binary(handle.read()) | 
| Christian Heimes | cbf3b5c | 2007-12-03 21:02:03 +0000 | [diff] [blame] | 316 |  | 
|  | 317 | server = SimpleXMLRPCServer(("localhost", 8000)) | 
| Georg Brandl | f694518 | 2008-02-01 11:56:49 +0000 | [diff] [blame] | 318 | print("Listening on port 8000...") | 
| Christian Heimes | cbf3b5c | 2007-12-03 21:02:03 +0000 | [diff] [blame] | 319 | server.register_function(python_logo, 'python_logo') | 
|  | 320 |  | 
|  | 321 | server.serve_forever() | 
|  | 322 |  | 
|  | 323 | The client gets the image and saves it to a file:: | 
|  | 324 |  | 
| Georg Brandl | 38eceaa | 2008-05-26 11:14:17 +0000 | [diff] [blame] | 325 | import xmlrpc.client | 
| Christian Heimes | cbf3b5c | 2007-12-03 21:02:03 +0000 | [diff] [blame] | 326 |  | 
| Georg Brandl | 38eceaa | 2008-05-26 11:14:17 +0000 | [diff] [blame] | 327 | proxy = xmlrpc.client.ServerProxy("http://localhost:8000/") | 
| Victor Stinner | 757db83 | 2010-01-30 02:16:55 +0000 | [diff] [blame] | 328 | with open("fetched_python_logo.jpg", "wb") as handle: | 
|  | 329 | handle.write(proxy.python_logo().data) | 
| Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 330 |  | 
|  | 331 | .. _fault-objects: | 
|  | 332 |  | 
|  | 333 | Fault Objects | 
|  | 334 | ------------- | 
|  | 335 |  | 
|  | 336 | A :class:`Fault` object encapsulates the content of an XML-RPC fault tag. Fault | 
| Senthil Kumaran | a6bac95 | 2011-07-04 11:28:30 -0700 | [diff] [blame] | 337 | objects have the following attributes: | 
| Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 338 |  | 
|  | 339 |  | 
|  | 340 | .. attribute:: Fault.faultCode | 
|  | 341 |  | 
|  | 342 | A string indicating the fault type. | 
|  | 343 |  | 
|  | 344 |  | 
|  | 345 | .. attribute:: Fault.faultString | 
|  | 346 |  | 
|  | 347 | A string containing a diagnostic message associated with the fault. | 
|  | 348 |  | 
| Christian Heimes | cbf3b5c | 2007-12-03 21:02:03 +0000 | [diff] [blame] | 349 | In the following example we're going to intentionally cause a :exc:`Fault` by | 
|  | 350 | returning a complex type object.  The server code:: | 
|  | 351 |  | 
| Georg Brandl | 38eceaa | 2008-05-26 11:14:17 +0000 | [diff] [blame] | 352 | from xmlrpc.server import SimpleXMLRPCServer | 
| Christian Heimes | cbf3b5c | 2007-12-03 21:02:03 +0000 | [diff] [blame] | 353 |  | 
|  | 354 | # A marshalling error is going to occur because we're returning a | 
|  | 355 | # complex number | 
|  | 356 | def add(x,y): | 
|  | 357 | return x+y+0j | 
|  | 358 |  | 
|  | 359 | server = SimpleXMLRPCServer(("localhost", 8000)) | 
| Georg Brandl | f694518 | 2008-02-01 11:56:49 +0000 | [diff] [blame] | 360 | print("Listening on port 8000...") | 
| Christian Heimes | cbf3b5c | 2007-12-03 21:02:03 +0000 | [diff] [blame] | 361 | server.register_function(add, 'add') | 
|  | 362 |  | 
|  | 363 | server.serve_forever() | 
|  | 364 |  | 
|  | 365 | The client code for the preceding server:: | 
|  | 366 |  | 
| Georg Brandl | 38eceaa | 2008-05-26 11:14:17 +0000 | [diff] [blame] | 367 | import xmlrpc.client | 
| Christian Heimes | cbf3b5c | 2007-12-03 21:02:03 +0000 | [diff] [blame] | 368 |  | 
| Georg Brandl | 38eceaa | 2008-05-26 11:14:17 +0000 | [diff] [blame] | 369 | proxy = xmlrpc.client.ServerProxy("http://localhost:8000/") | 
| Christian Heimes | cbf3b5c | 2007-12-03 21:02:03 +0000 | [diff] [blame] | 370 | try: | 
|  | 371 | proxy.add(2, 5) | 
| Georg Brandl | 0dedf45 | 2009-05-22 16:44:06 +0000 | [diff] [blame] | 372 | except xmlrpc.client.Fault as err: | 
| Georg Brandl | 2ee470f | 2008-07-16 12:55:28 +0000 | [diff] [blame] | 373 | print("A fault occurred") | 
| Georg Brandl | f694518 | 2008-02-01 11:56:49 +0000 | [diff] [blame] | 374 | print("Fault code: %d" % err.faultCode) | 
|  | 375 | print("Fault string: %s" % err.faultString) | 
| Christian Heimes | cbf3b5c | 2007-12-03 21:02:03 +0000 | [diff] [blame] | 376 |  | 
|  | 377 |  | 
| Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 378 |  | 
|  | 379 | .. _protocol-error-objects: | 
|  | 380 |  | 
|  | 381 | ProtocolError Objects | 
|  | 382 | --------------------- | 
|  | 383 |  | 
|  | 384 | A :class:`ProtocolError` object describes a protocol error in the underlying | 
|  | 385 | transport layer (such as a 404 'not found' error if the server named by the URI | 
| Senthil Kumaran | a6bac95 | 2011-07-04 11:28:30 -0700 | [diff] [blame] | 386 | does not exist).  It has the following attributes: | 
| Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 387 |  | 
|  | 388 |  | 
|  | 389 | .. attribute:: ProtocolError.url | 
|  | 390 |  | 
|  | 391 | The URI or URL that triggered the error. | 
|  | 392 |  | 
|  | 393 |  | 
|  | 394 | .. attribute:: ProtocolError.errcode | 
|  | 395 |  | 
|  | 396 | The error code. | 
|  | 397 |  | 
|  | 398 |  | 
|  | 399 | .. attribute:: ProtocolError.errmsg | 
|  | 400 |  | 
|  | 401 | The error message or diagnostic string. | 
|  | 402 |  | 
|  | 403 |  | 
|  | 404 | .. attribute:: ProtocolError.headers | 
|  | 405 |  | 
| Guido van Rossum | 460add4 | 2007-08-23 02:13:35 +0000 | [diff] [blame] | 406 | A dict containing the headers of the HTTP/HTTPS request that triggered the | 
| Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 407 | error. | 
|  | 408 |  | 
| Christian Heimes | cbf3b5c | 2007-12-03 21:02:03 +0000 | [diff] [blame] | 409 | In the following example we're going to intentionally cause a :exc:`ProtocolError` | 
|  | 410 | by providing an invalid URI:: | 
|  | 411 |  | 
| Georg Brandl | 38eceaa | 2008-05-26 11:14:17 +0000 | [diff] [blame] | 412 | import xmlrpc.client | 
| Christian Heimes | cbf3b5c | 2007-12-03 21:02:03 +0000 | [diff] [blame] | 413 |  | 
| Benjamin Peterson | 5e55b3e | 2010-02-03 02:35:45 +0000 | [diff] [blame] | 414 | # create a ServerProxy with an URI that doesn't respond to XMLRPC requests | 
|  | 415 | proxy = xmlrpc.client.ServerProxy("http://google.com/") | 
| Christian Heimes | cbf3b5c | 2007-12-03 21:02:03 +0000 | [diff] [blame] | 416 |  | 
|  | 417 | try: | 
|  | 418 | proxy.some_method() | 
| Georg Brandl | 0dedf45 | 2009-05-22 16:44:06 +0000 | [diff] [blame] | 419 | except xmlrpc.client.ProtocolError as err: | 
| Georg Brandl | 2ee470f | 2008-07-16 12:55:28 +0000 | [diff] [blame] | 420 | print("A protocol error occurred") | 
| Georg Brandl | f694518 | 2008-02-01 11:56:49 +0000 | [diff] [blame] | 421 | print("URL: %s" % err.url) | 
|  | 422 | print("HTTP/HTTPS headers: %s" % err.headers) | 
|  | 423 | print("Error code: %d" % err.errcode) | 
|  | 424 | print("Error message: %s" % err.errmsg) | 
| Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 425 |  | 
|  | 426 | MultiCall Objects | 
|  | 427 | ----------------- | 
|  | 428 |  | 
| Sandro Tosi | 9daf98d | 2011-08-20 17:05:56 +0200 | [diff] [blame] | 429 | The :class:`MultiCall` object provides a way to encapsulate multiple calls to a | 
|  | 430 | remote server into a single request [#]_. | 
| Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 431 |  | 
|  | 432 |  | 
|  | 433 | .. class:: MultiCall(server) | 
|  | 434 |  | 
|  | 435 | Create an object used to boxcar method calls. *server* is the eventual target of | 
|  | 436 | the call. Calls can be made to the result object, but they will immediately | 
|  | 437 | return ``None``, and only store the call name and parameters in the | 
|  | 438 | :class:`MultiCall` object. Calling the object itself causes all stored calls to | 
|  | 439 | be transmitted as a single ``system.multicall`` request. The result of this call | 
| Georg Brandl | 9afde1c | 2007-11-01 20:32:30 +0000 | [diff] [blame] | 440 | is a :term:`generator`; iterating over this generator yields the individual | 
|  | 441 | results. | 
| Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 442 |  | 
| Andrew Kuchling | c3db373 | 2013-06-20 21:33:05 -0400 | [diff] [blame] | 443 | A usage example of this class follows.  The server code:: | 
| Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 444 |  | 
| Georg Brandl | 38eceaa | 2008-05-26 11:14:17 +0000 | [diff] [blame] | 445 | from xmlrpc.server import SimpleXMLRPCServer | 
| Christian Heimes | cbf3b5c | 2007-12-03 21:02:03 +0000 | [diff] [blame] | 446 |  | 
| Ezio Melotti | 79016e1 | 2013-08-08 15:45:56 +0300 | [diff] [blame] | 447 | def add(x, y): | 
|  | 448 | return x + y | 
| Christian Heimes | cbf3b5c | 2007-12-03 21:02:03 +0000 | [diff] [blame] | 449 |  | 
|  | 450 | def subtract(x, y): | 
| Ezio Melotti | 79016e1 | 2013-08-08 15:45:56 +0300 | [diff] [blame] | 451 | return x - y | 
| Christian Heimes | cbf3b5c | 2007-12-03 21:02:03 +0000 | [diff] [blame] | 452 |  | 
|  | 453 | def multiply(x, y): | 
| Ezio Melotti | 79016e1 | 2013-08-08 15:45:56 +0300 | [diff] [blame] | 454 | return x * y | 
| Christian Heimes | cbf3b5c | 2007-12-03 21:02:03 +0000 | [diff] [blame] | 455 |  | 
|  | 456 | def divide(x, y): | 
| Andrew Kuchling | c3db373 | 2013-06-20 21:33:05 -0400 | [diff] [blame] | 457 | return x // y | 
| Christian Heimes | cbf3b5c | 2007-12-03 21:02:03 +0000 | [diff] [blame] | 458 |  | 
|  | 459 | # A simple server with simple arithmetic functions | 
|  | 460 | server = SimpleXMLRPCServer(("localhost", 8000)) | 
| Georg Brandl | f694518 | 2008-02-01 11:56:49 +0000 | [diff] [blame] | 461 | print("Listening on port 8000...") | 
| Christian Heimes | cbf3b5c | 2007-12-03 21:02:03 +0000 | [diff] [blame] | 462 | server.register_multicall_functions() | 
|  | 463 | server.register_function(add, 'add') | 
|  | 464 | server.register_function(subtract, 'subtract') | 
|  | 465 | server.register_function(multiply, 'multiply') | 
|  | 466 | server.register_function(divide, 'divide') | 
|  | 467 | server.serve_forever() | 
|  | 468 |  | 
|  | 469 | The client code for the preceding server:: | 
|  | 470 |  | 
| Georg Brandl | 38eceaa | 2008-05-26 11:14:17 +0000 | [diff] [blame] | 471 | import xmlrpc.client | 
| Christian Heimes | cbf3b5c | 2007-12-03 21:02:03 +0000 | [diff] [blame] | 472 |  | 
| Georg Brandl | 38eceaa | 2008-05-26 11:14:17 +0000 | [diff] [blame] | 473 | proxy = xmlrpc.client.ServerProxy("http://localhost:8000/") | 
|  | 474 | multicall = xmlrpc.client.MultiCall(proxy) | 
| Ezio Melotti | 79016e1 | 2013-08-08 15:45:56 +0300 | [diff] [blame] | 475 | multicall.add(7, 3) | 
|  | 476 | multicall.subtract(7, 3) | 
|  | 477 | multicall.multiply(7, 3) | 
|  | 478 | multicall.divide(7, 3) | 
| Christian Heimes | cbf3b5c | 2007-12-03 21:02:03 +0000 | [diff] [blame] | 479 | result = multicall() | 
|  | 480 |  | 
| Ezio Melotti | 79016e1 | 2013-08-08 15:45:56 +0300 | [diff] [blame] | 481 | print("7+3=%d, 7-3=%d, 7*3=%d, 7//3=%d" % tuple(result)) | 
| Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 482 |  | 
|  | 483 |  | 
|  | 484 | Convenience Functions | 
|  | 485 | --------------------- | 
|  | 486 |  | 
| Georg Brandl | 7f01a13 | 2009-09-16 15:58:14 +0000 | [diff] [blame] | 487 | .. function:: dumps(params, methodname=None, methodresponse=None, encoding=None, allow_none=False) | 
| Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 488 |  | 
|  | 489 | Convert *params* into an XML-RPC request. or into a response if *methodresponse* | 
|  | 490 | is true. *params* can be either a tuple of arguments or an instance of the | 
|  | 491 | :exc:`Fault` exception class.  If *methodresponse* is true, only a single value | 
|  | 492 | can be returned, meaning that *params* must be of length 1. *encoding*, if | 
|  | 493 | supplied, is the encoding to use in the generated XML; the default is UTF-8. | 
|  | 494 | Python's :const:`None` value cannot be used in standard XML-RPC; to allow using | 
|  | 495 | it via an extension,  provide a true value for *allow_none*. | 
|  | 496 |  | 
|  | 497 |  | 
| Florent Xicluna | 6166519 | 2011-11-15 20:53:25 +0100 | [diff] [blame] | 498 | .. function:: loads(data, use_datetime=False, use_builtin_types=False) | 
| Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 499 |  | 
|  | 500 | Convert an XML-RPC request or response into Python objects, a ``(params, | 
|  | 501 | methodname)``.  *params* is a tuple of argument; *methodname* is a string, or | 
|  | 502 | ``None`` if no method name is present in the packet. If the XML-RPC packet | 
|  | 503 | represents a fault condition, this function will raise a :exc:`Fault` exception. | 
| Florent Xicluna | 6166519 | 2011-11-15 20:53:25 +0100 | [diff] [blame] | 504 | The *use_builtin_types* flag can be used to cause date/time values to be | 
|  | 505 | presented as :class:`datetime.datetime` objects and binary data to be | 
|  | 506 | presented as :class:`bytes` objects; this flag is false by default. | 
|  | 507 |  | 
|  | 508 | The obsolete *use_datetime* flag is similar to *use_builtin_types* but it | 
|  | 509 | applies only to date/time values. | 
|  | 510 |  | 
|  | 511 | .. versionchanged:: 3.3 | 
|  | 512 | The *use_builtin_types* flag was added. | 
| Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 513 |  | 
| Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 514 |  | 
|  | 515 | .. _xmlrpc-client-example: | 
|  | 516 |  | 
|  | 517 | Example of Client Usage | 
|  | 518 | ----------------------- | 
|  | 519 |  | 
|  | 520 | :: | 
|  | 521 |  | 
|  | 522 | # simple test program (from the XML-RPC specification) | 
| Georg Brandl | 38eceaa | 2008-05-26 11:14:17 +0000 | [diff] [blame] | 523 | from xmlrpc.client import ServerProxy, Error | 
| Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 524 |  | 
|  | 525 | # server = ServerProxy("http://localhost:8000") # local server | 
|  | 526 | server = ServerProxy("http://betty.userland.com") | 
|  | 527 |  | 
| Collin Winter | c79461b | 2007-09-01 23:34:30 +0000 | [diff] [blame] | 528 | print(server) | 
| Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 529 |  | 
|  | 530 | try: | 
| Collin Winter | c79461b | 2007-09-01 23:34:30 +0000 | [diff] [blame] | 531 | print(server.examples.getStateName(41)) | 
| Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 532 | except Error as v: | 
| Collin Winter | c79461b | 2007-09-01 23:34:30 +0000 | [diff] [blame] | 533 | print("ERROR", v) | 
| Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 534 |  | 
|  | 535 | To access an XML-RPC server through a proxy, you need to define  a custom | 
| Christian Heimes | 5b5e81c | 2007-12-31 16:14:33 +0000 | [diff] [blame] | 536 | transport.  The following example shows how: | 
| Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 537 |  | 
| Christian Heimes | 5b5e81c | 2007-12-31 16:14:33 +0000 | [diff] [blame] | 538 | .. Example taken from http://lowlife.jp/nobonobo/wiki/xmlrpcwithproxy.html | 
| Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 539 |  | 
|  | 540 | :: | 
|  | 541 |  | 
| Georg Brandl | 2442015 | 2008-05-26 16:32:26 +0000 | [diff] [blame] | 542 | import xmlrpc.client, http.client | 
| Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 543 |  | 
| Georg Brandl | 38eceaa | 2008-05-26 11:14:17 +0000 | [diff] [blame] | 544 | class ProxiedTransport(xmlrpc.client.Transport): | 
| Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 545 | def set_proxy(self, proxy): | 
|  | 546 | self.proxy = proxy | 
|  | 547 | def make_connection(self, host): | 
|  | 548 | self.realhost = host | 
| Georg Brandl | 06788c9 | 2009-01-03 21:31:47 +0000 | [diff] [blame] | 549 | h = http.client.HTTP(self.proxy) | 
|  | 550 | return h | 
| Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 551 | def send_request(self, connection, handler, request_body): | 
|  | 552 | connection.putrequest("POST", 'http://%s%s' % (self.realhost, handler)) | 
|  | 553 | def send_host(self, connection, host): | 
|  | 554 | connection.putheader('Host', self.realhost) | 
|  | 555 |  | 
|  | 556 | p = ProxiedTransport() | 
|  | 557 | p.set_proxy('proxy-server:8080') | 
| Georg Brandl | 38eceaa | 2008-05-26 11:14:17 +0000 | [diff] [blame] | 558 | server = xmlrpc.client.Server('http://time.xmlrpc.com/RPC2', transport=p) | 
| Collin Winter | c79461b | 2007-09-01 23:34:30 +0000 | [diff] [blame] | 559 | print(server.currentTime.getCurrentTime()) | 
| Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 560 |  | 
| Christian Heimes | cbf3b5c | 2007-12-03 21:02:03 +0000 | [diff] [blame] | 561 |  | 
|  | 562 | Example of Client and Server Usage | 
|  | 563 | ---------------------------------- | 
|  | 564 |  | 
|  | 565 | See :ref:`simplexmlrpcserver-example`. | 
|  | 566 |  | 
|  | 567 |  | 
| Sandro Tosi | 9daf98d | 2011-08-20 17:05:56 +0200 | [diff] [blame] | 568 | .. rubric:: Footnotes | 
|  | 569 |  | 
|  | 570 | .. [#] This approach has been first presented in `a discussion on xmlrpc.com | 
|  | 571 | <http://web.archive.org/web/20060624230303/http://www.xmlrpc.com/discuss/msgReader$1208?mode=topic>`_. | 
|  | 572 | .. the link now points to webarchive since the one at | 
|  | 573 | .. http://www.xmlrpc.com/discuss/msgReader%241208 is broken (and webadmin | 
|  | 574 | .. doesn't reply) |