使用Suds时“Missing”方法属性

时间:2012-02-20 17:16:03

标签: python soap suds

我正在使用Suds开发Soap客户端,我遇到了问题。我创建客户端并打印它以了解可用的方法:

    wsdl_url='http://ws04.iula.upf.edu/soaplab2-axis/typed/services/tokenization.freeling_tokenizer?wsdl'
    FL_ws=Client(wsdl_url)
    print FL_ws

我的输出是(我删除了一些部分以方便阅读):

   Ports (1):
  (freeling_tokenizerPort)
     Methods (11):
        clear(ns2:jobId jobId, )
        describe()
        getLastEvent(ns2:jobId jobId, )
        getResults(ns2:jobId jobId, )
        run(ns1:language language, )
        runAndWaitFor(ns1:language language, )
     Types (22):
        ns1:RunAndWaitFor
        ns1:appInputs
        ns1:appResults
        ns2:describeRequest
        ns2:jobId

请注意,有许多方法在结束时都有缺少属性,例如:runAndWaitFor(ns1:language language,)。根据WISDL,这个缺失的属性是一个文本,可以作为直接数据或url给出:

<xs:complexType name="appInputs">
 <xs:sequence>
  <xs:choice id="input">
   <xs:element name="input_direct_data" type="xs:string"/>
   <xs:element name="input_url" type="xs:string"/>
  </xs:choice>
  <xs:element name="language">
   <xs:simpleType>
    <xs:restriction base="xs:string">
     <xs:enumeration value="en"/>
     <xs:enumeration value="es"/>
    </xs:restriction>
   </xs:simpleType>
  </xs:element>
 </xs:sequence>
</xs:complexType>

然后,我不知道如何调用此方法。在Perl中,它可以很好地定义和输入结构,如下所示:

# Inputs structure
my $inputs = {
    input_direct_data => "$input_direct_data",
    language => "$language"
};

所以我尝试了以下内容:

    input = FL_ws.factory.create('ns1:appInputs')
    input['input_direct_data']='The house is red.'
    input['language']='en'
    result=FL_ws.service.runAndWaitFor(input)
    print result

但是由Suds生成的xml不正确:

<ns1:Body>
  <ns0:runAndWaitFor>
     <language>
        <input_direct_data>The house is red.</input_direct_data>
        <language>en</language>
     </language>
  </ns0:runAndWaitFor>
</ns1:Body>

因为它将input_direct_data放在<language>下。我发现this帖子与XML有类似的问题,但他们的解决方案对我不起作用。在我看来,我的问题与Suds如何处理选择输入有关,因为它似乎不接受input_direct_data作为参数。

我得到的错误总是:

suds.WebFault: Server raised fault: 'Soaplab not able to process the input request: '

所以似乎输入没有正确到达服务......

关于如何解决这个问题的任何想法,或者我如何弄清楚Suds对此输入的期望,将会非常有帮助。

非常感谢你的帮助。

1 个答案:

答案 0 :(得分:1)

我找到了一个解决方案:

我使用"typed" wisdl来创建客户端,但由于某种原因,Suds无法从中正确获取参数。然后,我了解到有另一个"non-typed" wisdl可用于同一服务。使用它来创建Suds客户端,它能够正确获取方法的复杂参数,并成功构建了客户端。

我尝试访问的服务是使用SoapLab创建的。首先我认为不同WISDL的这个问题与SoapLab如何创建它们有关,但我不是SoapLab的专家,只是这些服务的用户,所以我真的不知道发生了什么......另一方面,我能够使用第一个wisdl创建一个perl客户端,所以也许这是Suds的一个问题。