Flask-XML-RPC is an extension for Flask that makes it easy to create APIs based on the XML-RPC standard.
If you’re using easy_install, then run this command to install Flask-XML-RPC:
$ easy_install Flask-XML-RPC
Or, if you’re using pip (which is recommended, since it’s awesome):
$ pip install Flask-XML-RPC
This is a REALLY simple example of how to create your own API using Flask-XML-RPC.
from flask import Flask
from flaskext.xmlrpc import XMLRPCHandler, Fault
app = Flask(__name__)
handler = XMLRPCHandler('api')
handler.connect(app, '/api')
@handler.register
def hello(name="world"):
if not name:
raise Fault("unknown_recipient", "I need someone to greet!")
return "Hello, %s!" % name
app.run()
Of course, the register_function() method can take a name if you want to use dotted names, but it’s easier to use namespaces. You get a namespace by calling the namespace() method with the prefix you want (without the dot).
handler = XMLRPCHandler('api')
blog = handler.namespace('blog')
@blog.register
def add_post(title, text):
# do whatever...
pass
The add_post function will then be available as blog.add_post. You can create namespaces from namespaces, as well.
blog_media = blog.namespace('media')
@blog_media.register
def delete(filename):
# do whatever...
pass
In this case, delete will be available as blog.media.delete. Namespacing can help you organize your API in a logical way.
The easiest way to test your application is with the XMLRPCTester. It takes a werkzeug.TestClient and the path to your responder. When called with the method and params, it will marshal it, make a fake POST request to the responder with the client, and demarshal the result for you, returning it or a Fault.
If you’re using a unittest-based setup like the one described in the Flask documentation, you could use the XMLRPCTester like:
def test_hello(self):
tester = XMLRPCTester(self.app, '/api')
assert tester('hello') == 'Hello, world!'
assert tester('hello', 'Steve') == 'Hello, Steve!'
fault = tester('hello', '')
assert fault.faultCode == 'unknown_recipient'
XMLRPCTester is actually a wrapper for test_xmlrpc_call(), which takes the client, responder path, method, and params.
If you prefer to marshal the XML-RPC data and make the requests yourself, the two functions dump_method_call() and load_method_response() are useful wrappers around the low-level xmlrpclib marshaling functions.
Practically all programming languages can use XML-RPC. In Python, you can call XML-RPC methods with the standard library xmlrpclib module.
>>> import xmlrpclib
>>> server = xmlrpclib.ServerProxy('http://localhost:5000/')
>>> server.hello()
'Hello, world!'
>>> server.hello('Steve')
'Hello, Steve!'
For other languages, please check their documentation.
This is the basic XML-RPC handler class. To use it, you create it:
handler = XMLRPCHandler('api')
Then, you can register functions with the register() method:
@handler.register
def spam():
pass
register() is just an alias for register_function(), so you can use that too. You can also register an instance using the register_instance() method, and any methods on said instance will be exposed if they do not start with an _.
Then, you connect it to a Flask instance or a Flask module with the connect() method, like this:
handler.connect(app, '/')
Parameters: |
|
---|
Connects the handler to an app or module. You have to provide the app and the URL route to use. The route can’t contain any variable parts, because there is no way to get them to the method.
handler.connect(app, '/api')
Parameters: |
|
---|
This returns a XMLRPCNamespace object, which has register() and register_function() methods. These forward directly to the register_function() method of the parent they were created from, but they will prepend the given prefix, plus a dot, to the name registered. For example:
blog = handler.namespace('blog')
@blog.register
def new_post(whatever):
pass
would make new_post available as blog.new_post.
Parameter: | prefix – The name to prefix the methods with. |
---|
This will register the given function. There are two ways to use it.
As a plain old method, with or without a name:
handler.register_function(spam)
handler.register_function(spam, 'spam')
As a decorator, also with or without a name:
@handler.register_function
def spam():
pass
@handler.register_function('spam')
def spam():
pass
It’s shorter and easier to use register(), however, as it does the exact same thing.
Parameters: |
|
---|
This registers any kind of object. If the requested method hasn’t been registered by register_function(), it will be checked against the instance. You can only have one instance at a time, however.
If allow_dotted_names is True, the name will be split on the dots and the object will be traveled down recursively. However, this is a HUGE SECURITY LOOPHOLE, as while private methods (starting with _) will not be exposed, it’s still possible that someone could get access to your globals and do very bad things. So don’t do it unless you have a very good reason.
Parameters: |
|
---|
This is a simple proxy that can register methods, and passes them on to the XMLRPCHandler that created it with a given name added as a prefix (with a dot). For more nesting, you can create namespaces from namespaces with the namespace() method.
Parameters: |
|
---|
Returns another namespace for the same handler, with the given name postfixed to the current namespace’s prefix. For example,
handler.namespace('foo').namespace('bar')
gives the same result as:
handler.namespace('foo.bar')
Parameter: | prefix – The name to prefix the methods with. |
---|
Registers a function. Use is the same as with the XMLRPCHandler.register_function() method.
Parameters: |
|
---|
This lets you conveniently make method calls using a Werkzeug Client, like the one returned by flask.Flask.test_client(). You create it with the Client and the path to the responder, and then you call it with the method and params.
Parameters: |
|
---|
This calls the client’s post method with the responder path, the marshaled method call, and a content type of text/xml. It will return the unmarshaled response or fault.
You can just call the instance like a function for the same effect. These two calls are equivalent:
tester.call('hello', 'world')
tester('hello', 'world')
Parameters: |
|
---|
This makes a method call using a Werkzeug Client, such as the one returned by flask.Flask.test_client(). It constructs the method call, makes the request, and then returns the response value or a Fault.
Parameters: |
|
---|
This marshals the given method and parameters into a proper XML-RPC method call. It’s very useful for testing.
Parameters: |
|
---|
This returns the actual value returned from an XML-RPC response. If it’s a Fault instance, it will return the fault instead of the value. This is also useful for testing.
Parameter: | response – The marshaled XML-RPC method response or fault. |
---|