From 02ad8ec61d3ed548dda7455e1f7c298df7b820bb Mon Sep 17 00:00:00 2001 From: jortel Date: Tue, 11 May 2010 20:44:48 +0000 Subject: Add Plugins facility. Supports hooks for onInit(), onLoad(), onSend() onReply() events. --- suds/client.py | 14 ++++++++++++-- suds/options.py | 3 +++ suds/wsdl.py | 3 +++ suds/xsd/doctor.py | 10 +++++++++- suds/xsd/schema.py | 7 +++---- tests/axis1.py | 18 +++++++++++++++++- 6 files changed, 47 insertions(+), 8 deletions(-) diff --git a/suds/client.py b/suds/client.py index a67e50f..336125f 100644 --- a/suds/client.py +++ b/suds/client.py @@ -40,6 +40,7 @@ from suds.options import Options from suds.properties import Unskin from urlparse import urlparse from copy import deepcopy +from suds.plugin import PluginContainer from logging import getLogger log = getLogger(__name__) @@ -109,6 +110,8 @@ class Client(object): self.set_options(**kwargs) reader = DefinitionsReader(options, Definitions) self.wsdl = reader.open(url) + plugins = PluginContainer(options.plugins) + plugins.onInit(wsdl=self.wsdl) self.factory = Factory(self.wsdl) self.service = ServiceSelector(self, self.wsdl.services) self.sd = [] @@ -593,13 +596,15 @@ class SoapClient: timer.stop() metrics.log.debug( "message for '%s' created: %s", - self.method.name, timer) + self.method.name, + timer) timer.start() result = self.send(msg) timer.stop() metrics.log.debug( "method '%s' invoked: %s", - self.method.name, timer) + self.method.name, + timer) return result def send(self, msg): @@ -618,6 +623,8 @@ class SoapClient: log.debug('sending to (%s)\nmessage:\n%s', location, msg) try: self.last_sent(Document(msg)) + plugins = PluginContainer(self.options.plugins) + plugins.onSend(env=msg) request = Request(location, str(msg)) request.headers = self.headers() reply = transport.send(request) @@ -655,6 +662,9 @@ class SoapClient: @raise WebFault: On server. """ log.debug('http succeeded:\n%s', reply) + plugins = PluginContainer(self.options.plugins) + ctx = plugins.onReply(reply=reply) + reply = ctx.reply if len(reply) > 0: r, p = binding.get_reply(self.method, reply) self.last_received(r) diff --git a/suds/options.py b/suds/options.py index 4cf3660..36f1732 100644 --- a/suds/options.py +++ b/suds/options.py @@ -93,6 +93,8 @@ class Options(Skin): - 0 = Cache XML documents. - 1 = Cache WSDL (pickled) object. - default: 0 + - B{plugins} - A plugin container. + - type: I{list} """ def __init__(self, **kwargs): domain = __name__ @@ -111,5 +113,6 @@ class Options(Skin): Definition('retxml', bool, False), Definition('autoblend', bool, False), Definition('cachingpolicy', int, 0), + Definition('plugins', [], (list, tuple)), ] Skin.__init__(self, domain, definitions, kwargs) diff --git a/suds/wsdl.py b/suds/wsdl.py index 8bba88f..7c89fa9 100644 --- a/suds/wsdl.py +++ b/suds/wsdl.py @@ -31,6 +31,7 @@ from suds.xsd.schema import Schema, SchemaCollection from suds.xsd.query import ElementQuery from suds.sudsobject import Object, Facade, Metadata from suds.reader import DocumentReader, DefinitionsReader +from suds.plugin import PluginContainer from urlparse import urljoin import re, soaparray @@ -135,6 +136,8 @@ class Definitions(WObject): reader = DocumentReader(options) d = reader.open(url) root = d.root() + plugins = PluginContainer(options.plugins) + plugins.onLoad(root=root) WObject.__init__(self, root) self.id = objid(self) self.options = options diff --git a/suds/xsd/doctor.py b/suds/xsd/doctor.py index 84c9151..2ac3521 100644 --- a/suds/xsd/doctor.py +++ b/suds/xsd/doctor.py @@ -22,6 +22,7 @@ schema(s). from logging import getLogger from suds.sax import splitPrefix, Namespace from suds.sax.element import Element +from suds.plugin import Plugin log = getLogger(__name__) @@ -186,7 +187,7 @@ class Import: return 0 -class ImportDoctor(Doctor): +class ImportDoctor(Doctor, Plugin): """ Doctor used to fix missing imports. @ivar imports: A list of imports to apply. @@ -210,3 +211,10 @@ class ImportDoctor(Doctor): def examine(self, root): for imp in self.imports: imp.apply(root) + + def onLoad(self, context): + root = context.root + if root.get('name') == 'schema': + self.examine(root) + else: + pass \ No newline at end of file diff --git a/suds/xsd/schema.py b/suds/xsd/schema.py index 4194673..f2aedfa 100644 --- a/suds/xsd/schema.py +++ b/suds/xsd/schema.py @@ -33,6 +33,7 @@ from suds.xsd.sxbase import SchemaObject from suds.xsd.deplist import DepList from suds.sax.element import Element from suds.sax import splitPrefix, Namespace +from suds.plugin import PluginContainer log = getLogger(__name__) @@ -168,10 +169,6 @@ class Schema: @type container: L{SchemaCollection} @ivar children: A list of direct top level children. @type children: [L{SchemaObject},...] - @ivar all: A children. - @type all: [L{SchemaObject},...] - @ivar groups: A schema groups cache. - @type groups: {name:L{SchemaObject}} @ivar all: A list of all (includes imported) top level children. @type all: [L{SchemaObject},...] @ivar types: A schema types cache. @@ -217,6 +214,8 @@ class Schema: self.attributes = {} self.groups = {} self.agrps = {} + plugins = PluginContainer(options.plugins) + plugins.onLoad(root=root) if options.doctor is not None: options.doctor.examine(root) form = self.root.get('elementFormDefault') diff --git a/tests/axis1.py b/tests/axis1.py index d06823d..3ae3225 100644 --- a/tests/axis1.py +++ b/tests/axis1.py @@ -29,6 +29,7 @@ from suds import WebFault from suds.client import Client from suds.sudsobject import Object from suds.transport.https import HttpAuthenticated +from suds.plugin import Plugin errors = 0 @@ -37,6 +38,21 @@ credentials = dict(username='jortel', password='abc123') setup_logging() +class TestPlugin(Plugin): + + def onInit(self, context): + print 'init: ctx=%s' % context.__dict__ + + def onLoad(self, context): + print 'loading: ctx=%s' % context.__dict__ + + def onSend(self, context): + print 'sending: ctx=%s' % context.__dict__ + + def onReply(self, context): + print 'gotreply: ctx=%s' % context.__dict__ + + #logging.getLogger('suds.client').setLevel(logging.DEBUG) def start(url): @@ -48,7 +64,7 @@ try: url = 'http://localhost:8081/axis/services/basic-rpc-encoded?wsdl' start(url) t = HttpAuthenticated(**credentials) - client = Client(url, transport=t, cache=None) + client = Client(url, transport=t, cache=None, plugins=[TestPlugin()]) print client # # create a name object using the wsdl -- cgit v1.2.1