You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何移除Spyne库生成的SOAP请求中的e:前缀?

问题描述

我使用Spyne库构建了如下SOAP服务代码:

from spyne.application import Application
from spyne.decorator import rpc
from spyne.model.complex import ComplexModel
from spyne.model.primitive import String, Integer
from spyne.service import ServiceBase
from spyne.protocol.soap import Soap11
from spyne.server.django import DjangoApplication
from spyne import Unicode
from django.views.decorators.csrf import csrf_exempt
from lxml import etree

class StatusData(ComplexModel):
    date = String

class AppealsExternalStatusRequest(ComplexModel):
    messageId = String

class DataWrapper(ComplexModel):
    AppealsExternalStatusRequest = AppealsExternalStatusRequest


class AppealsService(ServiceBase):
    @rpc(DataWrapper, _returns=String, _body_style='bare', _operation_name='data')
    def receive_status(ctx, data_wrapper):
        print(data_wrapper)
        return "Received"


soap_app = Application([AppealsService],
                        tns='certain_path',
                        in_protocol=Soap11(validator='lxml'),
                        out_protocol=Soap11())

django_soap_app = DjangoApplication(soap_app)
django_soap_app = csrf_exempt(django_soap_app)

访问http://localhost/soap_api?wsdl得到的请求格式如下:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:v1="path" xmlns:e="app.soap_service">
   <soapenv:Header/>
   <soapenv:Body>
      <v1:data>
         <e:AppealsExternalStatusRequest>
            <!--Optional:-->
            <e:messageId>?</e:messageId>
            <e:statusData>
               <!--Optional:-->
               <e:date>?</e:date>
               <!--Optional:-->
            </e:statusData>
         </e:AppealsExternalStatusRequest>
      </v1:data>
   </soapenv:Body>
</soapenv:Envelope>

我希望移除其中的e:前缀,但尝试添加命名空间会生成其他前缀,移除命名空间则会自动出现e:前缀。Spyne会自动生成xmlns:e="app.soap_service"(对应app_name.file_name),导致所有namespace=None的字段都带有e:前缀,请问该如何解决这个问题?

解决方案

Spyne自动生成额外命名空间前缀的核心原因是:自定义的ComplexModel类默认使用了所在模块的命名空间(即app.soap_service),没有和Application的目标命名空间(tns)保持一致。只需给所有自定义复杂类型指定__namespace__属性,值与Application的tns相同即可解决。

修改后的代码示例

from spyne.application import Application
from spyne.decorator import rpc
from spyne.model.complex import ComplexModel
from spyne.model.primitive import String, Integer
from spyne.service import ServiceBase
from spyne.protocol.soap import Soap11
from spyne.server.django import DjangoApplication
from spyne import Unicode
from django.views.decorators.csrf import csrf_exempt
from lxml import etree

# 统一定义目标命名空间常量,避免重复书写
TARGET_NAMESPACE = 'certain_path'

class StatusData(ComplexModel):
    __namespace__ = TARGET_NAMESPACE
    date = String

class AppealsExternalStatusRequest(ComplexModel):
    __namespace__ = TARGET_NAMESPACE
    messageId = String

class DataWrapper(ComplexModel):
    __namespace__ = TARGET_NAMESPACE
    AppealsExternalStatusRequest = AppealsExternalStatusRequest


class AppealsService(ServiceBase):
    @rpc(DataWrapper, _returns=String, _body_style='bare', _operation_name='data')
    def receive_status(ctx, data_wrapper):
        print(data_wrapper)
        return "Received"


soap_app = Application([AppealsService],
                        tns=TARGET_NAMESPACE,
                        in_protocol=Soap11(validator='lxml'),
                        out_protocol=Soap11())

django_soap_app = DjangoApplication(soap_app)
django_soap_app = csrf_exempt(django_soap_app)

简化写法(可选)

如果自定义复杂类型较多,可以创建一个基类统一设置命名空间,其他类继承该基类即可:

class BaseComplexModel(ComplexModel):
    __namespace__ = TARGET_NAMESPACE

class StatusData(BaseComplexModel):
    date = String

class AppealsExternalStatusRequest(BaseComplexModel):
    messageId = String

class DataWrapper(BaseComplexModel):
    AppealsExternalStatusRequest = AppealsExternalStatusRequest

修改后,所有自定义复杂类型会和服务使用同一命名空间,WSDL生成的请求中将不再出现e:前缀,统一使用服务的命名空间前缀(如示例中的v1:,也可通过Soap11(prefix='自定义前缀')指定自定义前缀)。

内容的提问来源于stack exchange,提问作者nope_that_does_not_work

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 22:07:33