Я рассмотрел примеры:
- http://pywebsvcs.svn.sourceforge.net/viewvc/pywebsvcs/trunk/wstools/
- http://pywebsvcs.sourceforge.net/cookbook.pdf
и googled, но не смог найти ни один полезный пример.
Я рассмотрел примеры:
и googled, но не смог найти ни один полезный пример.
ссылка: (Спасибо Дугу Хеллманну) здание мыла
Инфраструктура Zolera Soap (ZSI), является частью проекта pywebsvcs. Он предоставляет полные серверные и клиентские библиотеки для работы с SOAP. Чтобы использовать его, разработчик записывает файл WSDL (вручную или с помощью редактора WSDL), а затем генерирует источник Python для клиента и заглушки для сервера. Структуры данных, определенные в файле WSDL, преобразуются в классы Python, которые могут использоваться как в клиентском, так и в сервере.
мы внедрили простую службу эха, которая возвращает в качестве вывода все, что получает от клиента. Листинг 1 содержит входы WSDL, созданные вручную, для версии этой службы ZSI.
Листинг 1
<?xml version="1.0" encoding="UTF-8"?>
<definitions
xmlns="http://schemas.xmlsoap.org/wsdl/"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:http="http://schemas.xmlsoap.org/wsdl/http/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:tns="urn:ZSI"
targetNamespace="urn:ZSI" >
<types>
<xsd:schema elementFormDefault="qualified"
targetNamespace="urn:ZSI">
<xsd:element name="Echo">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:anyType"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>
</types>
<message name="EchoRequest">
<part name="parameters" element="tns:Echo" />
</message>
<message name="EchoResponse">
<part name="parameters" element="tns:Echo"/>
</message>
<portType name="EchoServer">
<operation name="Echo">
<input message="tns:EchoRequest"/>
<output message="tns:EchoResponse"/>
</operation>
</portType>
<binding name="EchoServer" type="tns:EchoServer">
<soap:binding style="document"
transport="http://schemas.xmlsoap.org/soap/http"/>
<operation name="Echo">
<soap:operation soapAction="Echo"/>
<input>
<soap:body use="literal"/>
</input>
<output>
<soap:body use="literal"/>
</output>
</operation>
</binding>
<service name="EchoServer">
<port name="EchoServer" binding="tns:EchoServer">
<soap:address location="http://localhost:7000"/>
</port>
</service>
</definitions>
Чтобы сгенерировать код клиента и сервера из WSDL, подайте его в программу wsdl2py (включенную в ZSI). Чтобы добавить поддержку сложных типов, добавьте параметр -b, но это не обязательно для этого простого примера. wsdl2py, в ответ, создаст три файла:
Листинг 2
EchoServer_client.py - это код, необходимый для создания клиента для веб-службы SimpleEcho.
##################################################
# file: EchoServer_client.py
#
# client stubs generated by
# "ZSI.generate.wsdl2python.WriteServiceModule"
#
##################################################
from EchoServer_types import *
import urlparse, types
from ZSI.TCcompound import ComplexType, Struct
from ZSI import client
from ZSI.schema import GED, GTD
import ZSI
from ZSI.generate.pyclass import pyclass_type
# Locator
class EchoServerLocator:
EchoServer_address = "http://localhost:7000"
def getEchoServerAddress(self):
return EchoServerLocator.EchoServer_address
def getEchoServer(self, url=None, **kw):
return EchoServerSOAP(
url or EchoServerLocator.EchoServer_address,
**kw)
# Methods
class EchoServerSOAP:
def __init__(self, url, **kw):
kw.setdefault("readerclass", None)
kw.setdefault("writerclass", None)
# no resource properties
self.binding = client.Binding(url=url, **kw)
# no ws-addressing
# op: Echo
def Echo(self, request, **kw):
if isinstance(request, EchoRequest) is False:
raise TypeError, "%s incorrect request type" % \
(request.__class__)
# no input wsaction
self.binding.Send(None, None, request, soapaction="Echo", **kw)
# no output wsaction
response = self.binding.Receive(EchoResponse.typecode)
return response
EchoRequest = GED("urn:ZSI", "Echo").pyclass
EchoResponse = GED("urn:ZSI", "Echo").pyclass
Листинг 3
EchoServer_server.py содержит код, необходимый для создания сервера веб-сервисов SimpleEcho.
##################################################
# file: EchoServer_server.py
#
# skeleton generated by
# "ZSI.generate.wsdl2dispatch.ServiceModuleWriter"
#
##################################################
from ZSI.schema import GED, GTD
from ZSI.TCcompound import ComplexType, Struct
from EchoServer_types import *
from ZSI.ServiceContainer import ServiceSOAPBinding
# Messages
EchoRequest = GED("urn:ZSI", "Echo").pyclass
EchoResponse = GED("urn:ZSI", "Echo").pyclass
# Service Skeletons
class EchoServer(ServiceSOAPBinding):
soapAction = {}
root = {}
def __init__(self, post='', **kw):
ServiceSOAPBinding.__init__(self, post)
def soap_Echo(self, ps, **kw):
request = ps.Parse(EchoRequest.typecode)
return request,EchoResponse()
soapAction['Echo'] = 'soap_Echo'
root[(EchoRequest.typecode.nspname,EchoRequest.typecode.pname)] = \
'soap_Echo'
Листинг 4
EchoServer_types.py имеет определения типов, используемые как кодом клиента, так и сервером.
##################################################
# file: EchoServer_types.py
#
# schema types generated by
# "ZSI.generate.wsdl2python.WriteServiceModule"
#
##################################################
import ZSI
import ZSI.TCcompound
from ZSI.schema import (LocalElementDeclaration, ElementDeclaration,
TypeDefinition, GTD, GED)
from ZSI.generate.pyclass import pyclass_type
##############################
# targetNamespace
# urn:ZSI
##############################
class ns0:
targetNamespace = "urn:ZSI"
class Echo_Dec(ZSI.TCcompound.ComplexType, ElementDeclaration):
literal = "Echo"
schema = "urn:ZSI"
def __init__(self, **kw):
ns = ns0.Echo_Dec.schema
TClist = [ZSI.TC.AnyType(pname=(ns,"value"),
aname="_value", minOccurs=1, maxOccurs=1,
nillable=False, typed=False,
encoded=kw.get("encoded"))]
kw["pname"] = ("urn:ZSI","Echo")
kw["aname"] = "_Echo"
self.attribute_typecode_dict = {}
ZSI.TCcompound.ComplexType.__init__(self,None,TClist,
inorder=0,**kw)
class Holder:
__metaclass__ = pyclass_type
typecode = self
def __init__(self):
# pyclass
self._value = None
return
Holder.__name__ = "Echo_Holder"
self.pyclass = Holder
# end class ns0 (tns: urn:ZSI)
После создания эти файлы не предназначены для редактирования, потому что они будут восстановлены как часть процесса сборки всякий раз, когда изменяется вход WSDL. Код в файлах растет, так как к определению службы добавляются все больше типов и вызовов.
Реализация сервера идет в отдельный файл, который импортирует сгенерированный код. В примере фактический сервис находится в строках 18-25 листинга 5. Декодер @soapmethod определяет вход (EchoRequest) и вывод (EchoResponse) для вызова. В примере реализация soap_Echo() просто заполняет значение ответа значением запроса и возвращает как запрос, так и ответ. Оттуда ZSI заботится о создании ответа SOAP и отправке его клиенту.
Листинг 5
import os
import sys
from EchoServer_client import *
from ZSI.twisted.wsgi import (SOAPApplication,
soapmethod,
SOAPHandlerChainFactory)
class EchoService(SOAPApplication):
factory = SOAPHandlerChainFactory
wsdl_content = dict(name='Echo',
targetNamespace='urn:echo',
imports=(),
portType='',
)
def __call__(self, env, start_response):
self.env = env
return SOAPApplication.__call__(self, env, start_response)
@soapmethod(EchoRequest.typecode,
EchoResponse.typecode,
operation='Echo',
soapaction='Echo')
def soap_Echo(self, request, response, **kw):
# Just return what was sent
response.Value = request.Value
return request, response
def main():
from wsgiref.simple_server import make_server
from ZSI.twisted.wsgi import WSGIApplication
application = WSGIApplication()
httpd = make_server('', 7000, application)
application['echo'] = EchoService()
print "listening..."
httpd.serve_forever()
if __name__ == '__main__':
main()
В листинге 6 приведен пример использования клиентских библиотек ZSI для доступа к серверам с конца клиента. Все, что нужно сделать, это создать дескриптор веб-службы EchoServer, создать EchoRequest, отправить его в веб-службу и прочитать ответ.
from EchoServer_client import *
import sys, time
loc = EchoServerLocator()
port = loc.getEchoServer(url='http://localhost:7000/echo')
print "Echo: ",
msg = EchoRequest()
msg.Value = "Is there an echo in here?"
rsp = port.Echo(msg)
print rsp.Value