It's only a matter to put together Reportlab to generate a pdf file on the fly and Cherrypy xmlrpc filter to serve it as an XML/RPC binary object (base64-encoded).
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51 | #################################################################
#################################################################
import xmlrpclib
from cherrypy.lib.filter.xmlrpcfilter import XmlRpcFilter
from cherrypy import cpg
from reportlab.pdfgen import canvas
class Root:
_cpFilterList = [XmlRpcFilter()]
def _cpOnError(self):
import traceback, StringIO
bodyFile = StringIO.StringIO()
traceback.print_exc(file = bodyFile)
errorBody = bodyFile.getvalue()
if cpg.request.isRPC:
## isRPC boolean is set on xml-rpc requests by the filter
## convert the traceback to a dumped Fault object:
## the XML-RPC exception
cpg.response.body = [xmlrpclib.dumps(xmlrpclib.Fault(1,errorBody))]
else:
## handle regular web errors
cpg.response.body = ['<pre>%s</pre>' % errorBody]
def getPdf(self,aMsg):
c = canvas.Canvas(None)
c.drawString(100,100,aMsg)
c.showPage()
c.save()
return xmlrpclib.Binary(c.getpdfdata())
getPdf.exposed = True
cpg.root = Root()
if __name__=='__main__':
cpg.server.start(configMap = {'socketPort': 9001,
'threadPool':0,
'socketQueueSize':10 })
########################################################
########################################################
# a simple client ######################################
########################################################
import xmlrpclib
server = xmlrpclib.ServerProxy('http://localhost:9001')
f = open('helloWorld.pdf','w')
f.write(server.getPdf('Hello World!').data)
f.close()
########################################################
########################################################
|
Comments
Even simpler using mod_python and Vampire. Even simpler when using mod_python and Vampire, as you don't need to add any special error handling code which determines whether it was an XML-RPC request or not.
Setting the "handler" to be an actual service object, automatically ensures that all the appropriate XML-RPC specific work is done. The object being wrapped as a service can be an existing object which knows nothing about mod_python, whereas in the original example the XML-RPC code is intertwined with the CherryPy code.
Mod_python is available from "http://www.modpython.org" and Vampire from "http://www.dscpl.com.au/projects/vampire".
Sign in to comment