Package ndg :: Package soap
[hide private]

Source Code for Package ndg.soap

  1  """SOAP common package for NDG SAML.   
  2   
  3  Initially for use with SAML SOAP Bindings.  This itself 
  4  uses ElementTree.  This SOAP interface provides an ElementTree interface to 
  5  support it 
  6   
  7  NERC DataGrid Project 
  8  """ 
  9  __author__ = "P J Kershaw" 
 10  __date__ = "24/07/09" 
 11  __copyright__ = "(C) 2009 Science and Technology Facilities Council" 
 12  __license__ = "http://www.apache.org/licenses/LICENSE-2.0" 
 13  __contact__ = "Philip.Kershaw@stfc.ac.uk" 
 14  __revision__ = '$Id: __init__.py 7130 2010-06-30 13:33:07Z pjkersha $' 
 15  import logging 
 16  log = logging.getLogger(__name__) 
17 18 19 -class Config(object):
20 """Configuration options 21 @type use_lxml: bool 22 @cvar use_lxml: Controls whether lxml.etree should be imported instead of 23 etree. lxml is required for XPath expressions with conditions. 24 """ 25 use_lxml = None
26
27 -def importElementTree():
28 """Imports ElementTree or the lxml ElementTree API depending on the 29 Config.use_lxml value and whether the lxml package is found. 30 @rtype: module 31 @return: the element tree module that has been imported 32 """ 33 if Config.use_lxml is not None: 34 if Config.use_lxml: 35 from lxml import etree as ElementTree 36 else: 37 try: # python 2.5 38 from xml.etree import ElementTree 39 except ImportError: 40 # if you've installed it yourself it comes this way 41 import ElementTree 42 else: 43 Config.use_lxml = False 44 try: 45 from lxml import etree as ElementTree 46 Config.use_lxml = True 47 except ImportError: 48 try: # python 2.5 49 from xml.etree import ElementTree 50 except ImportError: 51 # if you've installed it yourself it comes this way 52 import ElementTree 53 return ElementTree
54
55 -class SOAPObject(object):
56 """Base class for SOAP envelope, header and body elements""" 57 58 ELEMENT_PREFIX = "soap11" 59 SOAP11_NS = "http://schemas.xmlsoap.org/soap/envelope/" 60 SOAP12_NS = "http://www.w3.org/2003/05/soap-envelope" 61 DEFAULT_NS = SOAP11_NS 62 63 __slots__ = () 64
65 - def create(self):
66 raise NotImplementedError()
67
68 - def parse(self, source):
69 raise NotImplementedError()
70
71 - def serialize(self):
72 raise NotImplementedError()
73
74 - def prettyPrint(self):
75 raise NotImplementedError()
76
77 78 -class SOAPEnvelopeBase(SOAPObject):
79 """SOAP Envelope""" 80 81 DEFAULT_ELEMENT_LOCAL_NAME = "Envelope" 82 DEFAULT_ELEMENT_NS = SOAPObject.DEFAULT_NS 83 DEFAULT_ELEMENT_NS_PREFIX = SOAPObject.ELEMENT_PREFIX 84 85 soapHeader = property() 86 soapBody = property() 87 88 __slots__ = ()
89
90 91 -class SOAPHeaderBase(SOAPObject):
92 """SOAP Header base class""" 93 94 DEFAULT_ELEMENT_LOCAL_NAME = "Header" 95 DEFAULT_ELEMENT_NS = SOAPObject.DEFAULT_NS 96 DEFAULT_ELEMENT_NS_PREFIX = SOAPObject.ELEMENT_PREFIX 97 __slots__ = ()
98
99 100 -class SOAPBodyBase(SOAPObject):
101 """SOAP Body base class""" 102 103 DEFAULT_ELEMENT_LOCAL_NAME = "Body" 104 DEFAULT_ELEMENT_NS = SOAPObject.DEFAULT_NS 105 DEFAULT_ELEMENT_NS_PREFIX = SOAPObject.ELEMENT_PREFIX 106 fault = property() 107 __slots__ = ()
108
109 110 -class SOAPFaultBase(SOAPObject):
111 """SOAP Fault""" 112 113 DEFAULT_ELEMENT_LOCAL_NAME = "Fault" 114 DEFAULT_ELEMENT_NS = SOAPObject.DEFAULT_NS 115 DEFAULT_ELEMENT_NS_PREFIX = SOAPObject.ELEMENT_PREFIX 116 117 FAULT_CODE_ELEMENT_LOCAL_NAME = "faultcode" 118 FAULT_STRING_ELEMENT_LOCAL_NAME = "faultstring" 119 FAULT_ACTOR_ELEMENT_LOCAL_NAME = "faultactor" 120 DETAIL_ELEMENT_LOCAL_NAME = "detail" 121 122 VERSION_MISMATCH_CODE = "VersionMismatch" 123 MUST_UNDERSTAND_FAULT_CODE = "MustUnderstand" 124 CLIENT_FAULT_CODE = "Client" 125 SERVER_FAULT_CODE = "Server" 126 127 FAULT_CODES = ( 128 VERSION_MISMATCH_CODE, 129 MUST_UNDERSTAND_FAULT_CODE, 130 CLIENT_FAULT_CODE, 131 SERVER_FAULT_CODE 132 ) 133 134 __slots__ = ("__faultCode", "__faultString", "__faultActor", "__detail") 135
136 - def __init__(self, faultString=None, faultCode=None, faultActor=None, 137 detail=None):
138 """Initialise attributes""" 139 super(SOAPFaultBase, self).__init__() 140 141 if faultCode is None: 142 self.__faultCode = None 143 else: 144 self.faultCode = faultCode 145 146 if faultString is None: 147 self.__faultString = None 148 else: 149 self.faultString = faultString 150 151 if faultActor is None: 152 self.__faultActor = None 153 else: 154 self.faultActor = faultActor 155 156 if detail is None: 157 self.__detail = None 158 else: 159 self.detail = detail
160
161 - def _setFaultCode(self, value):
162 if not isinstance(value, basestring): 163 raise AttributeError('Expecting string type for "faultCode" ' 164 'attribute; got %r' % type(value)) 165 166 qnameElems = value.split(':') 167 if len(qnameElems) == 0: 168 raise AttributeError('Expecting Qualified Name for "faultCode" ' 169 'attribute; got %r' % value) 170 171 faultCodeFound = [qnameElems[1].startswith(i) 172 for i in self.__class__.FAULT_CODES] 173 if max(faultCodeFound) == False: 174 raise AttributeError('Expecting "faultCode" prefixed with one of ' 175 '%r; got %r' % (self.__class__.FAULT_CODES, 176 value)) 177 178 self.__faultCode = value
179
180 - def _getFaultCode(self):
181 return self.__faultCode
182 183 faultCode = property(_getFaultCode, _setFaultCode, 184 doc="Fault Code") 185
186 - def _setFaultString(self, value):
187 if not isinstance(value, basestring): 188 raise AttributeError('Expecting string type for "faultString" ' 189 'attribute; got %r' % type(value)) 190 self.__faultString = value
191
192 - def _getFaultString(self):
193 return self.__faultString
194 195 faultString = property(_getFaultString, _setFaultString, 196 doc="Fault String") 197
198 - def _getFaultActor(self):
199 return self.__faultActor
200
201 - def _setFaultActor(self, value):
202 if not isinstance(value, basestring): 203 raise AttributeError('Expecting string type for "faultActor" ' 204 'attribute; got %r' % type(value)) 205 self.__faultActor = value
206 207 faultActor = property(_getFaultActor, _setFaultActor, 208 doc="Fault Actor") 209
210 - def _getDetail(self):
211 return self.__detail
212
213 - def _setDetail(self, value):
214 """No type checking - detail could be an XML element or serialised 215 string content""" 216 self.__detail = value
217 218 detail = property(_getDetail, _setDetail, doc="Fault detail")
219
220 221 -class SOAPException(Exception):
222 """Base SOAP Exception class"""
223
224 225 -class SOAPFaultException(Exception):
226 """Raise an exception which also creates a fault object""" 227 SOAP_FAULT_CLASS = SOAPFaultBase 228
229 - def __init__(self, faultString, faultCode, faultActor=None, detail=None):
230 super(SOAPFaultException, self).__init__(faultString) 231 self.__fault = self.__class__.SOAP_FAULT_CLASS(faultString, faultCode, 232 faultActor=faultActor, 233 detail=detail)
234 235 @property
236 - def fault(self):
237 """Get SOAP fault object""" 238 return self.__fault
239