2011-04-07 128 views
6

我必須做的SOAP請求用肥皂水和Python將在肥皂水

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

屬性如何registerOrder添加屬性?

回答

5

suds documentation搜索MessagePlugin。編組選項是您正在搜索的內容。您需要將其作爲插件添加到您的客戶端中:

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

在編組方法中搜索context.envelope childs。 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")) 

我坐在這個上週,所以可能它會節省一些時間讓你:)

8

的更動態版本在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() 
1

可以使用__inject客戶端選項注入特定的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}) 

此外,我更喜歡使用泡沫-jurko https://pypi.python.org/pypi/suds-jurko/0.6其爲泡沫的叉被積極地維護。

1

我已經重複使用https://fedorahosted.org/suds/ticket/21,並調整了代碼來使用這個想法。如下更改SUDS並使用

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

按照想要的'attrName1'屬性調用'method'。

--- 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 
+