【问题标题】:adding an attribute in suds在 suds 中添加属性
【发布时间】:2011-04-07 22:26:59
【问题描述】:

我必须使用 suds 和 Python 进行肥皂请求

<soap:Body> 
    <registerOrder> 
        <order merchantOrderNumber="" description="" amount=""  currency=""  language=""  xmlns=""> 
             <returnUrl>http://mysafety.com</returnUrl> 
        </order> 
    </registerOrder> 
</soap:Body>

如何在 registerOrder 中添加属性?

【问题讨论】:

    标签: python web-services suds


    【解决方案1】:

    MessagePlugin 的更动态版本是:

    from suds.sax.attribute import Attribute
    from suds.plugin import MessagePlugin
    
    class _AttributePlugin(MessagePlugin):
        """
        Suds plug-in extending the method call with arbitrary attributes.
        """
        def __init__(self, **kwargs):
            self.kwargs = kwargs
    
        def marshalled(self, context):
            method = context.envelope.getChild('Body')[0]
            for key, item in self.kwargs.iteritems():
                method.attributes.append(Attribute(key, item))
    

    用法:

    client = Client(url)
    # method 1
    client.options.plugins = [_AttributePlugin(foo='bar')]
    response = client.service.method1()
    client.options.plugins = []
    # method 2
    response = client.service.method2()
    

    【讨论】:

      【解决方案2】:

      suds documentation 中搜索 MessagePlugin。编组选项是您正在搜索的内容。您需要将其作为插件添加到您的客户端中:

      self.client = Client(url, plugins=[MyPlugin()])
      

      在编组方法中搜索 context.envelope 子项。 python 的 vars() 函数在这个地方非常有用。我认为,它应该适合您:

      from suds.sax.attribute import Attribute
      from suds.plugin import MessagePlugin
      class MyPlugin(MessagePlugin):
          def marshalled(self, context):
              foo = context.envelope.getChild('Body').getChild('registerOrder')[0]
              foo.attributes.append(Attribute("foo", "bar"))
      

      上周我坐在这里,所以它可能会为你节省一些时间:)

      【讨论】:

        【解决方案3】:

        您可以使用 __inject Client 选项来注入特定的 xml

        raw_xml = """<?xml version="1.0" encoding="UTF-8"?>
        <SOAP-ENV:Envelope>
            <SOAP-ENV:Body>
                ...
            </SOAP-ENV:Body>
        </SOAP-ENV:Envelope>"""
        
        print client.service.example(__inject={'msg':raw_xml})
        

        另外,我更喜欢使用 suds-jurko https://pypi.python.org/pypi/suds-jurko/0.6,它是一个积极维护的 suds 分支。

        【讨论】:

          【解决方案4】:

          我已经重用了https://fedorahosted.org/suds/ticket/21 并修改了代码以使用这个想法。如下更改 SUDS 并使用

          Client.<method>(param1=value1, ... , attributes={'attrName1':'attrVal1'} )
          

          根据需要调用带有“attrName1”属性的“方法”。

          --- a/website/suds/bindings/binding.py
          +++ b/website/suds/bindings/binding.py
          @@ -24,6 +24,7 @@ from suds.sax import Namespace
           from suds.sax.parser import Parser
           from suds.sax.document import Document
           from suds.sax.element import Element
          +from suds.sax.attribute import Attribute
           from suds.sudsobject import Factory, Object
           from suds.mx import Content
           from suds.mx.literal import Literal as MxLiteral
          @@ -101,7 +102,7 @@ class Binding:
                   """
                   raise Exception, 'not implemented'
          
          -    def get_message(self, method, args, kwargs):
          +    def get_message(self, method, args, kwargs, attributes=None):
                   """
                   Get the soap message for the specified method, args and soapheaders.
                   This is the entry point for creating the outbound soap message.
          @@ -115,11 +116,23 @@ class Binding:
                   @rtype: L{Document}
                   """
          
          +        if attributes:
          +            pass
          +            # moved to suds/bindings/document.py
          +
          +            #print method
          +            #for name, val in attributes.items():
          +            #    method.attributes.append(Attribute(name, val))
          +
          +
                   content = self.headercontent(method)
                   header = self.header(content)
          -        content = self.bodycontent(method, args, kwargs)
          +        content = self.bodycontent(method, args, kwargs, attributes=attributes)
                   body = self.body(content)
                   env = self.envelope(header, body)
          +        #if attributes:
          +        #    print content
          +        #    1/0
                   if self.options().prefixes:
                       body.normalizePrefixes()
                       env.promotePrefixes()
          @@ -535,4 +548,4 @@ class PartElement(SchemaElement):
                       return self
                   else:
                       return self.__resolved
          -    
          \ No newline at end of file
          +    
          diff --git a/website/suds/bindings/document.py b/website/suds/bindings/document.py
          index edd9422..0c84753 100644
          --- a/website/suds/bindings/document.py
          +++ b/website/suds/bindings/document.py
          @@ -38,7 +38,7 @@ class Document(Binding):
               (multiple message parts), must present a I{document} view for that method.
               """
          
          -    def bodycontent(self, method, args, kwargs):
          +    def bodycontent(self, method, args, kwargs, attributes=None):
                   #
                   # The I{wrapped} vs I{bare} style is detected in 2 ways.
                   # If there is 2+ parts in the message then it is I{bare}.
          @@ -54,6 +54,12 @@ class Document(Binding):
                   else:
                       root = []
                   n = 0
          +
          +        if attributes:
          +            #print root.__class__
          +            for name, val in attributes.items():
          +                root.set(name, val)
          +
                   for pd in self.param_defs(method):
                       if n < len(args):
                           value = args[n]
          diff --git a/website/suds/client.py b/website/suds/client.py
          index 8b4f258..f80e36a 100644
          --- a/website/suds/client.py
          +++ b/website/suds/client.py
          @@ -592,7 +592,10 @@ class SoapClient:
                   timer.start()
                   result = None
                   binding = self.method.binding.input
          -        soapenv = binding.get_message(self.method, args, kwargs)
          +        attributes = kwargs.get('attributes', None)
          +        if attributes:
          +            del kwargs['attributes']
          +        soapenv = binding.get_message(self.method, args, kwargs, attributes)
                   timer.stop()
                   metrics.log.debug(
                           "message for '%s' created: %s",
          @@ -841,4 +844,4 @@ class RequestContext:
                   @type error: A suds I{TransportError}.
                   """
                   return self.client.failed(self.binding, error)
          -        
          \ No newline at end of file
          +        
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2012-06-09
            • 1970-01-01
            • 1970-01-01
            • 2020-11-28
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多