2011-04-07 20 views
6

muszę zrobić żądanie mydło z mydlin i Pythondodając atrybut w mydlin

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

Jak dodać atrybut w registerOrder?

Odpowiedz

5

Wyszukiwanie w suds documentation funkcji MessagePlugin. Opcja "Marshalled" jest tym, czego szukasz. Dodaj go do swojego klienta jako wtyczkę:

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

W metodzie marshalled wyszukaj childs context.envelope. Funkcja vars() Pythona jest bardzo przydatna w tym miejscu. Jak sądzę, należy go jak coś takiego dla Ciebie:

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")) 

ja siedziałem w tym przez ostatni tydzień, więc może będzie to zaoszczędzić trochę czasu dla ciebie :)

8

Bardziej dynamiczna wersja MessagePlugin byłoby:

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

Zastosowanie:

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

można użyć opcji __inject do klienta wstrzykiwać konkretny 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}) 

Również wolę za pomocą mydlin-Jurko https://pypi.python.org/pypi/suds-jurko/0.6 który jest rozwidlenie mydliny, który aktywnie utrzymane.

1

Ponownie użyłem https://fedorahosted.org/suds/ticket/21 i dostosowałem kod, aby użyć tego pomysłu. Zmień SUDS jak poniżej i użyj

, aby wywołać "method" z atrybutem "attrName1" zgodnie z oczekiwaniami.

--- 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 
+   
Powiązane problemy