在this tutorial之后,我将Unicode
转换为String
,在遵循wsgi
教程时效果很好。
在某些背景下,我将其托管在docker容器中,并将该容器的端口暴露给主机。这就是为什么我将0.0.0.0
用作HOST
变量。
python版本:3.8.0
spyne版本2.13.11a0
压缩版本3.4.0
import logging
from twisted.internet import reactor
from twisted.web.server import Site
from spyne import Application, rpc, Service, Iterable, String, UnsignedInteger
from spyne.protocol.soap import Soap11
from spyne.server.twisted import TwistedWebResource
HOST = '0.0.0.0'
PORT = 5050
class HelloWorldService(Service):
@rpc(String, UnsignedInteger, _returns=Iterable(String))
def say_hello(ctx, name, times):
for i in range(times):
yield f'Hello {name}'
application = Application(
[HelloWorldService], 'spyne.examples.twisted.resource_push',
in_protocol=Soap11(validator='lxml'), out_protocol=Soap11(),
)
def main():
resource = TwistedWebResource(application)
site = Site(resource)
logging.basicConfig(level=logging.DEBUG)
logging.getLogger('spyne.protocol.xml').setLevel(logging.DEBUG)
logging.info(f'listening on {HOST}:{PORT}')
logging.info(f'wsdl is at: http://{HOST}:{PORT}/?wsdl')
reactor.listenTCP(PORT, site, interface=HOST)
reactor.run()
if __name__ == '__main__':
main()
使用zeep
进行测试
import zeep
wsdl = 'http://localhost:5050/?wsdl'
client = zeep.Client(wsdl=wsdl)
client.service.say_hello('Daniel', 5)
这是错误
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "C:\...\lib\site-packages\zeep\proxy.py", line 45, in __call__
kwargs,
File "C:\...\lib\site-packages\zeep\wsdl\bindings\soap.py", line 122, in send
response = client.transport.post_xml(options["address"], envelope, http_headers)
File "C:\...\lib\site-packages\zeep\transports.py", line 95, in post_xml
return self.post(address, message, headers)
File "C:\...\lib\site-packages\zeep\transports.py", line 62, in post
address, data=message, headers=headers, timeout=self.operation_timeout
File "C:\...\lib\site-packages\requests\sessions.py", line 581, in post
return self.request('POST', url, data=data, json=json, **kwargs)
File "C:\...\lib\site-packages\requests\sessions.py", line 533, in request
resp = self.send(prep, **send_kwargs)
File "C:\...\lib\site-packages\requests\sessions.py", line 646, in send
r = adapter.send(request, **kwargs)
File "C:\...\lib\site-packages\requests\adapters.py", line 516, in send
raise ConnectionError(e, request=request)
requests.exceptions.ConnectionError: HTTPConnectionPool(host="b'localhost'", port=5050): Max retries exceeded with url: / (Caused by NewConnectionError('<urllib3.connection.HTTPConnection object at 0x04794F50>: Failed to establish a new connection: [Errno 11001] getaddrinfo failed'))
b'localhost'
似乎不正确。看看生成的wsdl肯定在那里
在http://localhost:5050/?wsdl
生成的WSDL
<wsdl:service name="HelloWorldService">
<wsdl:port name="Application" binding="tns:Application">
<wsdlsoap11:address location="http://b'localhost':5050/"/>
</wsdl:port>
</wsdl:service>
完整的WSDL
<wsdl:definitions xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:plink="http://schemas.xmlsoap.org/ws/2003/05/partner-link/" xmlns:wsdlsoap11="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:wsdlsoap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:soap11enc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:soap11env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:soap12env="http://www.w3.org/2003/05/soap-envelope" xmlns:soap12enc="http://www.w3.org/2003/05/soap-encoding" xmlns:wsa="http://schemas.xmlsoap.org/ws/2003/03/addressing" xmlns:xop="http://www.w3.org/2004/08/xop/include" xmlns:tns="spyne.examples.twisted.resource_push" targetNamespace="spyne.examples.twisted.resource_push" name="Application">
<wsdl:types>
<xs:schema targetNamespace="spyne.examples.twisted.resource_push" elementFormDefault="qualified">
<xs:complexType name="stringArray">
<xs:sequence>
<xs:element name="string" type="xs:string" minOccurs="0" maxOccurs="unbounded" nillable="true"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="say_hello">
<xs:sequence>
<xs:element name="name" type="xs:string" minOccurs="0" nillable="true"/>
<xs:element name="times" type="xs:nonNegativeInteger" minOccurs="0" nillable="true"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="say_helloResponse">
<xs:sequence>
<xs:element name="say_helloResult" type="tns:stringArray" minOccurs="0" nillable="true"/>
</xs:sequence>
</xs:complexType>
<xs:element name="stringArray" type="tns:stringArray"/>
<xs:element name="say_hello" type="tns:say_hello"/>
<xs:element name="say_helloResponse" type="tns:say_helloResponse"/>
</xs:schema>
</wsdl:types>
<wsdl:message name="say_hello">
<wsdl:part name="say_hello" element="tns:say_hello"/>
</wsdl:message>
<wsdl:message name="say_helloResponse">
<wsdl:part name="say_helloResponse" element="tns:say_helloResponse"/>
</wsdl:message>
<wsdl:service name="HelloWorldService">
<wsdl:port name="Application" binding="tns:Application">
<wsdlsoap11:address location="http://b'localhost':5050/"/>
</wsdl:port>
</wsdl:service>
<wsdl:portType name="Application">
<wsdl:operation name="say_hello" parameterOrder="say_hello">
<wsdl:input name="say_hello" message="tns:say_hello"/>
<wsdl:output name="say_helloResponse" message="tns:say_helloResponse"/>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="Application" type="tns:Application">
<wsdlsoap11:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="say_hello">
<wsdlsoap11:operation soapAction="say_hello" style="document"/>
<wsdl:input name="say_hello">
<wsdlsoap11:body use="literal"/>
</wsdl:input>
<wsdl:output name="say_helloResponse">
<wsdlsoap11:body use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
</wsdl:definitions>