【问题标题】:Not able to create a SOAP filter in suds无法在 suds 中创建 SOAP 过滤器
【发布时间】:2017-06-16 10:27:30
【问题描述】:

我有一个低于 XML 正文的 SOAP 请求

<x:Body>
    <ser:CreateExportJobRequest>
        <ser:ExportJobTypeName>Products</ser:ExportJobTypeName>
        <ser:ExportColumns>
            <ser:ExportColumn>Id</ser:ExportColumn>
            <ser:ExportColumn>itemName</ser:ExportColumn>
        </ser:ExportColumns>
        <ser:ExportFilters>
            <ser:ExportFilter id="updatedSince">
                <ser:Text>2.0</ser:Text>
            </ser:ExportFilter>
        </ser:ExportFilters>
        <ser:Frequency>ONETIME</ser:Frequency>
    </ser:CreateExportJobRequest>
</x:Body>

我可以使用Boomerang 发出成功的请求。

现在我真的想在我的 python 代码中使用它。所以我尝试了,

inputElement = client.factory.create('CreateExportJobRequest')

inputElement.ExportJobTypeName = "Products"
inputElement.ExportColumns.ExportColumn = ["Id", "itemName"]

inputElement.Frequency = 'ONETIME'

if updatedSince:
    inputElement.ExportFilters.ExportFilter = ['updatedSince']

t = client.service.CreateExportJob(inputElement.ExportJobTypeName, inputElement.ExportColumns, inputElement.ExportFilters, None, None, inputElement.Frequency) 

我收到一个错误,

'list' object has no attribute 'id'

因为创建了一个有点错误的 XML 请求

<ns1:ExportFilters>
    <ns1:ExportFilter>updatedSince</ns1:ExportFilter>
</ns1:ExportFilters>

所以我为ExportFilter 尝试了一些其他的东西,比如

inputElement.ExportFilters.ExportFilter = [{'id': 'updatedSince', 'text': updatedSince}]

inputElement.ExportFilters.ExportFilter = [('updatedSince', updatedSince)]

inputElement.ExportFilters.ExportFilter = [{'updatedSince': updatedSince}]
# says, Type not found: 'updatedSince'

inputElement.ExportFilters.ExportFilter = [
    {'key': 'updatedSince', 'value': {'key': 'eq', 'value': updatedSince}}
]
# says, Type not found: 'value'

但没有任何效果。

设置ExportFilter前,其值的形式为

ExportFilters: (ExportFilters){
  ExportFilter[] = <empty>
}

请帮忙。

【问题讨论】:

    标签: python soap suds


    【解决方案1】:

    在调试并检查了一些 suds 代码后,我找到了解决方法。

    修复的完整代码sn-p:

    inputElement = client.factory.create('CreateExportJobRequest')
    
    inputElement.ExportJobTypeName = "Products"
    inputElement.ExportColumns.ExportColumn = ["Id", "itemName"]
    
    inputElement.Frequency = 'ONETIME'
    
    if updatedSince:
        efilter = client.factory.create("ExportFilter")
        efilter._id = 'updatedSince'
        efilter.Text = updatedSince
        inputElement.ExportFilters.ExportFilter.append(efilter)
    
    t = client.service.CreateExportJob(inputElement.ExportJobTypeName, inputElement.ExportColumns, inputElement.ExportFilters, None, None, inputElement.Frequency)
    

    调试: 因为 suds 引发了 TypeNotFound 异常,所以我查找了所有 raise TypeNotFound 在 suds 中的地方。我将调试点放在我的 PyCharm 中。

    我发现suds/mx/literal.py 内的Typed 类中的start 方法引发了我遇到的错误。

    def start(self, content):
        #
        # Start marshalling the 'content' by ensuring that both the
        # 'content' _and_ the resolver are primed with the XSD type
        # information.  The 'content' value is both translated and
        # sorted based on the XSD type.  Only values that are objects
        # have their attributes sorted.
        #
        log.debug('starting content:\n%s', content)
        if content.type is None:
            name = content.tag
            if name.startswith('_'):
                name = '@'+name[1:]
            content.type = self.resolver.find(name, content.value)
            if content.type is None:
                raise TypeNotFound(content.tag)
        else:
            known = None
            if isinstance(content.value, Object):
                known = self.resolver.known(content.value)
                if known is None:
                    log.debug('object has no type information', content.value)
                    known = content.type
            frame = Frame(content.type, resolved=known)
            self.resolver.push(frame)
        frame = self.resolver.top()
        content.real = frame.resolved
        content.ancestry = frame.ancestry
        self.translate(content)
        self.sort(content)
        if self.skip(content):
            log.debug('skipping (optional) content:\n%s', content)
            self.resolver.pop()
            return False
        else:
            return True
    

    所以根据这个逻辑,我找到了解决办法。

    但是,如果有人为此建议一个标准程序,那就太好了。

    【讨论】:

      猜你喜欢
      • 2012-08-30
      • 2021-02-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-12-27
      相关资源
      最近更新 更多