我在Python SUDS中遇到了另一个可怕的TypeNotFound错误(Python 2.7,suds-jurko == 0.6)
这些是XSD的相关部分:
<xs:complexType final="extension restriction" name="requestHeader">
<xs:sequence>
<xs:element minOccurs="0" name="type" type="tns:requestType"/>
<xs:element minOccurs="0" name="userID" type="xs:string"/>
<xs:element minOccurs="0" name="sessionID" type="xs:string"/>
</xs:sequence>
</xs:complexType>
<xs:complexType final="extension restriction" name="requestType">
<xs:sequence>
<xs:element name="__value" type="xs:int"/>
</xs:sequence>
</xs:complexType>
WSDL正确导入XSD,因此我不相信Doctor会提供帮助:
<wsdl:definitions
name="FooBarService"
targetNamespace="foo.bar.ns"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:tns="foo.bar.ns"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">
<schema xmlns="http://www.w3.org/2001/XMLSchema">
<import namespace="foo.bar.ns" schemaLocation="someschemafile.xsd"/>
<import namespace="http://jaxb.dev.java.net/array" schemaLocation="someschemafile2.xsd"/>
someschemafile.xsd
:
<xs:schema
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:ns1="http://jaxb.dev.java.net/array"
xmlns:tns="foo.bar.ns"
attributeFormDefault="unqualified"
elementFormDefault="unqualified"
targetNamespace="foo.bar.ns">
然后我创建requestHeader
和requestType
:
q = soap_client.factory.create('requestHeader')
print q
(requestHeader){
type =
(requestType){
__value = None
}
userID = None
sessionID = None
}
然后:
q.type = soap_client.factory.create('requestType')
q.type.__value = 42
q.userID = "foo"
q.sessionID = "bar"
print q
(requestHeader){
type =
(requestType){
__value = 42
}
userID = "foo"
sessionID = "bar"
}
然后我尝试调用使用requestHeader
的方法,之后我得到:
TypeNotFound(u"Type not found: '__value'",)
我也试过这个:
q = {
'type': 42,
'userID': "foo",
'sessionID': "bar"
}
但这会导致错误的SOAP消息:
<header>
<type>42</type>
<userID>foo</userID>
<sessionID>bar</sessionID>
</header>
而不是
<header>
<type>
<__value>42</__value>
</type>
<userID>foo</userID>
<sessionID>bar</sessionID>
</header>
最终被服务拒绝了。
对不起,我无法提供完整的WSDL和XSD,它们受到限制。
如何使suds使用__value
元素创建正确的SOAP XML?
我使用WSDL的本地副本,因此我可以更改它,只要它能够生成正确的SOAP XML。不过,我不知道该改变什么。
编辑:添加了一些清理后的回溯(在调用SUDS方法之前删除了东西)request
是SUDS对象,其中一个属性属于requestHeader
---------------------------------------------------------------------------
FooClientClass Traceback (most recent call last)
<ipython-input-4-8ccf453fe073> in <module>()
----> 1 soap_client.service.someServiceMethod(request)
/home/user/.virtualenvs/foo_project/local/lib/python2.7/site-packages/suds/client.pyc in __call__(self, *args, **kwargs)
519 client = clientclass(self.client, self.method)
520 try:
--> 521 return client.invoke(args, kwargs)
522 except WebFault, e:
523 if self.faults():
/home/user/.virtualenvs/foo_project/local/lib/python2.7/site-packages/suds/client.pyc in invoke(self, args, kwargs)
574 timer.start()
575 binding = self.method.binding.input
--> 576 soapenv = binding.get_message(self.method, args, kwargs)
577 timer.stop()
578 metrics.log.debug("message for '%s' created: %s", self.method.name,
/home/user/.virtualenvs/foo_project/local/lib/python2.7/site-packages/suds/bindings/binding.pyc in get_message(self, method, args, kwargs)
107 content = self.headercontent(method)
108 header = self.header(content)
--> 109 content = self.bodycontent(method, args, kwargs)
110 body = self.body(content)
111 env = self.envelope(header, body)
/home/user/.virtualenvs/foo_project/local/lib/python2.7/site-packages/suds/bindings/document.pyc in bodycontent(self, method, args, kwargs)
93
94 parse_args(method.name, self.param_defs(method), args, kwargs,
---> 95 add_param, self.options().extraArgumentErrors)
96
97 return root
/home/user/.virtualenvs/foo_project/local/lib/python2.7/site-packages/suds/argparser.pyc in parse_args(method_name, param_defs, args, kwargs, external_param_processor, extra_parameter_errors)
81 """
82 arg_parser = _ArgParser(method_name, param_defs, external_param_processor)
---> 83 return arg_parser(args, kwargs, extra_parameter_errors)
84
85
/home/user/.virtualenvs/foo_project/local/lib/python2.7/site-packages/suds/argparser.pyc in __call__(self, args, kwargs, extra_parameter_errors)
106 self.__init_run(args, kwargs, extra_parameter_errors)
107 try:
--> 108 self.__process_parameters()
109 return self.__all_parameters_processed()
110 finally:
/home/user/.virtualenvs/foo_project/local/lib/python2.7/site-packages/suds/argparser.pyc in __process_parameters(self)
297 """Collect values for given web service operation input parameters."""
298 for pdef in self.__param_defs:
--> 299 self.__process_parameter(*pdef)
300
301 def __push_frame(self, ancestry_item):
/home/user/.virtualenvs/foo_project/local/lib/python2.7/site-packages/suds/argparser.pyc in __process_parameter(self, param_name, param_type, ancestry)
292 self.__stack[-1].process_parameter(param_optional, value is not None)
293 self.__external_param_processor(param_name, param_type,
--> 294 self.__in_choice_context(), value)
295
296 def __process_parameters(self):
/home/user/.virtualenvs/foo_project/local/lib/python2.7/site-packages/suds/bindings/document.pyc in add_param(param_name, param_type, in_choice_context, value)
84 # Construct request data for the current input parameter.
85 pdef = (param_name, param_type)
---> 86 p = self.mkparam(method, pdef, value)
87 if p is None:
88 return
/home/user/.virtualenvs/foo_project/local/lib/python2.7/site-packages/suds/bindings/document.pyc in mkparam(self, method, pdef, object)
128 tags.append(self.mkparam(method, pdef, item))
129 return tags
--> 130 return Binding.mkparam(self, method, pdef, object)
131
132 def param_defs(self, method):
/home/user/.virtualenvs/foo_project/local/lib/python2.7/site-packages/suds/bindings/binding.pyc in mkparam(self, method, pdef, object)
223 content = Content(tag=pdef[0], value=object, type=pdef[1],
224 real=pdef[1].resolve())
--> 225 return marshaller.process(content)
226
227 def mkheader(self, method, hdef, object):
/home/user/.virtualenvs/foo_project/local/lib/python2.7/site-packages/suds/mx/core.pyc in process(self, content)
57 if isinstance(content.value, Property):
58 root = self.node(content)
---> 59 self.append(document, content)
60 return document.root()
61
/home/user/.virtualenvs/foo_project/local/lib/python2.7/site-packages/suds/mx/core.pyc in append(self, parent, content)
70 log.debug('appending parent:\n%s\ncontent:\n%s', parent, content)
71 if self.start(content):
---> 72 self.appender.append(parent, content)
73 self.end(parent, content)
74
/home/user/.virtualenvs/foo_project/local/lib/python2.7/site-packages/suds/mx/appender.pyc in append(self, parent, content)
86 appender = candidate_appender
87 break
---> 88 appender.append(parent, content)
89
90
/home/user/.virtualenvs/foo_project/local/lib/python2.7/site-packages/suds/mx/appender.pyc in append(self, parent, content)
227 for item in object:
228 cont = Content(tag=item[0], value=item[1])
--> 229 Appender.append(self, child, cont)
230
231
/home/user/.virtualenvs/foo_project/local/lib/python2.7/site-packages/suds/mx/appender.pyc in append(self, parent, content)
166 @type content: L{Object}
167 """
--> 168 self.marshaller.append(parent, content)
169
170
/home/user/.virtualenvs/foo_project/local/lib/python2.7/site-packages/suds/mx/core.pyc in append(self, parent, content)
70 log.debug('appending parent:\n%s\ncontent:\n%s', parent, content)
71 if self.start(content):
---> 72 self.appender.append(parent, content)
73 self.end(parent, content)
74
/home/user/.virtualenvs/foo_project/local/lib/python2.7/site-packages/suds/mx/appender.pyc in append(self, parent, content)
86 appender = candidate_appender
87 break
---> 88 appender.append(parent, content)
89
90
/home/user/.virtualenvs/foo_project/local/lib/python2.7/site-packages/suds/mx/appender.pyc in append(self, parent, content)
227 for item in object:
228 cont = Content(tag=item[0], value=item[1])
--> 229 Appender.append(self, child, cont)
230
231
/home/user/.virtualenvs/foo_project/local/lib/python2.7/site-packages/suds/mx/appender.pyc in append(self, parent, content)
166 @type content: L{Object}
167 """
--> 168 self.marshaller.append(parent, content)
169
170
/home/user/.virtualenvs/foo_project/local/lib/python2.7/site-packages/suds/mx/core.pyc in append(self, parent, content)
70 log.debug('appending parent:\n%s\ncontent:\n%s', parent, content)
71 if self.start(content):
---> 72 self.appender.append(parent, content)
73 self.end(parent, content)
74
/home/user/.virtualenvs/foo_project/local/lib/python2.7/site-packages/suds/mx/appender.pyc in append(self, parent, content)
86 appender = candidate_appender
87 break
---> 88 appender.append(parent, content)
89
90
/home/user/.virtualenvs/foo_project/local/lib/python2.7/site-packages/suds/mx/appender.pyc in append(self, parent, content)
227 for item in object:
228 cont = Content(tag=item[0], value=item[1])
--> 229 Appender.append(self, child, cont)
230
231
/home/user/.virtualenvs/foo_project/local/lib/python2.7/site-packages/suds/mx/appender.pyc in append(self, parent, content)
166 @type content: L{Object}
167 """
--> 168 self.marshaller.append(parent, content)
169
170
/home/user/.virtualenvs/foo_project/local/lib/python2.7/site-packages/suds/mx/core.pyc in append(self, parent, content)
69 """
70 log.debug('appending parent:\n%s\ncontent:\n%s', parent, content)
---> 71 if self.start(content):
72 self.appender.append(parent, content)
73 self.end(parent, content)
/home/user/.virtualenvs/foo_project/local/lib/python2.7/site-packages/suds/mx/literal.pyc in start(self, content)
84 content.type = self.resolver.find(name, content.value)
85 if content.type is None:
---> 86 raise TypeNotFound(content.tag)
87 else:
88 known = None
TypeNotFound(u"Type not found: '__value'",)
答案 0 :(得分:0)
根据@dopstar评论,这是因为SUDS中的错误。由于我没有时间尝试在源代码上修复它,我设计了一些丑陋的解决方法
from lxml import etree
etree_object = build_XML_using_etree()
soap_client.service.someServiceMethod(
__inject={'msg': etree.tostring(etree_object)}
)
丑陋的部分实际上在这里看不到它是编织隐藏在build_XML_using_etree
方法后面的XML的逻辑,因为我们不能在这里依赖SUDS。
另一方面,一旦将原始XML注入SUDS堆栈,其他一切工作都很顺利,所以也许这不是那么糟糕......