ne legyünk rest-ek továbblépni, azaz soap web szolgáltatások
TRANSCRIPT
Mi a baj a REST-el?
Mikor használjunk SOAP-ot?
● Magas biztonság (WS-Sec, XMLSec, SAML)
● Aszinkron szolgáltatás● Állapottartó szolgáltatás (WS-Addressing)● Ipari környezet, sokféle nem ismert kliens● Interface specifikació formálisan kell● Service felfedezés
Problémák
Típusos interfész vs.
nem erősen típusos nyelv
Python SOAP lib?
● SOAPpy – nem standard, nehézkes tipus kezelés
● ZSI – nem standard, túl körülményes típus kezelés
● soaplib – névterek kezelésének hiánya
decorator_with_args = lambda decorator: lambda *args, **kwargs: lambda func: decorator(func, *args, **kwargs)
@decorator_with_argsdef soapmethod(func, *params, **kwparams): @functools.wraps(func) def wrapper(*args, **kwargs): return func(*args, **kwargs) wrapper.__doc__ = func.__doc__ wrapper.__name__ = func.__name__ wrapper.soap_descriptor = FunctionDescriptor(func, *params, **kwparams) return wrapper
Sebesség: lxml!
Szolgáltatás
from soaplib.serializers.primitive import String, DateTimefrom soaplib.serializers.clazz import ClassSerializer
class Organization(ClassSerializer): class types: name = String domain_name = String created = DateTime account_id = String def __init__(self, obj=None): super(Organization, self).__init__() if obj is not None: self.name = obj.name self.domain_name = obj.domain_name self.created = obj.created self.account_id = obj.account_id
class OrganizationService(DjangoSOAP): __tns__ = 'urn:genie:service:api'
@soapmethod(String, identity.soap_data.Identity, soap_data.Organization, order.soap_data.Customer, _returns=soap_data.Organization) def create(self, token, admin, org, customer): [...]
o = Organization.objects.get(...) [...] return soap_data.Organization(o)
class String(object): def __init__(self, ns=None): self._xs_type_ = 'xs:string' self.__tns__ = ns
def to_xml(self, name, value, ns=None, nsmap={}): if value is None: return Null.to_xml(name, value, ns, nsmap) if type(value) != unicode: value = unicode(value, 'utf-8') element = create_element(name, ns, nsmap) element.text = value element.set('{%s}type' % XSI_NS, self._xs_type_) return element
def from_xml(self, element): type = element.get('{%s}type' % XSI_NS, self._xs_type_) if type != self._xs_type_: raise InvalidXSDTypeError() if element.text is None: return None try: u = unicode(element.text) return u.encode('utf-8') except: return element.text
Kliens
from service import soapmethod, SoapServicefrom serializers.primitive import String, Integerfrom serializers.clazz import ClassSerializerfrom client import SoapClient
class GetBalanceRequestType(ClassSerializer): __tns__ = 'urn:ebay:apis:eBLBaseComponents' class types: Version = String GetAllCurrencies = String
class PayPalService(SoapService): __tns__ = 'urn:ebay:api:PayPalAPI' @soapmethod(GetBalanceRequestType) def GetBalanceReq(self, GetBalanceRequest): pass
c = SoapClient('https://foo', PayPalService(), 'cert_key.pem')print c.GetBalanceReq(GetBalanceRequestType(Version="55.0", GetAllCyrrencies="1"), headers=soap_headers)